rollup简介

rollup是一个JavaScript模块打包器、它很轻量、没有webpack的重、也不需要像webpack一样对不同复杂的场景做打包覆盖、一般用于工程化库的打包、很多大型框架Vue、React等也是使用rollup进行打包!

image.png

start

  1. yarn init // 初始化package.json
  2. yarn add rollup -D // 安装rollup
  3. // package.json配置script
  4. "scripts": {
  5. "build":"rollup --config rollup.config.js"
  6. }

rollup.config.js

在根节点里面添加rollup.config.js、添加配置信息

  1. export default {
  2. input: 'src/main.js',
  3. output:[
  4. {
  5. file: './dist/bundle.es.js',
  6. format: 'es',
  7. name: 'BundleEs'
  8. },
  9. {
  10. file: './dist/bundle.umd.js',
  11. format: 'umd',
  12. name: 'BundleUMD'
  13. }
  14. ]
  15. };

创建打包文件内容

——src
——main.ts
——demo
index.ts

  1. // main.js
  2. import { name } from "./demo/index"
  3. console.log(name)
  4. // demo/index.js
  5. export const name = 'demo'

执行build

yarn 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

  1. yarn add @rollup/plugin-typescript -D // 添加解析typescript插件
  2. // rollup.config.js
  3. export default {
  4. input: 'src/main.ts',
  5. output:[
  6. {
  7. file: './dist/bundle.es.js',
  8. format: 'es',
  9. name: 'BundleEs'
  10. },
  11. {
  12. file: './dist/bundle.umd.js',
  13. format: 'umd',
  14. name: 'BundleUMD'
  15. }
  16. ],
  17. plugins:[
  18. typescript()
  19. ]
  20. };
  21. // main.ts
  22. import { add } from "./demo"
  23. const sum = add(1,2);
  24. console.log(sum)
  25. // demo/index.ts
  26. export function add(n1:number, n2:number):number{
  27. return n1 + n2
  28. }
  29. // 执行yarn build进行打包

配置Babel

  1. yarn add @rollup/plugin-babel @babel/core -D
  2. // rollup.config.js
  3. import typescript from '@rollup/plugin-typescript';
  4. import { babel } from '@rollup/plugin-babel';
  5. export default {
  6. input: 'src/main.ts',
  7. output:[
  8. {
  9. file: './dist/bundle.es.js',
  10. format: 'es',
  11. name: 'BundleEs'
  12. },
  13. {
  14. file: './dist/bundle.umd.js',
  15. format: 'umd',
  16. name: 'BundleUMD'
  17. }
  18. ],
  19. plugins:[
  20. typescript(),
  21. babel({ babelHelpers: 'bundled' })
  22. ]
  23. };

配置commonJS默认的导出声明

image.png

  1. yarn add @rollup/plugin-commonjs -D
  2. // rollup.config.js
  3. import typescript from '@rollup/plugin-typescript';
  4. import { babel } from '@rollup/plugin-babel';
  5. import commonjs from '@rollup/plugin-commonjs';
  6. export default {
  7. input: 'src/main.ts',
  8. output:[
  9. {
  10. file: './dist/bundle.es.js',
  11. format: 'es',
  12. name:"BundleEs"
  13. },
  14. {
  15. file: './dist/bundle.umd.js',
  16. format: 'umd',
  17. name:"BundleUMD"
  18. }
  19. ],
  20. plugins:[
  21. commonjs(),
  22. typescript(),
  23. babel({ babelHelpers: 'bundled' })
  24. ]
  25. };
  26. // 记得使用commonJS后、插件都要以import导入进来、不要使用require方式了

rollup打包流程

首先我们需要了解rollup使用了acorn 和 magic-string 两个库

acorn 是一个 JavaScript 语法解析器,它将 JavaScript 字符串解析成语法抽象树 AST

  1. export default function add(a, b) { return a + b }
  2. // 最后会被解析成下方的语法树
  3. {
  4. "type": "Program",
  5. "start": 0,
  6. "end": 50,
  7. "body": [
  8. {
  9. "type": "ExportDefaultDeclaration",
  10. "start": 0,
  11. "end": 50,
  12. "declaration": {
  13. "type": "FunctionDeclaration",
  14. "start": 15,
  15. "end": 50,
  16. "id": {
  17. "type": "Identifier",
  18. "start": 24,
  19. "end": 27,
  20. "name": "add"
  21. },
  22. "expression": false,
  23. "generator": false,
  24. "params": [
  25. {
  26. "type": "Identifier",
  27. "start": 28,
  28. "end": 29,
  29. "name": "a"
  30. },
  31. {
  32. "type": "Identifier",
  33. "start": 31,
  34. "end": 32,
  35. "name": "b"
  36. }
  37. ],
  38. "body": {
  39. "type": "BlockStatement",
  40. "start": 34,
  41. "end": 50,
  42. "body": [
  43. {
  44. "type": "ReturnStatement",
  45. "start": 36,
  46. "end": 48,
  47. "argument": {
  48. "type": "BinaryExpression",
  49. "start": 43,
  50. "end": 48,
  51. "left": {
  52. "type": "Identifier",
  53. "start": 43,
  54. "end": 44,
  55. "name": "a"
  56. },
  57. "operator": "+",
  58. "right": {
  59. "type": "Identifier",
  60. "start": 47,
  61. "end": 48,
  62. "name": "b"
  63. }
  64. }
  65. }
  66. ]
  67. }
  68. }
  69. }
  70. ],
  71. "sourceType": "module"
  72. }

magic-string是 rollup 作者写的一个关于字符串操作的库、有兴趣的可以去github看看

rollup打包整体步骤分为:

  • 配置收集合并
  • 文件分析、分析导入和导出的模块、将引入的模块和导出的模块填入对应的对象
  • 利用acorn进行源码编译,生成ast树、分析每个 AST 节点间的作用域,找出每个 AST 节点定义的变量
  • 依赖解析分析标识符,并找出它们的依赖项。什么是标识符?如变量名,函数名,属性名,都归为标识符。当解析到一个标识符时,rollup 会遍历它当前的作用域,看看有没这个标识符。如果没有找到,就往它的父级作用域找。如果一直找到模块顶级作用域都没找到,就说明这个函数、方法依赖于其它模块,需要从其他模块引入。如果一个函数、方法需要被引入,就将它添加到 Module 的 _dependsOn 对象里
  • 根据依赖项,读取对应的文件。
  • 生成代码,这里会对一些额外的代码进行移除、比如引入的模块却没有进行使用