Spec-Zone.ru › webpack 5

Библиотеки для разработки

Помимо приложений, 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.

подсказка

Обратите внимание, что настройка library связана с настройкой entry. Для большинства библиотек достаточно указать одну точку входа. Хотя библиотеки с несколькими частями возможны, проще экспортировать частичные экспонаты через скрипт индекса, который служит единственной точкой входа. Использование array в качестве точки входа для библиотеки не рекомендуется.

Внешняя зависимость 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 без нарушения обратной совместимости.

предупреждение

Свойство module должно указывать на скрипт, который использует синтаксис модулей ES2015, но не другие синтаксические конструкции, которые ещё не поддерживаются браузерами или Node.js. Это позволяет webpack анализировать синтаксис модулей сам, что позволяет создавать более лёгкие объединённые файлы за счёт удаления неиспользуемых частей, если пользователи используют только определённые части библиотеки.

Теперь вы можете опубликовать его как пакет npm и найти его на unpkg.com, чтобы распространить его среди пользователей.

подсказка

Чтобы экспортировать таблицы стилей, связанные с вашей библиотекой, следует использовать MiniCssExtractPlugin. Пользователи могут затем использовать и загружать их как любые другие таблицы стилей.

© JS Foundation and other contributors
Licensed under the Creative Commons Attribution License 4.0.
https://webpack.js.org/guides/author-libraries

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API