Вывод модуля ES с помощью webpack
С помощью Rollup я могу вывести модуль ES, просто установив опцию format
в 'es'
. Как я могу сделать то же самое с webpack? Если это невозможно сейчас, есть ли у webpack какие-либо планы по его добавлению?
Единственное, что я нашел в документации для output.libraryTarget
, которая упоминает модули ES, такова:
libraryTarget: "commonjs-module"
- Экспортировать его с помощью объекта module.exports
(output.library
игнорируется), __esModule
определен (он пронумерован как модуль ES2015 в режиме взаимодействия)
Однако, это довольно неясно для меня. Это то же самое, что и libraryTarget: "commonjs2"
с той лишь разницей, что __esModule
определено? Что такое "режим взаимодействия"?
Ответы
Ответ 1
В Webpack2 пока нет соответствующей библиотеки, но она не выводит пакеты ES6. С другой стороны Если вы свяжете свою библиотеку с поставщиками CommonJS, вы не сможете запустить Tree Shaking, не имея возможности устранить неиспользуемые модули. Это из-за модулей ES все еще развивается, поэтому никто не отправляет пакеты ES в браузер, в то время как webpack используется в основном для создания пакетов с поддержкой браузера.
С другой стороны, если вы публикуете библиотеку, вы можете предоставить как цели CommonJS (umd), так и ES, благодаря "module" в пакете. JSON. На самом деле вам не нужно, чтобы webpack публиковал ES-цель, все, что вам нужно сделать, - запустить babel в каждом файле, чтобы получить его в стандарте es2015, например, если вы используете реакцию, вы можете запустить babel только с предустановленной "реакцией". Если ваш источник уже ES 2015 без дополнительных функций, вы можете указать модуль прямо на ваш src/index.js:
//package.json
...
"module": "src/index.js"
"main": "dist/your/library/bundle.js
...
Мне было удобно использовать babel для обработки инструкций export v from 'mod'
в моем основном index.js, поэтому у меня есть 1 файл модуля, экспортирующий все мои модули. Это достигается с помощью расширений babel-plugin-transform-export-extensions (также включенных в предустановку 1-го этапа).
Я рассматриваю этот подход из библиотеки action-bootstrap, вы можете видеть скрипты в своем github (они - webpack1). Я немного улучшил свои скрипты в своем реагировании-сигма-репо, не стесняйтесь копировать следующие файлы, которые будут делать то, что вам нужно:
config/babel.config.js
scripts/buildBabel.js
scripts/es/build.js
scripts/build.js // this is command line controller, if you need just ES you don't need it
Также посмотрите на lib target (scripts/lib/build.js и .babelrc), я предоставляю lib transpiled modules, поэтому пользователи библиотеки могут включать только те модули, в которых они нуждаются, даже без ES, явно указывающих require ( "response-sigma/lib/Sigma/" ), особенно полезно, если ваша библиотека тяжелая и модульная!
Ответ 2
Во-первых, я хотел бы указать разницу между commonJS
и commonJS2
commonJS
не поддерживает использование module.exports = function() {}
, которое используется node.js
и многими другими реализациями commonJS
.
Webpack2
использует концепцию связывания библиотечного кода и широкого использования его и чтобы он совместим с работой в разных средах, мы используем libraryTarget
Теперь часть здесь ответит на ваши вопросы
Возможные варианты библиотеки, поддерживаемые в Webpack2
,
-
libraryTarget: "umd", // enum
-
libraryTarget: "umd-module", // ES2015 module wrapped in UMD
-
libraryTarget: "commonjs-module", // ES2015 module wrapped in CommonJS
-
libraryTarget: "commonjs2", // exported with module.exports
-
libraryTarget: "commonjs", // exported as properties to exports
-
libraryTarget: "amd", // defined with AMD defined method
-
libraryTarget: "this", // property set on this
-
libraryTarget: "var", // variable defined in root scope
Интерлоп имеет следующее значение
Чтобы стимулировать использование CommonJS и модулей ES6, при экспорте default export
без другого exports
module.exports
будет установлено дополнительно exports["default"]
, как показано в следующем примере
export default test;
exports["default"] = test;
module.exports = exports["default"];
Таким образом, в основном это означает, что commonJS-module
можно использовать, выставив его как module.exports
с помощью interloping
с модулем ES2015, завернутым в commonJS
Более подробную информацию о interloping
можно найти в этом blogpost и ссылке stackoverflow к нему.
Основная идея заключается в ES6
свойствах экспорта и импорта среды выполнения не могут быть изменены, но в commonJS
это работает отлично, поскольку требуемые изменения происходят во время выполнения, поэтому он имеет ES2015 интерполировано с commonJS.
Обновление
Webpack 2 предоставляет возможность создания библиотеки, которая может быть в комплекте и включена.
Если вы хотите, чтобы ваш модуль использовался в разных средах, вы можете связать его как библиотеку, добавив параметры библиотеки и вывешивая ее в вашу конкретную среду. Процедура, упомянутая в docs.
Еще один простой пример того, как использовать commonjs-module
Важно отметить, что babel
добавляет exports.__esModule = true
к каждому es6 module
, и при импорте он вызывает _interopRequire
, чтобы проверить это свойство.
__esModule = true
необходимо установить только при экспорте библиотеки. Его необходимо установить на exports
модуля ввода. Внутренним модулям не требуется __esModule
, это просто хабельный хак.
Как упоминалось в документах
__esModule
определен (он продиктован как ES2015 в режиме в режиме взаимодействия)
Использование, как указано в тестовых примерах
export * from "./a";
export default "default-value";
export var b = "b";
import d from "library";
import { a, b } from "library";