亲,Rollup,了解一下?

103 阅读4分钟

一、准备工作

  1. git init,方便配置改崩了,可以回退

  2. pnpm init

  3. pnpm add rollup -D

  4. /package.json
    
    添加type属性,使node可以执行import语句的js文件
    {
      ...
      "type": "module",
      ...
    }
    
  5. 创建/rollup.config.js配置文件

    1. export default {
          input: 'src/index.js',
          output: {
              file: 'dist/bundle.js',
              format: 'esm'
          }
      }
      
    2. 添加测试js文件

      1. // src/index.js
        import { add, deepCopy } from './util.js'
        
        let arr = [1, 2, 3, 4].map(res => res + 1)
        console.log('数组arr', arr);
        
        let n = add(1, 2)
        console.log('数字和:', n);
        
        let obj1 = {
          a: 1,
          c: {
            d: 2
          }
        }
        
        let obj2 = deepCopy(obj1)
        obj1.c.d = 3
        console.log('obj2.c.d', obj2.c.d);
        
      2. // 帮我写一个方法,传2个数字,返回一个数字,这个数字是传入的2个数字的和
        export let add = (a, b)=> {
          return a + b;
        }
        
        // 帮我写一个深拷贝
        export let deepCopy = (obj) => {
          let result = {};
          for (let key in obj) {
            if (typeof obj[key] === 'object') {
              result[key] = deepCopy(obj[key]);
            } else {
              result[key] = obj[key];
            }
          }
          return result;
        }
        
    3. 打包方式

      1. 控制台:npx rollup src/index.js --file dist/index.js
      2. 控制台:npx rollup -c [文件路径rollup.config.js]
        1. rollup.config.js路径可以不写,默认找的就是这个配置文件
      3. package.json配置命令"build": "rollup -c"
    4. 加提示,方便开发在/rollup.config.js中顶部添加代码

      1. 方式1:加注释

        1. /**
           *  @type {import('rollup').RollupOptions}
           * */
          
      2. 方式2:引入配置函数

        1. import { defineConfig } from 'rollup'
          
          export default defineConfig({
            input: 'src/index.js',
            output: {
              file: 'dist/bundle.js',
              format: 'esm'
            },
          })
          
    5. 理解【二、摇树优化】,测试tree shaking,就是不引入deepCopy,打包还会打进去吗?

二、摇树优化:tree shaking

使用esm模式,编译阶段,可静态分析代码使用情况,进行删减打包

1. tree shaking优先条件

tree shaking是建立在esm模式上的,因为ESM导入导出是静态的,CommonJS导入导出是动态,所以CommonJS无法精准tree shaking(webpack一定程度上,优化了这个情况,所以说无法精准,而不是不能。)

2. tree shaking原理

  1. 静态分析:识别模块(就是js文件)的导入和导出关系
  2. 标记未使用代码:标记导入和导出,没对应上的代码
  3. 剔除未使用代码:根据标记结果,最终打包时剔除未使用的代码

三、导出

多种类型,output使用数组

/**
 *  @type {import('rollup').RollupOptions}
 * */

export default {
  input: 'src/index.js',
  output: [
    {
      file: 'dist/esm/bundlejs',
      format: 'esm'
    },
    {
      file: 'dist/cjs/bundle.js',
      format: 'cjs'
    }
  ],

}

入口多文件

export default {
  // 多入口
  input: ['src/index.js', 'src/main.js'],
  // 导出多种类型
  output: [
    {
      dir: 'dist/esm',
      format: 'esm'
    }
  ],
}
// 添加 src/main.js
// src/main.js
import { add } from './util.js'


let n = add(1, 2)
console.log('数字和:', n);

不同的入口,对应各自的导出

/**
 *  @type {import('rollup').RollupOptions}
 * */
let buildIndexOption = {
  input: ['src/index.js'],
  output: [
    {
      dir: 'dist/esm',
      format: 'esm'
    }
  ],
}

let buildMainOption = {
  input: ['src/main.js'],
  output: [
    {
      dir: 'dist/cjs',
      format: 'cjs'
    }
  ],
}

export default [buildIndexOption, buildMainOption]

是否把第三方库打包到代码里

// 测试插件,lodash-es
pnpm add lodash-es
  • 不需要:/rollup.config.js配置external: ['lodash-es']
    • 我用的是4.x,rollup 4.9.4,好像默认支持了,我电脑没报错
  • 需要:
    • 安装:
      • pnpm add @rollup/plugin-node-resolve -D
    • 使用
      • import {nodeResolve} from '@rollup/plugin-node-resolve'
      • /rollup.config.js配置pluginsplugins: [nodeResolve('lodash-es')]
      • 这样,lodash代码与自己的代码,就都在一起了

