W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗(yàn)值獎勵
除了打包應(yīng)用程序,webpack 還可以用于打包 JavaScript library。以下指南適用于希望簡化打包策略的 library 作者。
假設(shè)我們正在編寫一個名為 webpack-numbers 的小的 library,可以將數(shù)字 1 到 5 轉(zhuǎn)換為文本表示,反之亦然,例如將 2 轉(zhuǎn)換為 'two'。
基本的項(xiàng)目結(jié)構(gòu)可能如下所示:
project
+ |- webpack.config.js
+ |- package.json
+ |- /src
+ |- index.js
+ |- ref.json
使用 npm 初始化項(xiàng)目,然后安裝 webpack,webpack-cli 和 lodash:
npm init -y
npm install --save-dev webpack webpack-cli lodash
我們將 lodash 安裝為 devDependencies 而不是 dependencies,因?yàn)槲覀儾恍枰獙⑵浯虬轿覀兊膸熘?,否則我們的庫體積很容易變大。
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 中。
到目前為止,一切都應(yīng)該與打包應(yīng)用程序一樣,這里是不同的部分 - 我們需要通過 output.library 配置項(xiàng)暴露從入口導(dǎo)出的內(nèi)容。
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",
},
};
我們將入口起點(diǎn)公開為 webpackNumbers,這樣用戶就可以通過 script 標(biāo)簽使用它:
<script src="https://example.org/webpack-numbers.js" rel="external nofollow" rel="external nofollow" ></script>
<script>
window.webpackNumbers.wordToNum('Five');
</script>
然而它只能通過被 script 標(biāo)簽引用而發(fā)揮作用,它不能運(yùn)行在 CommonJS、AMD、Node.js 等環(huán)境中。
作為一個庫作者,我們希望它能夠兼容不同的環(huán)境,也就是說,用戶應(yīng)該能夠通過以下方式使用打包后的庫:
const webpackNumbers = require('webpack-numbers');
// ...
webpackNumbers.wordToNum('Two');
require(['webpackNumbers'], function (webpackNumbers) {
// ...
webpackNumbers.wordToNum('Two');
});
<!DOCTYPE html>
<html>
...
<script src="https://example.org/webpack-numbers.js" rel="external nofollow" rel="external nofollow" ></script>
<script>
// ...
// Global variable
webpackNumbers.wordToNum('Five');
// Property in the window object
window.webpackNumbers.wordToNum('Five');
// ...
</script>
</html>
我們更新 output.library 配置項(xiàng),將其 type 設(shè)置為 'umd':
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'webpack-numbers.js',
- library: 'webpackNumbers',
+ library: {
+ name: 'webpackNumbers',
+ type: 'umd',
+ },
},
};
現(xiàn)在 webpack 將打包一個庫,其可以與 CommonJS、AMD 以及 script 標(biāo)簽使用。
現(xiàn)在,如果執(zhí)行 webpack,你會發(fā)現(xiàn)創(chuàng)建了一個體積相當(dāng)大的文件。如果你查看這個文件,會看到 lodash 也被打包到代碼中。在這種場景中,我們更傾向于把 lodash 當(dāng)作 peerDependency。也就是說,consumer(使用者) 應(yīng)該已經(jīng)安裝過 lodash 。因此,你就可以放棄控制此外部 library ,而是將控制權(quán)讓給使用 library 的 consumer。
這可以使用 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: '_',
+ },
+ },
};
這意味著你的 library 需要一個名為 lodash 的依賴,這個依賴在 consumer 環(huán)境中必須存在且可用。
對于想要實(shí)現(xiàn)從一個依賴中調(diào)用多個文件的那些 library:
import A from 'library/one';
import B from 'library/two';
// ...
無法通過在 externals 中指定整個 library 的方式,將它們從 bundle 中排除。而是需要逐個或者使用一個正則表達(dá)式,來排除它們。
module.exports = {
//...
externals: [
'library/one',
'library/two',
// 匹配以 "library/" 開始的所有依賴
/^library\/.+$/,
],
};
遵循 生產(chǎn)環(huán)境 指南中提到的步驟,來優(yōu)化生產(chǎn)環(huán)境下的輸出結(jié)果。那么,我們還需要將生成 bundle 的文件路徑,添加到 package.json 中的 main 字段中。
package.json
{
...
"main": "dist/webpack-numbers.js",
...
}
或者,按照這個 指南,將其添加為標(biāo)準(zhǔn)模塊:
{
...
"module": "src/index.js",
...
}
這里的 key(鍵) main 是參照 package.json 標(biāo)準(zhǔn),而 module 是參照 一個提案,此提案允許 JavaScript 生態(tài)系統(tǒng)升級使用 ES2015 模塊,而不會破壞向后兼容性。
現(xiàn)在,你可以 將其發(fā)布為一個 npm package,并且在 unpkg.com 找到它,并分發(fā)給你的用戶。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: