Как с помощью WebPack создать готовые к использованию «разделенные» пакеты, в которых один зависит от другого?

Мой вопрос очень близок к другие, ответы на которые I полагать по-прежнему требуют еще одного шага WebPack, которого я хочу избежать. Но вот сначала история:

У меня есть модуль Node (назовем его libfoo), который предоставляет некоторые функции и требует некоторых сторонних модулей, и скрипт небольшойmain.js, который обеспечивает основную точку входа и требует libfoo:

основной.js:

const foo = require('foo');
function main() {
    foo.bar();
}
main();

Теперь я хочу превратить libfoo и main.js в результаты исполняемый файл браузера с помощью WebPack. И я хочу, чтобы libfoo (который довольно большой) статически находился в целевых системах, в то время как main.js был очень маленьким и быстро менялся (просто представьте тестовый сценарий, где libfoo — это модуль, который я хочу протестировать, а main.js содержит меняющиеся фрагменты кода)

Мне удалось создать два пакета — назовем их foo.browser.js и main.browser.js — в которых содержать весь необходимый функционал, но у меня не получается заставить main.browser.js корректно импортировать foo.browser.js.

Я еще не очень разбираюсь в WebPack - и до сих пор не мог понять, что происходит. Мой текущий подход выглядит так: я создаю foo.browser.js, выполнив следующую команду:

webpack --output-filename foo.browser.js foo.js

И у меня есть webpack.config.js вместо main.js, который выглядит так:

module.exports = {
  externals: {'foo': 'foo'},  // don't know what I'm doing here - added `commonjs` and `root` randomly
}

Я превращаю main.js в main.browser.js очень похожей командой: webpack --output-filename main.browser.js main.js

Теперь я пытаюсь использовать эти оба файла в файле с именем foo.html, содержащем эти строки:

<script src = "dist/foo.browser.js"></script>
<script src = "dist/main.browser.js"></script>

Но когда я теперь открываю foo.html в браузере, я получаю

external "foo":1 Uncaught ReferenceError: foo is not defined
    at Object.foo (external "foo":1)
    at __webpack_require__ (bootstrap:19)  
    at Object../main.js (main.js:3)  
    at __webpack_require__ (bootstrap:19)
    at bootstrap:83
    at bootstrap:83

Я немного повозился, но (боюсь, только случайно), но безуспешно.

В моем сценарии есть одно ограничение, которое может отличаться от других (рабочих) примеров, которые я нашел: мне нужно, чтобы foo.browser.js и main.browser.js были "окончательный", т.е. они должны работать в целевой системе без дополнительной постобработки (например, снова запустить WebPack, чтобы превратить их в единый пакет).

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
6
0
115
1

Ответы 1

Вы можете сделать это с помощью этого типа конфигурации:

module.exports = [{
  resolve: {
    modules: ["."],
  },
  entry: {
    "foo": "foo.js",
  },
  output: {
    path: `${__dirname}/build`,
    filename: "[name].js",
    sourceMapFilename: "[name].js.map",
    library: "foo",
    // libraryTarget: "umd",
  }
},{
  resolve: {
    modules: ["."],
  },
  entry: {
    "main": "main.js",
  },
  externals: {
    "foo": "foo",
  },
  output: {
    path: `${__dirname}/build`,
    filename: "[name].js",
    sourceMapFilename: "[name].js.map",
  }
}];

Это создаст два пакета в подкаталоге build/. Ключ к тому, чтобы заставить main использовать foo:

  1. Запись "foo": "foo" в externals для создания пакета main. Всякий раз, когда main запрашивает foo, он ищет его внешне в «модуле» с именем foo. Я взял «модуль» в кавычки, потому что когда у вас есть пакеты в формате UMD и вы загружаете их с помощью script, модульной системы нет. Вместо того, чтобы искать фактический модуль, код будет искать глобальную переменную с именем foo.

  2. Пакет foo экспортирует себя в глобальное пространство как переменную foo, что позволяет использовать его main.

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