Как выставить объекты из пакета 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
  };
});

Буду очень признателен за любой вклад или понимание того, как я могу приблизиться к этому миру. Спасибо:)

0 ответов

Другие вопросы по тегам