需求
打包一个支持大整数计算的基础库,需要支持的版本:
- 需要打包压缩版和非压缩版
- 需要支持 AMD/CJS/ESM 模块引入
配置
创建webpack项目
- 创建一个空目录
- 执行
npm init初始化项目 - 安装对应的依赖
npm install webpack webpack-cli -D
包文件
包文件重点需要注意的点:export default, 若没有导出对应的方法或者组件,发布到npm上后安装该依赖,会导致当前的包为undefined
// src/index.js
// 算法 两数相加
export default function add(a, b) {
let i = a.length - 1;
let j = b.length - 1;
// 进位
let carry = 0;
let res = '';
// 两数相加
while(i >= 0 || j >= 0) {
let x = 0;
let y = 0;
let sum;
if (i >= 0) {
x = a[i] - 0;
i--;
}
if (j >= 0) {
y = b[j] - 0;
j--;
}
sum = x + y + carry;
if (sum >= 10) {
carry = 1;
sum -= 10;
} else {
carry = 0;
}
res = sum + res;
}
if (carry) {
res = carry + res;
}
return res;
}
webpack.config.js配置
基础库打包和普通的项目打包配置绝大部分是一样的。主要区别在于output。如果是打包基础库,需要在output中配置一个library属性,属性值里面对包名、库类型、库的可使用模块方式等的定义。
module.exports = {
mode: 'production',
entry: {
'large-number': './src/index.js',
'large-number.min': './src/index.js'
},
output: {
// 导出的文件名
filename: '[name].js',
library: {
// 指定库的名称
name: 'largeNumber',
// 指定哪一个导出应该被暴露为一个库
export: 'default',
// umd: 这将在所有模块定义下暴露你的库, 允许它与 CommonJS、AMD 和作为全局变量工作
type: 'umd'
}
}
}
配置好webpack.config.js后,想要打包构建基础库。需要进一步配置package.json文件。在package.json文件中添加script命令: "build": "webpack"用于打包构建库
但在当前webpack.config.js配置下打包生成的bundle文件都会被自动压缩,原因是: mode模式为production下的 js 会默认被压缩。 若想打包出一个不被压缩的libary, 需要将mode设置为none, 再使用optimization的优化属性,使用TerserPlugin插件来将libary.min.js进行压缩处理。下面就将对第一版的webpack.config.js进行改进。
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
mode: 'none',
entry: {
'large-number': './src/index.js',
'large-number.min': './src/index.js'
},
output: {
// 导出的文件名
filename: '[name].js',
library: {
// 指定库的全局变量名称
name: 'largeNumber',
// 指定哪一个导出应该被暴露为一个库
export: 'default',
// umd: 这将在所有模块定义下暴露你的库, 允许它与 CommonJS、AMD 和作为全局变量工作
type: 'umd'
}
},
optimization: {
// 告知 webpack 使用 TerserPlugin 或其它在 optimization.minimizer定义的插件压缩 bundle
minimize: true,
minimizer: [new TerserPlugin({
include: /\.min\.js$/
})]
}
}
配置包入口文件
配置包的入口文件,如果是打一个基础库或者包,需要在package.json文件中配置main属性,main属性定义了包的入口文件。定义好入口文件后,需要在项目中建立一个入口文件同名文件index.js作为入口。当前需求是开发环境下使用非压缩版本,开发环境下使用压缩版本。
// package.json
{
"name": "largestnumber",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack"
},
"author": "",
"license": "ISC",
"devDependencies": {
"terser-webpack-plugin": "^5.3.1",
"webpack": "^5.71.0",
"webpack-cli": "^4.9.2"
}
}
使用全局的process.env.NODE_ENV判断当前引入文件的环境,根据不同的环境引入不同dist文件
// index.js
if (process.env.NODE_ENV === 'production') {
module.exports = require('./dist/large-number.min.js');
} else {
module.exports = require('./dist/large-number.js');
}
发布到npm
注册npm账户
注册npm账号比较简单,直接官网注册即可。
生成package.json
package.json文件配置,重要的是需要配置一个main属性。可以在scripts中添加一个命令 "prepublish": "webpack" , 每次npm publish发布时会自动去执行该命令进行构建。
通过命令行登录到npm
执行npm login命令,登录npm 根据面板提示,依次填入用户名、密码、邮箱以及验证码即可。
执行发布命令
执行npm publish命令进行发布,需要注意的是包名的唯一性,如果提示包名重复或者包名错误等信息,及时调整包名。
基础包发布成功上npm后,与正常安装依赖一样使用即可。目前发布的包npm install large-number-guazi, 引入: import largeNumber from 'large-number-guazi'。如下正常使用即可
需继续深入了解
包的按需引入,参考lodash。未完待续