Как выставить объекты из пакета Webpack и добавить внешние библиотеки в скомпилированный пакет?
Укороченная версия
TL;DR Я хочу иметь возможность выставлять произвольные объекты и функции из пакета Webpack (назовем его Bundle2), который я могу использовать в другом (независимом и не связанном) пакете (Bundle1).
Например, Bundle2 может быть приложением React, которое действует как виджет в Bundle1. Затем Bundle2 каким-то образом предоставит компонент React, действия и редукторы, чтобы Bundle1 мог его использовать (например, для объединения редукторов, рендеринга компонента Bundle2 и т. Д.).
Но я также хочу, чтобы Bundle2 использовал некоторые библиотеки, которые уже включены в Bundle1, для экономии места.
Я знаю, что могу использовать Webpack options.externals
чтобы исключить libs из пакета, и я получил это на работу. Но он ожидает, что внешние объекты будут на глобальном объекте. Я хочу иметь возможность вводить зависимости от Bundle1 в Bundle2 как-то, например, проходя через реквизит. Я не хочу устанавливать window.React = require('react')
в Bundle1, чтобы Bundle2 мог использовать React.
РЕДАКТИРОВАТЬ: разъяснение... Мой вариант использования я хочу, чтобы пользователи могли добавлять виджеты из магазина или что-то в этом роде. Поскольку потенциально могут быть тысячи виджетов, я не думаю, что все эти виджеты (которые могут быть сгенерированы пользователем) могут быть масштабируемыми или выполнимыми для включения в основной комплект во время компиляции (даже при использовании блоков Webpack или функций разделения кода), Кроме того, я думаю, что запускать чужой код через мой веб-пакет опасно, так как они могут таким образом выполнять произвольный нативный код. Вместо этого я хочу, чтобы виджеты других людей находились где-то на моем сервере, и когда они "устанавливают их", я в основном асинхронно загружаю код виджета в их панель управления.
Длинная версия
Допустим, у меня есть следующие пакеты Webpack:
dashboard.bundle.js
, основной комплект приложений. Это приложение React с Redux.clockWidget.bundle.js
, который определяет компонент React часов и использует Redux для обновления самого себя в зависимости от его состояния. Таким образом, он имеет корневой компонент, редуктор и некоторые действия.
Во время выполнения, clockWidget.bundle.js
загружается асинхронно в dashboard.bundle.js
с помощью require.js
вроде как это:
// Inside dashboard.bundle.js
requirejs(['clockWidget.bundle.js'], (widgetFunc) => {
// I want to be able to do this:
const widget = widgetFunc();
const { actions, reducer, Component } = widget;
// Where:
// Component - is a React component I can render either server-side or client-side inside the dashboard bundle.
// actions & reducer - are Redux actions and reducers
});
В принципе, clockWidget
будет втянут в асинхронно и оказано где-то внутри dashboard
с использованием Component
дано clockWidget
расслоение.
Чтобы уменьшить размер clockWidget
Я использую Webpack's options.externals
особенность, чтобы исключить React
из пачки, так как dashboard.bundle.js
уже есть.
Я хочу быть в состоянии сделать что-то вроде этого:
// inside dashboard.bundle.js:
import React from 'react';
//...
requirejs(['clockWidget.bundle.js'], (widgetFunc) => {
// Give the clockWidget bundle access to React:
const widget = widgetFunc({ React })();
// Then calling that gives me all the stuff I need, like before:
const { actions, reducer, Component } = widget;
// ...rendering the component, etc...
});
Но я не могу понять, как это сделать. Я пробовал что-то вроде этого:
// Inside the compiled clockWidget.bundle.js:
// Wrap the Webpack output with a RequireJS define,
// and return an object with the actions, reducer, and component from inside the bundle.
define(() => {
// I can make Webpack generate this code using
// output: {
// libraryTarget: 'var'
// }
var bundle = function() {
// imagine minified webpack code in here...
};
// ^ I want to somehow pass down instances to React and other libs
// so this bundle can consume it. If I use webpack's options.externals,
// I can simply expose libs globally in dashboard.bundle.js to do the trick, but that smells bad to me.
// Expose these keys to RequireJS:
return {
Actions: {}, // somehow point Actions to the webpack compiled actions
Reducer: {}, // point Reducer to the webpack compiled reducer
Component: {}, // point Component to the webpack compiled component
};
});
Буду очень признателен за любой вклад или понимание того, как я могу приблизиться к этому миру. Спасибо:)