许多工具能被构建库工程,例如 Webpack、Snowpack、Vite、Rollup 等。通常用Rollup可能会多一点,不顾webpack也不是不能用,也是常见的解决方案。
用webpack构建lib工程,应该关注一下几个点:
- 正确配置输入输出,以及package.json中读取使用库的入口;
- source map生成;
- 是否需要external;
- 是不是需要提取css成单文件;
配置输入输出
module.exports = {
mode: "production",
entry: "./src/index.js",
output: {
filename: "[name].js",
path: path.join(__dirname, "./lib"),
// lib特别的输出指定
// umd是比较通用的
library: {
name: "_",
type: "umd",
},
},
}
这里面需要注意的是library我们设置了umd的形式,umd兼容cmd、amd等常见的模块化形式,所以比较通用。
另外,package.json中要指定入口:
{
"main": "dist/main.js",
"module": "src/index.js",
}
比如,我们指定main是dist/main.js,module是esm模式的入口,直接使用源码都可以。
sourcemap
可以使用。devtool 配置项生成 Sourcemap 文件:
{
devtool: 'source-map'
}
extermals
为什么要配置externals呢?
因为我们期望自己的lib打包体积变小:如果你的lib中引用了其他的lib,默认是会将所有的包都打包起来的。这样就造成了体积过大。
这时候如果把引用的包,用external声明起来,打包的时候就不会被加入到最终产物中,这样体积就不会那么大了。自己的lib打包后,生成的UMD 模板通过 require、define 函数中引入 external依赖。
{
externals: {
// 所有node modules的依赖都不打包
// const nodeExternals = require('webpack-node-externals')
// externals: [nodeExternals()]
// lodash将不被打包
lodash: {
commonjs: "lodash",
commonjs2: "lodash",
amd: "lodash",
root: "_",
},
},
}
但是这样存在一个风险就是:external的依赖并不存在在当前环境中。
解决的办法是,package.json中声明peerDependencies:
"peerDependencies": {
"lodash": "^4.17.21"
}
关于peerDependencies可参考:、
当你安装一个包时,其 dependencies 和 devDependencies 会被 npm 自动安装。 peerDependencies 则有所不同,它们不会被自动安装。 当一个依赖项 c 被列在某个包 b 的 peerDependency 中时,它就不会被自动安装。取而代之的是,包含了 b 包的代码库 a 则必须将对应的依赖项 c 包含为其依赖。
抽离css
如果写的是UI库,那么这一步就很重要。
还是借助MiniCssExtractPlugin,这里注意使用了MiniCssExtractPlugin以及MiniCssExtractPlugin.loader,而且MiniCssExtractPlugin.loader是在css-loader之后的。
{
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
plugins: [new MiniCssExtractPlugin()],
}