rollup.js 是一款简单易用的 ES 模块打包工具。
Rollup的安装
npm安装即可,我这边是全局安装的4.12.0版本
Rollup的基本使用
最基础的功能
可以直接使用rollup命令rollup main.js --file bundle.js,直接将两个文件打包成一个文件
打包前
// TestA.js
export const logFunction = () => {
console.log("123");
};
// main.js
import { logFunction } from "./src/TestA";
logFunction();
打包后
// bundle.js
const logFunction = () => {
console.log("123");
};
logFunction();
使用config配置文件
实际的打包配置比较复杂,使用配置文件会方便一点。
//rollup.config.js
export default {
input: "main.js",
output: [
{
file: "dist/esm/index.js",
},
],
plugins: [],
};
打包命令pnpm rollup -c
但会提示错误
RollupError: Node tried to load your configuration file as CommonJS even though it is likely an ES module. To resolve this, change the extension of your configuration to ".mjs", set "type": "module" in your package.json file or pass the "--bundleConfigAsCjs" flag.
这个时候在package.json中,添加"type": "module",声明项目中的所有.js文件都使用Es Modules就可以正常打包了。
{
"name": "hy-rollup",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module", // 添加配置
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
打包format Todo
使用插件
Rollup的基础功能只是一个ESM打包器,有些复杂场景就需要使用rollup插件来处理了。
打包Typescript
首先新建三个Ts文件
// TestA.ts
const testA = (number: number): string => {
console.log(number);
return "num is " + number;
};
export default testA;
// TestB.ts
import testA from "./TestA";
export const testB = (...params: any) => {
testA(10);
console.log(params);
};
export let testBB = "testBB";
// main.ts
import { testB } from "./src/TestB";
testB();
然后再调用原有命令,会报错。这个时候就需要用rollup插件来处理了。首先安装1个rollup插件和两个ts依赖
pnpm add @rollup/plugin-typescript
pnpm add tslib -D
pnpm add typescript -D
然后再执行pnpm rollup -c,就可以正常的打包了。打包结果如下。
var testA = function (number) {
console.log(number);
return "num is " + number;
};
var testB = function () {
var params = [];
for (var _i = 0; _i < arguments.length; _i++) {
params[_i] = arguments[_i];
}
testA(10);
console.log(params);
};
testB();
通过ts配置文件控制ts编译
如果我们想对ts编译做控制,可以使用npx tsc --init命令,在根栏目创建一个tsconfig.js配置文件。
初始化的配置文件,这里我把注释都删掉了。
{
"compilerOptions": {
"target": "es2016",
"module": "commonjs",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
}
}
但是这样打的包会变成这个样子,明显不是我们想要的。
Object.defineProperty(exports, "__esModule", { value: true });
const TestB_1 = require("./src/TestB");
(0, TestB_1.testB)();
可以猜测下,@rollup/plugin-typescript插件里的默认读取的ts配置和tsc默认生成的不同,这个时候就需要研究下tsconfig.json里面的参数了。研究过后发现,只要修改以下两个参数,就能打包成我们想要的样子了。
// tsconfig.json
{
"compilerOptions": {
"target": "ES5", // 想要的编译后的结果
"module": "ES6", // 使用什么模块处理模式
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"moduleResolution": "Bundler"
}
}
此外,上面的配置文件,我还偷偷的加上了"moduleResolution": "Bundler"配置,它以让你使用 exports 声明类型的同时,使用相对路径模块可以不写扩展名。 具体可以看这篇文章。
@rollup/plugin-alias
通过@rollup/plugin-alias插件可以给import路径设置别名
import alias from '@rollup/plugin-alias';
export default {
input: 'src/index.js',
output: {
dir: 'output',
format: 'cjs'
},
plugins: [
alias({
entries: [
{ find: 'utils', replacement: '../../../utils' },
{ find: 'batman-1.0.0', replacement: './joker-1.5.0' }
]
})
]
};
@rollup/plugin-node-resolve
这个插件可以让我们直接使用npm包名称来import npm包(rollup默认必须使用文件路径来引入npm包)
import { nodeResolve } from '@rollup/plugin-node-resolve';
export default {
input: 'src/index.js',
output: {
dir: 'output',
format: 'cjs'
},
plugins: [nodeResolve()]
};
@rollup/plugin-commonjs
允许我们打包commonjs,正常情况下,我们开发前端项目的js库时,是不会写commonjs的,但是我们有时会引入第三方的npm包,其中可能有的npm包是用commonjs模式导出的,这个时候我们就需要用到这个插件了
@rollup/plugin-json
可以import json文件
举个例子
把axios打包进我们的库中。
import axios from "axios";
const testA = (number: number): string => {
console.log(number, axios);
return "num is " + number;
};
export default testA;
- 需要引入
@rollup/plugin-typescript插件来处理ts - 需要使用
@rollup/plugin-node-resolve来处理第三方npm包名的解析 - 打包过程中会报错,因为axios内部还使用了commonjs模块以及对json的引用,所以还需要使用
@rollup/plugin-commonjs插件以及@rollup/plugin-json插件 - 打包成功,但是发现打包产物里面还有require("xx"),后面在使用这个js库的时候还会报错。
- 如果对插件配置比较熟悉的话,可以给
@rollup/plugin-node-resolve插件配置browser: true ,就可以正常使用了,同时也不需要使用@rollup/plugin-commonjs插件了()
// 配置文件
import typescript from "@rollup/plugin-typescript";
import { nodeResolve } from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import json from "@rollup/plugin-json";
export default {
input: "main.ts",
output: [
{
file: "dist/esm/index.js",
},
],
plugins: [
typescript(),
nodeResolve({ browser: true }), //commonjs(),
json(),
],
};
@rollup/plugin-babel
这里我们用了tsc,编译ts,如果是用js写的库的话,需要用babel编译。(之前看到大部分文章,编译ts库也都用rollupplugin-babel,还没搞懂原因)