アプリケーション以外に、webpackはJavaScriptライブラリをバンドルするためにも使用できます。以下のガイドは、バンドル戦略を合理化しようとしているライブラリ作成者を対象としています。
ここでは、ユーザーが1から5までの数値を数値表現からテキスト表現に、またはその逆に変換できるようにする小さなライブラリwebpack-numbersを作成すると仮定します。例:2を'two'に変換。
基本的なプロジェクト構造は次のようになります
プロジェクト
+ |- webpack.config.js
+ |- package.json
+ |- /src
+ |- index.js
+ |- ref.jsonnpmでプロジェクトを初期化し、webpack、webpack-cli、lodashをインストールします
npm init -y
npm install --save-dev webpack webpack-cli lodashlodashは、ライブラリにバンドルしたくないため、またはライブラリが簡単に肥大化する可能性があるため、dependenciesではなく、devDependenciesとしてインストールします。
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.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タグで機能するライブラリをバンドルします。
ここで、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';
// ...externalsでlibraryを指定しても、バンドルから除外することはできません。一つずつ除外するか、正規表現を使用する必要があります。
module.exports = {
//...
externals: [
'library/one',
'library/two',
// Everything that starts with "library/"
/^library\/.+$/,
],
};プロダクションガイドに記載されている手順に従って、プロダクション向けに出力を最適化してください。また、生成されたバンドルのパスをpackage.jsonのパッケージのmainフィールドとして追加しましょう。
package.json
{
...
"main": "dist/webpack-numbers.js",
...
}または、このガイドに従って、標準モジュールとして追加します。
{
...
"module": "src/index.js",
...
}キーmainは、package.jsonの標準を指し、moduleは、a proposal であり、JavaScript エコシステムが後方互換性を損なうことなく ES2015 モジュールを使用できるようにするためのものです。
これで、npmパッケージとして公開し、unpkg.comで見つけてユーザーに配布できます。