webpack打包组件和基础库

599 阅读3分钟

需求

  打包一个支持大整数计算的基础库,需要支持的版本:

  • 需要打包压缩版和非压缩版
  • 需要支持 AMD/CJS/ESM 模块引入

配置

webpack打包库

创建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 根据面板提示,依次填入用户名、密码、邮箱以及验证码即可。 image.png

执行发布命令

  执行npm publish命令进行发布,需要注意的是包名的唯一性,如果提示包名重复或者包名错误等信息,及时调整包名。 image.png

  基础包发布成功上npm后,与正常安装依赖一样使用即可。目前发布的包npm install large-number-guazi, 引入: import largeNumber from 'large-number-guazi'。如下正常使用即可

image.png

需继续深入了解

  包的按需引入,参考lodash。未完待续