Библиотеки для разработки
Помимо приложений, webpack также может использоваться для объединения JavaScript-библиотек. Следующее руководство предназначено для авторов библиотек, стремящихся оптимизировать свою стратегию объединения.
Создание библиотеки
Предположим, что мы пишем небольшую библиотеку, webpack-numbers, которая позволяет пользователям преобразовывать числа от 1 до 5 из их числового представления в текстовое и наоборот, например, 2 в 'два'.
Структура проекта будет выглядеть так:
project
+ |- webpack.config.js + |- package.json + |- /src + |- index.js + |- ref.json
Инициализируйте проект с помощью npm, а затем установите webpack, webpack-cli и lodash:
npm init -y npm install --save-dev webpack webpack-cli lodash
Мы устанавливаем lodash в качестве devDependencies, а не dependencies, потому что не хотим включать его в нашу библиотеку, или это может легко привести к увеличению размера библиотеки.
src/ref.json
[
{
"num": 1,
"word": "One"
},
{
"num": 2,
"word": "Two"
},
{
"num": 3,
"word": "Three"
},
{
"num": 4,
"word": "Four"
},
{
"num": 5,
"word": "Five"
},
{
"num": 0,
"word": "Zero"
}
]
src/index.js
import _ from 'lodash';
import numRef from './ref.json';
export function numToWord(num) {
return _.reduce(
numRef,
(accum, ref) => {
return ref.num === num ? ref.word : accum;
},
''
);
}
export function wordToNum(word) {
return _.reduce(
numRef,
(accum, ref) => {
return ref.word === word && word.toLowerCase() ? ref.num : accum;
},
-1
);
}
Настройка webpack
Начнем с базовой настройки webpack:
webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'webpack-numbers.js',
},
};
В приведенном выше примере мы говорим webpack объединить src/index.js в dist/webpack-numbers.js.
Экспорт библиотеки
До сих пор всё должно быть так же, как при объединении приложения, и вот наступает момент отличия – нам нужно экспортировать данные из точки входа через опцию output.library.
webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'webpack-numbers.js',
+ library: "webpackNumbers",
},
};
Мы экспортировали точку входа как webpackNumbers, поэтому пользователи могут использовать её через тег script:
<script src="https://example.org/webpack-numbers.js"></script>
<script>
window.webpackNumbers.wordToNum('Five');
</script>
Однако это работает только при ссылке через тег script, её нельзя использовать в других средах, таких как CommonJS, AMD, Node.js и т.д.
Как авторы библиотеки, мы хотим, чтобы она была совместима в разных средах, то есть пользователи должны иметь возможность использовать объединённую библиотеку в нескольких способами, перечисленных ниже:
-
Модуль CommonJS require:
const webpackNumbers = require('webpack-numbers'); // ... webpackNumbers.wordToNum('Two'); -
Модуль AMD require:
require(['webpackNumbers'], function (webpackNumbers) { // ... webpackNumbers.wordToNum('Two'); }); -
Тег script:
<!DOCTYPE html> <html> ... <script src="https://example.org/webpack-numbers.js"></script> <script> // ... // Global variable webpackNumbers.wordToNum('Five'); // Property in the window object window.webpackNumbers.wordToNum('Five'); // ... </script> </html>
Давайте обновим опцию output.library с её значением type до 'umd':
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'webpack-numbers.js',
- library: 'webpackNumbers',
+ globalObject: 'this',
+ library: {
+ name: 'webpackNumbers',
+ type: 'umd',
+ },
},
};
Теперь webpack объединит библиотеку, которая будет работать с CommonJS, AMD и тегом script.
Внешняя зависимость Lodash
Теперь, если вы запустите npx webpack, вы увидите, что создаётся большой объединённый файл. Если вы его просмотрите, вы увидите, что lodash был объединён вместе с вашим кодом. В этом случае мы хотели бы рассматривать lodash как внешнюю зависимость. Это означает, что потребитель уже должен иметь lodash установленную.
Это можно сделать, используя конфигурацию externals:
webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'webpack-numbers.js',
library: {
name: "webpackNumbers",
type: "umd"
},
},
+ externals: {
+ lodash: {
+ commonjs: 'lodash',
+ commonjs2: 'lodash',
+ amd: 'lodash',
+ root: '_',
+ },
+ },
};
Это означает, что ваша библиотека ожидает зависимость под названием lodash в среде потребителя.
Ограничения внешних зависимостей
Для библиотек, использующих несколько файлов из зависимости:
import A from 'library/one'; import B from 'library/two'; // ...
Вы не сможете исключить их из сборки, указав library во внешних зависимостях. Вам либо придётся исключить их по одному, либо использовать регулярное выражение.
module.exports = {
//...
externals: [
'library/one',
'library/two',
// Everything that starts with "library/"
/^library\/.+$/,
],
};
Окончательные шаги
Оптимизируйте выходные данные для производства, следуя инструкциям в руководстве по производству. Добавим также путь к сгенерированному объединённому файлу в поле main пакета package.json.
package.json
{
...
"main": "dist/webpack-numbers.js",
...
}
Или, чтобы добавить его как стандартный модуль, как в этом руководстве:
{
...
"module": "src/index.js",
...
}
Ключ main относится к стандарту package.json, а module к предложению для улучшения экосистемы JavaScript до использования модулей ES2015 без нарушения обратной совместимости.
Теперь вы можете опубликовать его как пакет npm и найти его на unpkg.com, чтобы распространить его среди пользователей.
© JS Foundation and other contributors
Licensed under the Creative Commons Attribution License 4.0.
https://webpack.js.org/guides/author-libraries