アプリケーション以外に、webpackはJavaScriptライブラリをバンドルするためにも使用できます。以下のガイドは、バンドル戦略を合理化しようとしているライブラリ作成者を対象としています。
ここでは、ユーザーが1から5までの数値を数値表現からテキスト表現に、またはその逆に変換できるようにする小さなライブラリwebpack-numbers
を作成すると仮定します。例:2を'two'に変換。
基本的なプロジェクト構造は次のようになります
プロジェクト
+ |- 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
は、ライブラリにバンドルしたくないため、またはライブラリが簡単に肥大化する可能性があるため、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で見つけてユーザーに配布できます。