rollup简介
rollup是一个JavaScript模块打包器、它很轻量、没有webpack的重、也不需要像webpack一样对不同复杂的场景做打包覆盖、一般用于工程化库的打包、很多大型框架Vue、React等也是使用rollup进行打包!
start
yarn init // 初始化package.json
yarn add rollup -D // 安装rollup
// package.json配置script
"scripts": {
"build":"rollup --config rollup.config.js"
}
rollup.config.js
在根节点里面添加rollup.config.js、添加配置信息
export default {
input: 'src/main.js',
output:[
{
file: './dist/bundle.es.js',
format: 'es',
name: 'BundleEs'
},
{
file: './dist/bundle.umd.js',
format: 'umd',
name: 'BundleUMD'
}
]
};
创建打包文件内容
——src
——main.ts
——demo
index.ts
// main.js
import { name } from "./demo/index"
console.log(name)
// demo/index.js
export const name = 'demo'
执行build
常用插件使用
- @rollup/plugin-babel [ 将高级语法转换为低浏览器也能运行的代码 ]
- @rollup/plugin-node-resolve [ import xxx from “xxx/index.js” => import xxx from “xxx”、还有主要用于查找和打包node_modules中的第三方模块 ]
- @rollup/plugin-commonjs [ 很多插件模块使用的是commonJS、需要将commonJS转为ESModule ]
- rollup-plugin-uglify [ 代码压缩 ]
- @rollup/plugin-typescript [ 解析TS ]
搭建TS版本cli
在上面的工程下把 js 统一改为 ts
yarn add @rollup/plugin-typescript -D // 添加解析typescript插件
// rollup.config.js
export default {
input: 'src/main.ts',
output:[
{
file: './dist/bundle.es.js',
format: 'es',
name: 'BundleEs'
},
{
file: './dist/bundle.umd.js',
format: 'umd',
name: 'BundleUMD'
}
],
plugins:[
typescript()
]
};
// main.ts
import { add } from "./demo"
const sum = add(1,2);
console.log(sum)
// demo/index.ts
export function add(n1:number, n2:number):number{
return n1 + n2
}
// 执行yarn build进行打包
配置Babel
yarn add @rollup/plugin-babel @babel/core -D
// rollup.config.js
import typescript from '@rollup/plugin-typescript';
import { babel } from '@rollup/plugin-babel';
export default {
input: 'src/main.ts',
output:[
{
file: './dist/bundle.es.js',
format: 'es',
name: 'BundleEs'
},
{
file: './dist/bundle.umd.js',
format: 'umd',
name: 'BundleUMD'
}
],
plugins:[
typescript(),
babel({ babelHelpers: 'bundled' })
]
};
配置commonJS默认的导出声明
yarn add @rollup/plugin-commonjs -D
// rollup.config.js
import typescript from '@rollup/plugin-typescript';
import { babel } from '@rollup/plugin-babel';
import commonjs from '@rollup/plugin-commonjs';
export default {
input: 'src/main.ts',
output:[
{
file: './dist/bundle.es.js',
format: 'es',
name:"BundleEs"
},
{
file: './dist/bundle.umd.js',
format: 'umd',
name:"BundleUMD"
}
],
plugins:[
commonjs(),
typescript(),
babel({ babelHelpers: 'bundled' })
]
};
// 记得使用commonJS后、插件都要以import导入进来、不要使用require方式了
rollup打包流程
首先我们需要了解rollup使用了acorn 和 magic-string 两个库
acorn 是一个 JavaScript 语法解析器,它将 JavaScript 字符串解析成语法抽象树 AST
export default function add(a, b) { return a + b }
// 最后会被解析成下方的语法树
{
"type": "Program",
"start": 0,
"end": 50,
"body": [
{
"type": "ExportDefaultDeclaration",
"start": 0,
"end": 50,
"declaration": {
"type": "FunctionDeclaration",
"start": 15,
"end": 50,
"id": {
"type": "Identifier",
"start": 24,
"end": 27,
"name": "add"
},
"expression": false,
"generator": false,
"params": [
{
"type": "Identifier",
"start": 28,
"end": 29,
"name": "a"
},
{
"type": "Identifier",
"start": 31,
"end": 32,
"name": "b"
}
],
"body": {
"type": "BlockStatement",
"start": 34,
"end": 50,
"body": [
{
"type": "ReturnStatement",
"start": 36,
"end": 48,
"argument": {
"type": "BinaryExpression",
"start": 43,
"end": 48,
"left": {
"type": "Identifier",
"start": 43,
"end": 44,
"name": "a"
},
"operator": "+",
"right": {
"type": "Identifier",
"start": 47,
"end": 48,
"name": "b"
}
}
}
]
}
}
}
],
"sourceType": "module"
}
magic-string是 rollup 作者写的一个关于字符串操作的库、有兴趣的可以去github看看
rollup打包整体步骤分为:
- 配置收集合并
- 文件分析、分析导入和导出的模块、将引入的模块和导出的模块填入对应的对象
- 利用acorn进行源码编译,生成ast树、分析每个 AST 节点间的作用域,找出每个 AST 节点定义的变量
- 依赖解析分析标识符,并找出它们的依赖项。什么是标识符?如变量名,函数名,属性名,都归为标识符。当解析到一个标识符时,rollup 会遍历它当前的作用域,看看有没这个标识符。如果没有找到,就往它的父级作用域找。如果一直找到模块顶级作用域都没找到,就说明这个函数、方法依赖于其它模块,需要从其他模块引入。如果一个函数、方法需要被引入,就将它添加到 Module 的 _dependsOn 对象里
- 根据依赖项,读取对应的文件。
- 生成代码,这里会对一些额外的代码进行移除、比如引入的模块却没有进行使用