skip to content
1874

Rollup打包——多入口配置

/ 5 min read

最后更新:

适用场景

当开发一个组件包时,由于平台的差异,所以在某些实现上需要实现两套。

例如,multi-input是一个可以同时用于微信小程序和浏览器环境的npm库,其中的request请求库在不同客户端的实现不一样。在微信环境下用的是wx.request,在浏览器环境用的是fetch

但是在微信环境使用时,我不希望我引入的代码中包含用不到的适用于浏览器环境的fetch等相关代码。再加上微信小程序对于代码体积的严格限制。所以我希望multi-input再引入的时候可以有多个入口,主逻辑代码直接引入multi-inputrequest库相关逻辑单独有个入口。

解决办法有两种

  1. request库相关逻辑抽离成另外一个npm
  2. rollup打包多入口文件并配合package.json中的exports字段实现

本文介绍第二种方法,使用示例如下:

import { TestCore } from 'multi-input' // 引用的是 dist 文件中的代码
import { WebRequest } from 'multi-input/lib/web-request'// 引用的是 lib 文件中的代码
import { WxRequest } from 'multi-input/lib/wx-request' // 引用的是 lib 文件中的代码

这样在微信小程序端使用并打包时,就不会将WebRequest相关代码打包到微信小程序代码中,实现按需引入。

代码结构

| 代码源码:multi-input

multi-input库代码结构如下

.
|-multi-input
|-.gitignore
|-adapter // 这里面就是不同客户端的request请求库的实现的源代码
| |-web-request.ts
| |-wx-request.ts
|-src
| |-core.ts
| |-index.ts
| |-manager
| | |-message.ts
| |-utils
| | |-url.ts
|-rollup.config.js // rollup打包配置
|-tsconfig.json
|-package.json

注意事项

要想要外部以这样的方式引用,有几个必要条件:

  1. 代码隔离:adapter下的文件只能引用adapter目录中的文件,src下中的文件只能引用src中的文件
  2. 打包产物路径存在:multi-input根目录下必须存在打包后的lib/web-request文件
  3. 路径映射:package.json中的exports字段中需要有lib/web-request的路径映射
  4. 多入口打包:rollup需要分别打包srcadapter下的文件

Rollup配置

功能点如下

  • multi-inputesm模式导出到dist
  • adapter下的请求库以esm模式导出到lib
  • 打包后的类型声明文件和js文件和原文件目录结构保持一致
rollup.config.js
import resolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs"; // 解析js
import typescript from "@rollup/plugin-typescript"; // 解析ts
const getBasePlugins = (tsConfig) => {
return [
resolve(),
commonjs(),
typescript({
...tsConfig,
}),
];
};
export default [
// 主逻辑代码打包
{
input: "src/index.ts",
output: {
dir: "dist",
format: "esm",
exports: "named",
preserveModules: true,
preserveModulesRoot: "src",
sourcemap: true,
},
plugins: [
...getBasePlugins({
outDir: "dist",
declaration: true,
filterRoot: "src",
}),
],
},
// adapter导出
{
input: {
"web-request": "adapter/web-request.ts",
"wx-request": "adapter/wx-request.ts",
},
output: [
{
dir: "lib",
format: "esm",
sourcemap: true
},
],
plugins: [
...getBasePlugins({
outDir: "lib",
declaration: true,
filterRoot: "adapter",
}),
],
},
];

package.json配置

{
"name": "multi-input",
"version": "1.0.0",
"description": "多入口打包",
"main": "dist/index.js",
"module": "dist/index.js",
"typings": "dist/index.d.ts",
"scripts": {
"build": "rollup -c rollup.config.js --bundleConfigAsCjs",
"clean": "rimraf -rf ./dist ./lib"
},
"files": ["dist", "lib"],
"exports": {
// 定义multi-input路径引用文件
".": "./dist/index.js",
// 定义multi-input/lib/web-request路径引用文件
"./lib/web-request": {
"import": "./lib/web-request.js",
"types": "./lib/web-request.d.ts"
},
// 定义multi-input/lib/wx-request路径引用文件
"./lib/wx-request": {
"import": "./lib/wx-request.js",
"types": "./lib/wx-request.d.ts"
}
},
"author": "1874",
"license": "ISC",
"devDependencies": {
"@rollup/plugin-commonjs": "^25.0.4",
"@rollup/plugin-node-resolve": "^15.2.1",
"@rollup/plugin-typescript": "^11.1.3",
"rimraf": "^5.0.1",
"rollup": "^3.28.1",
"tslib": "^2.6.2",
"typescript": "^5.2.2"
}
}

打包后代码结构

.
|-multi-input
|-dist // 主包打包产物
| |-core.d.ts
| |-core.js
| |-core.js.map
| |-index.d.ts
| |-index.js
| |-index.js.map
| |-manager
| | |-message.d.ts
| | |-message.js
| | |-message.js.map
| |-utils
| | |-url.d.ts
| | |-url.js
| | |-url.js.map
|-lib // request 插件打包产物
| |-tslib.es6-4083ca3c.js
| |-tslib.es6-4083ca3c.js.map
| |-web-request.d.ts
| |-web-request.js
| |-web-request.js.map
| |-wx-request.d.ts
| |-wx-request.js
| |-wx-request.js.map
|-adapter // request 插件源码
| |-web-request.ts
| |-wx-request.ts
|-src // 主包源码
| |-core.ts
| |-index.ts
| |-manager
| | |-message.ts
| |-utils
| | |-url.ts
|-package.json
|-pnpm-lock.yaml
|-rollup.config.js
|-tsconfig.json

参考资料