构建 library
webpack 除了打包应用程序代码,还可以用于打包 JavaScript library
应用场景
- 提炼高可服用工具类 code
- 构建 UI 库
- 根据业务需求,在其他 UI 库的基础上做业务组件封装
...
兼容性
用户应该能够通过以下方式访问 library
- ES2015 模块
import webpackNumbers from 'webpack-numbers'
- CommonJS 模块
require('webpack-numbers')
- AMD
- CMD
- 全局变量,当通过 script 脚本引入时
- Nodejs
output
跟 webpack 打包部署代码最大的不同点就在于 output 输出属性的配置上,webpack 为构建 lib 提供了 library,libraryTarget, libraryExport 等属性
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'myLib.js',
library: 'myLib', // 暴露出去的变量的名字
libraryTarget: 'umd'
}
library
暴露的模块名称。取决于 libraryTarget 的值,当 libraryTarget:commonjs2 时无效
libraryTarget
暴露library的方式
-
变量,以 script 方式引用, 默认值。 node 环境不支持
- var
- assign
这两个属性,都是在全局创建一个变量,只有定义与未定义的区别,并不能在 nodejs 中得的支持,并且存在变量冲突的可能性
module.exports = {
mode: "production",
entry: "./q-library/index.js",
output: {
path: path.resolve(process.cwd(), "./lib"),
filename: "q-library.js",
library: "qlibrary", // 模块名称
libraryTarget: "assign",
},
};
-
对象属性
- window。在 window 对象上定一个 library 设置的变量,不支持 node。
- global。在 global 对象上定义一个 library 设置的变量。受 target 属性影响,当 target 为默认值 web 时,会在 window 上注册,如果你想在 global 上注册,必须修改 target 为 node
- this。在当前 this 对象上定义一个 library 设置的变量。如果 this 是 window,就在 window。在 node 的环境中,如果没指定 require 赋值的变量,并不会在指向 global。
module.exports = {
mode: "production",
entry: "./q-library/index.js",
target: "node", // 默认值为 web, 如果想导出属性绑定在 gloabl 对象上,必须修改此属性为 node
output: {
path: path.resolve(process.cwd(), "./lib"),
filename: "q-library2.js",
library: "qlibrary2", // 模块名称
libraryTarget: "global",
},
};
-
模块定义
- commonjs。在 export 对象上定义 library 设置的变量,不支持浏览器。
- commonjs2。直接用 module.export 导出 export,会忽略 library 设置的变量。不支持浏览器
- amd。在 define 方法上定义 library 设置的变量,不能用 script 直接引用,必须通过第三方模块 RequireJS 来时用
- umd。兼容的模块化定义。该方案支持 commonjs、commonjs2、amd,可以在浏览器、node 中通用。但是如果你想做到这一点,必须要额外设置,umdNamedDefine: true,globalObject: ‘this’,umdNamedDefine 为设置 amd 前置名称使用 library 设置的变量,globalObject 为改变全局指向。当然便捷的引入一定会带来一定的冗余,这就看你如何取舍了。最后建议,如果目标明确,我只是兼容 nodejs,那么选择 commonjs/commonjs2,如果只兼容浏览器,那就选择暴露变量的方式,如果想通用,那就选择 umd 的方式,对于不同的情况做多种处理方式,是非常明智的选择。
module.exports = {
mode: "production",
entry: "./q-library/index.js",
// target: 'node',// 默认值为 web, 如果想导出属性绑定在 gloabl 对象上,必须修改此属性为 node
output: {
path: path.resolve(process.cwd(), "./lib"),
filename: "q-library3.js",
library: "qlibrary3", // 模块名称
libraryTarget: "umd",
globalObject: "this",
umdNamedDefine: true,
},
};
- libraryExport
配置哪个或者哪些模块将通过 libraryTarget 暴露出来
这个属性的常用方式是和 libraryTarget 一起使用
// 将mudule.exports 的default直接导出
{
libraryTarget: 'commonjs2',
libraryExport: 'default'
}
externals
- 如果构建的 library 依赖第三方 library,但是又不想把这个依赖打包到自己的 library 中。把依赖的主动权交给用户
- 这意味着你的 library 需要一个名为 lodash 的依赖,这个依赖在用户的环境中必须存在且可用
externals: {
lodash: {
commonjs: 'lodash',
commonjs2: 'lodash',
amd: 'lodash',
root: '\_'
}
}