webpack library篇|博客系列
# 一、webpack-numbers案例
这里我也不折腾了, 就以官网提供的案例进行讲解吧.
首先让我们明确要做什么事情.
- 本地编写创建一个名为
lindaidai-webpack-numbers的项目(也就是library) - 这个library的功能是导出两个方法, 能实现数字与字符串的互相转换
- library中用到了lodash这个工具库
- 将library打包发布到NPM上, 其它用户能够通过
npm install的方式下载使用 - 外部化lodash, 也就是我们library虽然使用了lodash, 但是并不要将它打包到我们的bundle中
- 用户能通过ES2015模块, CommonJS模块, script脚本引入我们的library并使用它
该 library 的使用方式如下:
// ES2015模块引入
import * as webpackNumbers from 'lindaidai-webpack-numbers'
// CommonJS模块引入
var webpackNumbers = require('lindaidai-webpack-numbers')
// ES2015模块和CommonJS模块都是这样调用的:
webpackNumbers.numToWord(2)
// AMD模块引入
require(['lindaidai-webpack-numbers'], function (webpackNumbers) {
// AMD 模块调用
webpackNumbers.wordToNum('Two');
})
用户还可以通过 script 标签来加载和使用此 library:
<!doctype html>
<html>
...
<script src="https://unpkg.com/lindaidai-webpack-numbers"></script>
<script>
// ...
// 全局变量
webpackNumbers.wordToNum('Five')
// window 对象中的属性
window.webpackNumbers.wordToNum('Five')
// ...
</script>
</html>
# 创建library的项目结构
让我们使用webpack快速的构建一个本地的library.
由于有了之前webpack的基础, 我相信你构建起来应该也会很快.
mkdir lindaidai-webpack-numbers && cd lindaidai-webpack-numbers
npm init -y
cnpm i --save-dev webpack webpack-cli lodash
touch webpack.config.js
mkdir src && cd src
touch index.js
touch ref.json
一顿操作之后, 项目结构变成了这样:
lindaidai-webpack-numbers
|- /node_modules
|- /src
|- index.js
|- ref.json
|- package.json
|- webpack.config.js
之后来简单的编写一下文件中的代码:
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 num === ref.num ? ref.word : accum
})
}
export function wordToNum(word) {
return _.reduce(numRef, (accum, ref) => {
return ref.word === word && word.toLowerCase() ? ref.num : accum;
}, -1);
};
webpack.config.js:
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'webpack-numbers.js'
}
};
# 配置webpack.config.js
编写完成上面👆几个文件之后, 打包之后生成的dist目录就只有一个webpack-numbers.js文件:
/dist
|- webpack.numbers.js
但是我们注意到生成的js中包含了lodash:
lindaidai@LinDaiDaideMacBook-Pro lindaidai-webpack-numbers % npm run build
> lindaidai-webpack-numbers@1.0.0 build /Users/lindaidai/codes/webpack/lindaidai-webpack-numbers
> webpack
Hash: e49f78747376a068a282
Version: webpack 4.41.5
Time: 1544ms
Built at: 2020-02-10 6:57:59 PM
Asset Size Chunks Chunk Names
+ webpack-numbers.js 72.4 KiB 0 [emitted] main
所以导致webpack-number.js非常大.
# 外部化lodash(配置externals)
因此对于这种我们额外引入的module, 我们更倾向于把 lodash 当作 peerDependency。也就是说,用户应该已经将 lodash 安装好.
所以,你可以放弃对外部 library 的控制,而是将控制权让给使用 library 的用户。
这个功能需要靠externals配置:
webpack.config.js:
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: '_'
+ }
}
};
这意味着你的 library 需要一个名为
lodash的依赖,这个依赖在用户的环境中必须存在且可用。
# 暴露library
因为我们编写的library可能会在不同的执行环境中用到,例如 CommonJS,AMD,Node.js 或者作为一个全局变量.
所以为了实现这个功能, 我们首先需要在oupout中添加library属性:
webpack.config.js:
var 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属性是为了将library在打包之后的bundle文件中暴露一个名为webpackNumbers的全局变量.
但是还需要指定我们的library在怎样的环境中使用.
这依靠于libraryTarget属性, 它可以控制library如何以不同方式暴露的选项.
主要有以下几个值:
- 变量:作为一个全局变量,通过
script标签来访问(libraryTarget:'var')。 - this:通过
this对象访问(libraryTarget:'this')。 - window:通过
window对象访问,在浏览器中(libraryTarget:'window')。 - UMD:在 AMD 或 CommonJS 的
require之后可访问, 也就是以上几种环境都可以访问(libraryTarget:'umd')
如果设置了 library 但没设置 libraryTarget,则 libraryTarget 默认为 var
所以在此处我希望在所有的环境中都能使用, 则只要设置libraryTarget: 'umd':
var 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: '_'
}
}
};
# 发布至NPM
现在我们希望的是将打包之后的dist文件与这整个项目一起发布到NPM上.
所以我们需要执行打包命令让library项目目录结构变为:
lindaidai-webpack-numbers
|- /dist
|- webpack.numbers.js
|- /src
|- index.js
|- ref.json
|- package.json
|- webpack.config.js
(如果你的项目没有配置打包命令的话需要在package.json中配置一个脚本命令"build": “webpack”, 这样你就可以执行npm run build指令进行打包了)
# 登录npm
npm adduser //创建用户(如果你没有npm账号的话)
or
npm login //登录用户
可以使用:
npm whoami
检测用户是否登录上了npm