打包时,想把第三方插件提取(切割)出来,配置output

output: [
  {
    dir: 'dist/esm',
    format: 'esm',
    // 1. 对象形式
    // manualChunks: {
    //   'lodash-es': ['lodash-es']
    // }
    
    // 2. 方法形式
     manualChunks(filePath) {
      if (filePath.includes('lodash-es')) {
        return 'lodash-es'
      }
    }
  }
],

使用三方插件时,需支持CommonJS时,使用插件

  1. 安装:

    1. pnpm add @rollup/plugin-commonjs -D
    2. pnpm add lodash 这个符合commonjs
  2. 使用

    1. /**
       *  @type {import('rollup').RollupOptions}
       * */
      import { nodeResolve } from '@rollup/plugin-node-resolve'
      import commonjs from '@rollup/plugin-commonjs'
      
      let buildIndexOption = {
        input: ['src/index.js'],
        output: [
          {
            dir: 'dist/esm',
            format: 'esm',
            manualChunks: {
              'lodash': ['lodash']
            }
          }
        ],
        plugins: [
          nodeResolve(),
          commonjs()
        ]
      }
      export default [buildIndexOption]
      
    2. 此代码,只为了测试打包,试验而已。用node 运行index.js时,报错

      1. // src/index.js
        import { add } from "./util.js";
        import { random } from "lodash";
        
        let n = add(1, 2);
        console.log("数字和:", n);
        
        console.log(random(1, 20));
        console.log(random(1, 20));
        console.log(random(1, 20));
        
      2. /package.json
        
        {
        	...
        	"type": "module", // 好像是因为这个
        	...
        }
        
        

四、使用浏览器未兼容语法,需要用插件转义下

pnpm add @rollup/plugin-babel @babel/core @babel/preset-env @babel/plugin-transform-runtime @babel/runtime @babel/runtime-corejs3 -D

/babel.config.js

export default {
  presets: [
    [
      "@babel/preset-env",
      {
        useBuiltIns: "usage",
        corejs: 3,
        // 百分比调高点,这样就能看到let转var了
        targets: "> 40.25%, not dead",
      },
    ],
  ],
  plugins: [
    [
      "@babel/plugin-transform-runtime",
      {
        corejs: 3,
      },
    ],
  ],
};

/**
 *  @type {import('rollup').RollupOptions}
 * */
import { nodeResolve } from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
import babel from "@rollup/plugin-babel";

let buildIndexOption = {
  input: ["src/index.js"],
  output: [
    {
      dir: "dist/esm",
      format: "esm",
    },
  ],
  plugins: [
    nodeResolve(),
    commonjs(), // 这个必须有,不可以注释
    babel({
      babelHelpers: "runtime",
      exclude: "node_modules/**",
      extensions: [".js"],
      include: ["src/**"],
    }),
  ],
};
export default [buildIndexOption];

五、要支持ts:需安装插件

pnpm add typescript tslib @rollup/plugin-typescript -D

初始化ts配置文件 npx tsc --init

// 创建ts配置文件
{
  "compilerOptions": {
    "target": "ESNext",
    "lib": [
      "ESNext",
      "DOM",
      "DOM.Iterable"
    ],
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "resolveJsonModule": true,
    "noEmit": true,
    "isolatedModules": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipDefaultLibCheck": true,
    "skipLibCheck": true
  },
  "include": [
    "src/**/*",
    "rollup.config.ts"
  ]
}
// 创建 rollup.config.ts
/**
 *  @type {import('rollup').RollupOptions}
 * */

import typescript from '@rollup/plugin-typescript'

let buildIndexOption = {
  input: ['src/index.ts'],
  output: [
    {
      dir: 'dist/esm',
      format: 'esm',
    }
  ],
  plugins: [
    typescript()
  ]
}
export default [buildIndexOption]
// 创建:src/index.ts
type myObj = {
  a: number,
  b: string
}

let obj:myObj = {
  a: 1,
  b: 'hello'
}

console.log('',obj);

// 添加打包命令

"scripts": {
	   // ...
    "build-ts": "rollup -c rollup.config.ts --configPlugin typescript"
  },

六、仓库地址:

gitee.com/wmh1106/rol…