Библиотеки для авторизации
Помимо приложений, webpack также можно использовать для объединения JavaScript-библиотек. Следующее руководство предназначено для авторов библиотек, стремящихся оптимизировать свою стратегию объединения.
Создание библиотеки
Предположим, что вы пишете небольшую библиотеку ,webpack-numbers, которая позволяет пользователям преобразовывать числа от 1 до 5 из их числового представления в текстовое и наоборот, например, 2 в 'два'.
Базовая структура проекта может выглядеть так:
project
+ |- webpack.config.js + |- package.json + |- /src + |- index.js + |- ref.json
Инициализируйте npm, установите webpack и lodash:
npm init -y npm install --save-dev webpack lodash
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);
} Спецификация использования библиотеки будет следующей:
- Импорт модуля ES2015:
import * as webpackNumbers from 'webpack-numbers';
// ...
webpackNumbers.wordToNum('Two'); - Требование модуля CommonJS:
const webpackNumbers = require('webpack-numbers');
// ...
webpackNumbers.wordToNum('Two'); - Требование модуля AMD:
require(['webpackNumbers'], function (webpackNumbers) {
// ...
webpackNumbers.wordToNum('Two');
}); Потребитель также может использовать библиотеку, загрузив ее через тег script:
<!doctype html>
<html>
...
<script src="https://unpkg.com/webpack-numbers"></script>
<script>
// ...
// Global variable
webpackNumbers.wordToNum('Five')
// Property in the window object
window.webpackNumbers.wordToNum('Five')
// ...
</script>
</html> Обратите внимание, что мы также можем настроить его для экспорта библиотеки следующим образом:
- Свойство в глобальном объекте для node.
- Свойство в объекте
this.
Для полной конфигурации библиотеки и кода обратитесь к webpack-library-example.
Основная конфигурация
Теперь давайте соберем эту библиотеку таким образом, чтобы достичь следующих целей:
- Использование
externalsдля предотвращения объединенияlodash, поэтому потребитель должен загрузить его. - Установите имя библиотеки как
webpack-numbers. - Экспортируйте библиотеку как переменную, называемую
webpackNumbers. - Возможность доступа к библиотеке внутри Node.js.
Кроме того, потребитель должен иметь возможность доступа к библиотеке следующими способами:
- Модуль ES2015. Например,
import webpackNumbers from 'webpack-numbers'. - Модуль CommonJS. Например,
require('webpack-numbers'). - Глобальная переменная при включении через тег
script.
Мы можем начать с этой базовой конфигурации webpack:
webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'webpack-numbers.js',
},
}; Внешняя Lodash
Теперь, если вы запустите webpack, вы обнаружите, что создан большой пакет. Если вы изучите файл, вы увидите, что lodash был включен вместе с вашим кодом. В этом случае мы хотели бы рассматривать lodash как peerDependency. Это означает, что потребитель должен иметь 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',
},
+ externals: {
+ lodash: {
+ commonjs: 'lodash',
+ commonjs2: 'lodash',
+ amd: 'lodash',
+ root: '_',
+ },
+ },
}; Это означает, что ваша библиотека ожидает зависимость под названием lodash в среде потребителя.
Обратите внимание, что если вы планируете использовать свою библиотеку только как зависимость в другом пакете webpack, вы можете указать
externalsкак массив.
Внешние ограничения
Для библиотек, использующих несколько файлов из зависимости:
import A from 'library/one'; import B from 'library/two'; // ...
Вы не сможете исключить их из пакета, указав library в externals. Вам нужно будет либо исключить их по одному, либо использовать регулярное выражение.
module.exports = {
//...
externals: [
'library/one',
'library/two',
// Everything that starts with "library/"
/^library\/.+$/,
],
}; Экспорт библиотеки
Для широкого использования библиотеки нам необходимо, чтобы она была совместима в разных средах, таких как CommonJS, AMD, Node.js и как глобальная переменная. Чтобы ваша библиотека была доступна для использования, добавьте свойство library внутри output:
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',
},
externals: {
lodash: {
commonjs: 'lodash',
commonjs2: 'lodash',
amd: 'lodash',
root: '_',
},
},
}; Обратите внимание, что настройка
libraryсвязана с конфигурациейentry. Для большинства библиотек достаточно указать единственный пункт входа. Хотя многокомпонентные библиотеки возможны, проще экспортировать частичные экспонаты через скрипт индекса, который служит единственным точкой входа. Использованиеarrayкакentryточки для библиотеки не рекомендуется.
Это экспортирует ваш пакет библиотеки, доступный как глобальная переменная с именем webpackNumbers при импорте. Чтобы сделать библиотеку совместимой с другими средами, добавьте свойство libraryTarget в конфигурацию. Это добавит различные варианты экспорта библиотеки.
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',
+ libraryTarget: 'umd',
},
externals: {
lodash: {
commonjs: 'lodash',
commonjs2: 'lodash',
amd: 'lodash',
root: '_',
},
},
}; Вы можете экспортировать библиотеку следующими способами:
- Переменная: как глобальная переменная, доступная тегом
script(libraryTarget:'var'). - Этот объект: доступен через объект
this(libraryTarget:'this'). - Окно: доступен через объект
windowв браузере (libraryTarget:'window'). - UMD: доступно после AMD или CommonJS
require(libraryTarget:'umd').
Если library установлено, а libraryTarget нет, libraryTarget по умолчанию равно var, как указано в документации по конфигурации вывода. См. output.libraryTarget там для подробного списка всех доступных опций.
В webpack 3.5.5 использование
libraryTarget: { root:'_' }не работает должным образом (как указано в проблеме 4824). Однако вы можете установитьlibraryTarget: { var: '_' }для ожидания библиотеки как глобальной переменной.
Конечные шаги
Оптимизируйте свой вывод для производства, выполнив шаги, описанные в руководстве по производству. Также добавьте путь к сгенерированному пакету как поле main пакета в package.json
package.json
{
...
"main": "dist/webpack-numbers.js",
...
} Или, чтобы добавить его как стандартный модуль, как в этом руководстве:
{
...
"module": "src/index.js",
...
} Ключевое main относится к стандарту из package.json, а module к предложению для повышения возможности использования JavaScript-экосистемы ES2015-модулей без нарушения обратной совместимости.
Свойство
moduleдолжно указывать на скрипт, использующий синтаксис модулей ES2015, но не другие синтаксические конструкции, которые еще не поддерживаются браузерами или node. Это позволяет webpack парсить синтаксис модулей самостоятельно, что позволяет создавать более легкие пакеты с помощью tree shaking, если пользователи используют только определенные части библиотеки.
Теперь вы можете опубликовать его в качестве npm-пакета и найти его на unpkg.com, чтобы распространить его среди пользователей.
Для экспорта стилей, связанных с вашей библиотекой, следует использовать
MiniCssExtractPlugin. Пользователи могут затем использовать и загружать их так же, как и любой другой стиль.
© JS Foundation and other contributors
Licensed under the Creative Commons Attribution License 4.0.
https://v4.webpack.js.org/guides/author-libraries