Jacky's blog Jacky's blog
首页
  • 编码专题
  • 深入浅出 Vite
  • 深入浅出 babel
  • 快速上手API
  • 深入浅出 react
  • Node

    • code-notebook
  • 状态管理

    • redux
  • 前端工程化

    • Wepack
  • React源码

    • React源码
  • 组件库封装

    • 组件库
  • 开发工具

    • Vscode 插件
  • 项目展示
  • 案例中心 (opens new window)
  • First Project
  • 基础算法题
  • 链表题
  • 动态规划
  • 双指针
  • 递归
  • 数据结构
  • 前端学习计划 (opens new window)
  • 技术随笔
  • 转载文章
  • 包管理工具
  • 前端学习周报
  • VSCode插件
  • Promise 专题
  • 函数技巧
  • React 专题
  • 配置文件

    • TSCONFIG-配置 (opens new window)
    • NGINX-配置 (opens new window)
    • 正则规则查询手册 (opens new window)
    • Lint 配置 (opens new window)
  • 教程

    • GIT-教程
    • NPM SCRIPTS-工作流 (opens new window)
    • DOCKER-教程 (opens new window)
    • LERNA-教程 (opens new window)
    • GIT-常用操作整理 (opens new window)
  • VSCode

    • LAUNCH.JSON (opens new window)
  • 指令

    • NPM 指令 (opens new window)
    • NVM 指令 (opens new window)
    • Nginx 指令 (opens new window)
    • YARN 指令 (opens new window)
    • PNPM 指令 (opens new window)
  • 库

    • FS-EXTRA 库 (opens new window)
    • NODE 库-PATH (opens new window)
  • 永远的神

    • 魔法师卡颂-自顶向下学 React 源码 (opens new window)
    • 全栈潇晨 (opens new window)
    • 博客-程序员山月-Daily (opens new window)
    • 淘系前端:冴羽 (opens new window)
  • 系列文章

    • 《图解HTTP》 (opens new window)
    • 《ES6标准入门》 (opens new window)
    • 《现代JavaScript教程》 (opens new window)
    • 《深入浅出Webpack》 (opens new window)
    • VSCode 插件系列:小茗同学 (opens new window)
    • JEST 教程 (opens new window)
    • 前端精读周刊:各种精读系列 (opens new window)
    • 一文吃透系列 (opens new window)
    • 图解 REACT 原理 (opens new window)
  • 实用网站

    • MDN (opens new window)
    • CAN I USE (opens new window)
    • TYPESCRIPT-ESLint-RULES (opens new window)
    • ESLint-RULES (opens new window)
    • FRONT-END TREND (opens new window)
    • NPM TREND (opens new window)
    • 在线分析 Node 依赖 (opens new window)
    • FIND NPM (opens new window)
    • CODE PEN (opens new window)
    • 印记中文 (opens new window)
    • TOOL.LU (opens new window)
    • 阮一峰-网道 (opens new window)
    • DIGITAL OCEAN (opens new window)
    • DEVDOCS.IO (opens new window)
    • JOI (opens new window)
  • 算法

    • 小浩算法 (opens new window)
    • LABULADONG 的算法小抄 (opens new window)
    • 力扣 SOLUTION (opens new window)
    • HACKER RANK (opens new window)
    • 代码随想录 (opens new window)
  • 博客系列

    • 美团大佬 (opens new window)
    • 蜡笔小伟 (opens new window)
    • 优秀博客1 (opens new window)
    • 优秀博客2-umi (opens new window)
    • 优质博客 (opens new window)
  • CSS

    • CSS-EASING 库 (opens new window)
    • ROUGH.JS (opens new window)
    • CSS 网站收集
    • UNOCSS (opens new window)
  • 前端

    • PROMISE (opens new window)
    • UNDERSCORE.JS (opens new window)
    • study with BGM (opens new window)
    • nginx【B站视频】 (opens new window)
    • 机器学习
    • Js基础
  • 掘金已购课程

    • 前端自动化测试精讲 (opens new window)
    • 深入浅出 Vite (opens new window)
    • 现代 Web 布局 (opens new window)
    • 前端算法与数据结构 (opens new window)
    • 基于 Vite 的 SSG 框架开发实战 (opens new window)
    • SSR 实战:官网开发指南 (opens new window)
    • WebGL 入门与实践 (opens new window)
    • 玩转 CSS 的艺术之美 (opens new window)
    • 前端调试通关秘籍 (opens new window)
    • React 进阶实践指南 (opens new window)
    • TypeScript 全面进阶指南 (opens new window)
    • 前端缓存技术与方案解析 (opens new window)
    • npm scripts 前端工作流 (opens new window)
    • Webpack5 核心原理与应用实践 (opens new window)
  • 购物车

    • 张鑫旭-技术写作指南 (opens new window)
    • 深入剖析 Node.js 底层原理 (opens new window)
    • 前端开发者的现代 C++ 课 (opens new window)
    • 从前端到全栈 (opens new window)
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Jacky Wang

行到水穷处,坐看云起时
首页
  • 编码专题
  • 深入浅出 Vite
  • 深入浅出 babel
  • 快速上手API
  • 深入浅出 react
  • Node

    • code-notebook
  • 状态管理

    • redux
  • 前端工程化

    • Wepack
  • React源码

    • React源码
  • 组件库封装

    • 组件库
  • 开发工具

    • Vscode 插件
  • 项目展示
  • 案例中心 (opens new window)
  • First Project
  • 基础算法题
  • 链表题
  • 动态规划
  • 双指针
  • 递归
  • 数据结构
  • 前端学习计划 (opens new window)
  • 技术随笔
  • 转载文章
  • 包管理工具
  • 前端学习周报
  • VSCode插件
  • Promise 专题
  • 函数技巧
  • React 专题
  • 配置文件

    • TSCONFIG-配置 (opens new window)
    • NGINX-配置 (opens new window)
    • 正则规则查询手册 (opens new window)
    • Lint 配置 (opens new window)
  • 教程

    • GIT-教程
    • NPM SCRIPTS-工作流 (opens new window)
    • DOCKER-教程 (opens new window)
    • LERNA-教程 (opens new window)
    • GIT-常用操作整理 (opens new window)
  • VSCode

    • LAUNCH.JSON (opens new window)
  • 指令

    • NPM 指令 (opens new window)
    • NVM 指令 (opens new window)
    • Nginx 指令 (opens new window)
    • YARN 指令 (opens new window)
    • PNPM 指令 (opens new window)
  • 库

    • FS-EXTRA 库 (opens new window)
    • NODE 库-PATH (opens new window)
  • 永远的神

    • 魔法师卡颂-自顶向下学 React 源码 (opens new window)
    • 全栈潇晨 (opens new window)
    • 博客-程序员山月-Daily (opens new window)
    • 淘系前端:冴羽 (opens new window)
  • 系列文章

    • 《图解HTTP》 (opens new window)
    • 《ES6标准入门》 (opens new window)
    • 《现代JavaScript教程》 (opens new window)
    • 《深入浅出Webpack》 (opens new window)
    • VSCode 插件系列:小茗同学 (opens new window)
    • JEST 教程 (opens new window)
    • 前端精读周刊:各种精读系列 (opens new window)
    • 一文吃透系列 (opens new window)
    • 图解 REACT 原理 (opens new window)
  • 实用网站

    • MDN (opens new window)
    • CAN I USE (opens new window)
    • TYPESCRIPT-ESLint-RULES (opens new window)
    • ESLint-RULES (opens new window)
    • FRONT-END TREND (opens new window)
    • NPM TREND (opens new window)
    • 在线分析 Node 依赖 (opens new window)
    • FIND NPM (opens new window)
    • CODE PEN (opens new window)
    • 印记中文 (opens new window)
    • TOOL.LU (opens new window)
    • 阮一峰-网道 (opens new window)
    • DIGITAL OCEAN (opens new window)
    • DEVDOCS.IO (opens new window)
    • JOI (opens new window)
  • 算法

    • 小浩算法 (opens new window)
    • LABULADONG 的算法小抄 (opens new window)
    • 力扣 SOLUTION (opens new window)
    • HACKER RANK (opens new window)
    • 代码随想录 (opens new window)
  • 博客系列

    • 美团大佬 (opens new window)
    • 蜡笔小伟 (opens new window)
    • 优秀博客1 (opens new window)
    • 优秀博客2-umi (opens new window)
    • 优质博客 (opens new window)
  • CSS

    • CSS-EASING 库 (opens new window)
    • ROUGH.JS (opens new window)
    • CSS 网站收集
    • UNOCSS (opens new window)
  • 前端

    • PROMISE (opens new window)
    • UNDERSCORE.JS (opens new window)
    • study with BGM (opens new window)
    • nginx【B站视频】 (opens new window)
    • 机器学习
    • Js基础
  • 掘金已购课程

    • 前端自动化测试精讲 (opens new window)
    • 深入浅出 Vite (opens new window)
    • 现代 Web 布局 (opens new window)
    • 前端算法与数据结构 (opens new window)
    • 基于 Vite 的 SSG 框架开发实战 (opens new window)
    • SSR 实战:官网开发指南 (opens new window)
    • WebGL 入门与实践 (opens new window)
    • 玩转 CSS 的艺术之美 (opens new window)
    • 前端调试通关秘籍 (opens new window)
    • React 进阶实践指南 (opens new window)
    • TypeScript 全面进阶指南 (opens new window)
    • 前端缓存技术与方案解析 (opens new window)
    • npm scripts 前端工作流 (opens new window)
    • Webpack5 核心原理与应用实践 (opens new window)
  • 购物车

    • 张鑫旭-技术写作指南 (opens new window)
    • 深入剖析 Node.js 底层原理 (opens new window)
    • 前端开发者的现代 C++ 课 (opens new window)
    • 从前端到全栈 (opens new window)
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 编码专题

  • 深入浅出 Vite

    • 00-目录大纲
    • 07-Vite预构建上手
    • 09-Esbuild 插件开发实战
    • 10-Rollup 打包基本概念及使用
      • 0.前言
        • 问题1:为什么深入学习 Vite 需要掌握 rollup?
      • 1.概念理解
        • 问题2:什么是Tree Shaking, 为什么rollup可以具有天然的Tree Shaking功能?
        • 问题3:可以哪儿两种方式来使用 rollup?
      • 2. Rollup 基本配置
        • 问题4:rollup 如何进行多入口+多产物配置?
        • 问题5:rollup 中如何打包 umd 格式?
        • 问题6:rollup 除了 input 、output 外还能配置哪儿些?
        • 问题7:rollup 如何开启 watch 模式?
      • 3.Rollup 插件相关
        • 问题8:rollup 如何接入 plugin 插件?
        • 问题9:如何打包 loadsh 这类 cjs 格式包,能说说在开发实践中都使用过哪些常用的Rollup库吗?
    • 11-Rollup打包机制及插件开发
    • 12-Vite插件开发实战
    • 13-Vite热更新
    • 16-Vite搭建 SSR 框架
  • 快速上手 API

  • 深入浅出Babel

  • 深入浅出 React

  • 百问掘金
  • 深入浅出 Vite
wangjiasheng
2023-04-03
目录

10-Rollup 打包基本概念及使用

# 0.前言

本节课程代码的仓库 (opens new window):13-vite-rollup

本篇博客为《深入浅出 Vite 》掘金手册第十章总结。

# 问题1:为什么深入学习 Vite 需要掌握 rollup?

在开发阶段,我们主要使用 ESbuild 对第三方依赖进行预构建,但是 ESbuild 存在种种缺陷,如不支持降级到 es5 代码,不支持新式语法,不具备 ts 类型系统机制,完全不提供处理 chunk 产物的接口等。因此在生产阶段,推荐使用功能更丰富且稳定的 rollup 作为打包工具。当然 esbuild 同样也可以以 minify 器的身份 "混入其中"。

除此以外,整个 Vite 架构体系中就是基于 rollup 搭建的,因此对 rollup 的插件机制进行完全性的兼容,编写 vite 插件某种程度上等同于编写 rollup 插件,两者主要区别在于 vite 实现了些特有 hooks 钩子函数,扩展了 rollup 在开发阶段的能力。

# 1.概念理解

# 问题2:什么是Tree Shaking, 为什么rollup可以具有天然的Tree Shaking功能?

参考仓库 (opens new window)案例,执行脚本指令: npm run build:nobundle 。

  • tree-shaking 的定义

    计算机编译原理中DCE(Dead Code Elimination,即消除无用代码) 技术。

  • 具体表现:

    在 bundle 模式(当 rollup 配置文件设定 单入口 )下,基于 esm 模块机制的代码并不会被全量打入一个 chunk 中。

  • tree-shaking 的实现机制:

    esm 模块在当初设计时就支持静态分析,即依赖关系在运行前编译时就能确定下来。通过 AST 语法树对没有用到的节点打标记,统一进行删除操作。

通过下述案例直观感受下 tree shaking (树摇) 功能。

准备文件:

// src/index.js
import { add } from "./util";
console.log(add(1, 2));

// src/util.js
export const add = (a, b) => a + b;
export const multi = (a, b) => a * b;
1
2
3
4
5
6
7

采用如下 rollup.config.js 配置:

// rollup.config.js
// 以下注释是为了能使用 VSCode 的类型提示
/**
 * @type { import('rollup').RollupOptions }
 */
const buildOptions = {
  input: ["src/index.js"],
  output: {
    // 产物输出目录
    dir: "dist/es",
    // 产物格式
    format: "esm",
  },
};

export default buildOptions;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

执行指令:rollup -c 后,示例案例中执行:npm run build:nobundle

到产物输出目录查看产物内容:

// dist/es/index.js
// 代码已经打包到一起
const add = (a, b) => a + b;

console.log(add(1, 2));
1
2
3
4
5

# 问题3:可以哪儿两种方式来使用 rollup?

有两种方式:命令行(推荐)和 代码调用。

  • 命令行:rollup -c 其中 -c 不可省略,默认读取 rollup.config.js 配置文件,当然也可如下指定配置文件。

     "scripts":
        "build:nobundle": "npx rollup -c ./rollups/basic.rollup.js",
        "build:umd": "npx rollup -c ./rollups/umd.rollup.js",
        "build:lodash": "npx rollup -c ./rollups/lodash.rollup.js"
     }
    
    1
    2
    3
    4
    5
  • 代码编程

      "scripts": {
        "command:build": "npx tsx ./scripts/command/build.ts",
        "command:watch": "npx tsx ./scripts/command/watch.ts",
      }
    
    1
    2
    3
    4

    上面是使用 tsx 进行 node 脚本的执行,本质和 ts-node 没太大区别,基于 esbuild 实现。

    具体完整脚本就不展开了,可以到代码仓库中看,大致就两步。

    import rollup from "rollup";
    let bundle;
    try {
      /*1. rollup.rollup 获取 bundle 对象*/
      bundle = await rollup.rollup({})//  rollup.config.js 中处 output 属性外的参数,如 input 或者 plugins:[]
      /* 2. 使用 bundle.generate 或者 write (2选1) 产出 */
      const {result} = bundle.generate({})
      await bundle.write({}) // 直接配置 output 配置文件
    }catch(err){}
    
    1
    2
    3
    4
    5
    6
    7
    8
    9

    详细的使用方式见后续问题。

# 2. Rollup 基本配置

# 问题4:rollup 如何进行多入口+多产物配置?

本案例中的实践代码为:

"scripts": {
  "build:nobundle": "npx rollup -c ./rollups/basic.rollup.js",
  "command:build": "npx tsx ./scripts/command/build.ts",
},
1
2
3
4

多入口的配置非常简单,当 rollup.config.js 中 input 为一数组即可,当数组大小超出1时,则为多入口。

多出口的概念同上,但区别在于命令行和代码调用的方式差别还是非常大的。

对于 命令行 形式 多产物 的配置还是很容易的,直接指定 output 为数组格式即可。

  • 举例:打包为 cjs 和 esm 格式。
const typescript = require("rollup-plugin-typescript2");
const path = require("path");
const srcPath = path.join(__dirname, "..", "src");

/**
 * @type { import('rollup').RollupOptions }
 */
const buildOptions = {
  input: [
    path.join(srcPath, "basic/index.ts"),
    path.join(srcPath, "basic/util.ts"),
  ],
  output: [
    {
      /* 产物输出文件 */
      dir: "dist/basic/es",
      /* 产物格式 */
      format: "esm",
    },
    {
      /* 产物输出文件 */
      dir: "dist/basic/cjs",
      /* 产物格式 */
      format: "cjs",
    },
  ],
  plugins: [typescript()],
};

module.exports = buildOptions;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

但对于 rollup.rollup({}) 这种代码调用格式时,bundle.write({}) 无法传入数组,必须指定为对象格式,因此多产物的输出只能靠手动循环实现,代码示例如下:

import * as rollup from "rollup";
import typescript from "rollup-plugin-typescript2";
import * as path from "path";
import { SRC_PATH, DIST_PATH } from "const";

// 常用 inputOptions 配置
const inputOptions = {
  input: [
    path.join(SRC_PATH, "./basic/index.ts"),
    path.join(SRC_PATH, "./basic/util.ts"),
  ],
  external: [],
  plugins: [typescript()],
};

const outputOptionsList = [
  // 常用 outputOptions 配置
  {
    dir: path.join(DIST_PATH, "basic-node", "es"),
    entryFileNames: `[name].[hash].js`,
    chunkFileNames: "chunk-[hash].js",
    assetFileNames: "assets/[name]-[hash][extname]",
    format: "esm",
    sourcemap: true,
  },
  {
    dir: path.join(DIST_PATH, "basic-node", "cjs"),
    entryFileNames: `[name].[hash].js`,
    chunkFileNames: "chunk-[hash].js",
    assetFileNames: "assets/[name]-[hash][extname]",
    format: "cjs",
    sourcemap: true,
  },
];

async function build() {
  let bundle;
  let buildFailed = false;
  debugger;
  try {
    /* 1. 调用 rollup.rollup 生成 bundle 对象 */
    bundle = await rollup.rollup(inputOptions);
    for (const outputOptions of outputOptionsList) {
      /* 2. bundle 暴露两个函数:generate 和 write */
      /* 此两个函数使用上没有差别,只是前者不会输出到磁盘,后者会输出到磁盘 */
      const { output } = await bundle.generate(outputOptions);
      await bundle.write(outputOptions);
    }
  } catch (error) {
    buildFailed = true;
    console.error(error);
  }
  if (bundle) {
    /* 调用 close 方法结束打包工作 */
    await bundle.close();
  }
  process.exit(buildFailed ? 1 : 0);
}

build();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

# 问题5:rollup 中如何打包 umd 格式?

umd 格式的打包,需要单独区分,因为此类格式要求单入口+单出口。与前者不同支出在于,需要将 output 中的 dir 修改为 file 属性。

PS:这种配置方案,查了半天都没有配置出来,最终还是问 chatgpt 才解决的。

本节问题可使用仓库代码中 npm run build:umd 指令测试。

rollup.config.js 配置文件如下:

const typescript = require("rollup-plugin-typescript2");
const path = require("path");
const srcPath = path.join(__dirname, "..", "src");

/**
 * @type { import('rollup').RollupOptions }
 */
const buildOptions = {
  input: [path.join(srcPath, "/basic/index.ts")],
  output: [
    {
      /* 产物输出文件 */
      file: "dist/basic/umd/index.js",
      /* 产物格式 */
      format: "umd",
    },
  ],
  plugins: [typescript()],
};

module.exports = buildOptions;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 问题6:rollup 除了 input 、output 外还能配置哪儿些?

对于打包工具所具备能力都很类似,如 format、sourcemap 等,当用到时再去 rollup 官网搜索就好了。

详细配置清单见下:

import typescript from "rollup-plugin-typescript2";
import * as path from "path";
import { fileURLToPath } from "url";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

/**
 * @type { import('rollup').RollupOptions }
 */
const buildOptions = {
  input: ["src/index.ts", "src/util.ts"],
  output: {
    // 产物输出目录
    dir: path.resolve(__dirname, "../", "dist/output"),
    // 以下三个配置项都可以使用这些占位符:
    // 1. [name]: 去除文件后缀后的文件名
    // 2. [hash]: 根据文件名和文件内容生成的 hash 值
    // 3. [format]: 产物模块格式,如 es、cjs
    // 4. [extname]: 产物后缀名(带`.`)
    // 入口模块的输出文件名
    entryFileNames: `[name].js`,
    // 非入口模块(如动态 import)的输出文件名
    chunkFileNames: "chunk-[hash].js",
    // 静态资源文件输出文件名
    assetFileNames: "assets/[name]-[hash][extname]",
    // 产物输出格式,包括`amd`、`cjs`、`es`、`iife`、`umd`、`system`
    format: "cjs",
    // 是否生成 sourcemap 文件
    sourcemap: true,
    // 如果是打包出 iife/umd 格式,需要对外暴露出一个全局变量,通过 name 配置变量名
    name: "MyBundle",
    // 全局变量声明
    globals: {
      // 项目中可以直接用`$`代替`jquery`
      jquery: "$",
    },
  },
  plugins: [typescript()],
};

export default buildOptions;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

# 问题7:rollup 如何开启 watch 模式?

响应的代码见仓库 (opens new window)

import * as rollup from "rollup";
import * as path from "path";
import typescript from "rollup-plugin-typescript2";
import { SRC_PATH } from "const";

const watcher = rollup.watch({
  // 和 rollup 配置文件中的属性基本一致,只不过多了`watch`配置
  input: [
    path.join(SRC_PATH, "/basic/index.ts"),
    path.join(SRC_PATH, "basic/util.ts"),
  ],
  output: [
    {
      dir: "dist/watch/es",
      format: "esm",
    },
    {
      dir: "dist/watch/cjs",
      format: "cjs",
    },
  ],
  watch: {
    exclude: ["node_modules/**"],
    include: ["src/**"],
  },
  plugins: [typescript()],
});

// 监听 watch 各种事件
watcher.on("restart", () => {
  console.log("重新构建...");
});

watcher.on("change", (id) => {
  console.log("发生变动的模块id: ", id);
});

watcher.on("event", (e) => {
  if (e.code === "BUNDLE_END") {
    console.log("打包信息:", e);
  }
  if (e.code === "ERROR") {
    console.log("ERROR:", e.error);
  }
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

# 3.Rollup 插件相关

# 问题8:rollup 如何接入 plugin 插件?

配置 plugin 插件时首先要区分插件的运行时机是在 开发阶段 还是生产阶段?

如果分不清的话,推荐直接将所有插件配置到最外层的 plugins ,当明显为生产插件时,可配置到 output 中。

// rollup.config.js
import { terser } from 'rollup-plugin-terser'
import resolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";

export default {
  output: {
    // 加入 terser 插件,用来压缩代码
    plugins: [terser()]
  },
  plugins: [resolve(), commonjs()]
}
1
2
3
4
5
6
7
8
9
10
11
12

# 问题9:如何打包 loadsh 这类 cjs 格式包,能说说在开发实践中都使用过哪些常用的Rollup库吗?

对于 rollup 来说,虽然提供支持多种输出格式的产物,但是对于输入代码仅仅支持 esm 格式。

ps:这里的意思是指,当入口文件为 cjs 时,rollup 不会对这个文件有任何处理,也不会处理第三方依赖。

这就要求我们统一使用 ESM 规范,并且要求导入的第三方依赖均为 esm 模块。

对于第一个要求还可以控制,但是第二条就很难满足,因为有的第三方依赖仅提供 cjs,这类典型的包有 react 以及 lodash。

为了解决这个问题,需要引入两个核心的插件包:

pnpm i @rollup/plugin-node-resolve @rollup/plugin-commonjs 
1

其中:

  • @rollup/plugin-node-resolve是为了允许我们加载第三方依赖。
  • @rollup/plugin-commonjs 的作用是将 CommonJS 格式的代码转换为 ESM 格式。

rollup配置如下:

const resolve = require("@rollup/plugin-node-resolve");
const commonjs = require("@rollup/plugin-commonjs");
const rollupOptions = {
  plugins: [resolve(),commonjs()]
}
1
2
3
4
5

详细的执行结果:可执行 npm run build:lodash 查看构建结果。

除了上述的插件外,还推荐使用如下插件,后续章节会对其中几个插件进行源码分析:

  • @rollup/plugin-node-resolve:允许解析第三方依赖。
  • @rollup/plugin-commonjs :将 cjs 第三方依赖转化为 esm 依赖。
  • @rollup/plugin-json:支持 .json 的加载,甚至可配置rollup 的 tree-shaking 机制进行按需打包。
  • @rollup/plugin-babel:接入 Babel
  • rollup-plugin-terser:接入 terser 进行代码压缩,不过在 vite 中默认采用 esbuild 完成这部分工作。
  • @rollup/plugin-typescript:官方的 ts 插件,但更推荐使用 "rollup-plugin-typescript2" 插件,官方插件的增强版。
  • @rolllup/plugin-alias:支持别名配置。
  • @rollup/plugin-replace:全局字符串替换,内部核心使用 margic string 工具包实现。
  • rollup-plugin-visualizer:构建产物分析,体积可视化分析图。

完整的官方插件清单:https://github.com/rollup/plugins/tree/master/packages

每个 packages 源码都在 100~200 行,非常值得借鉴学习。

编辑 (opens new window)
上次更新: 2023/04/04, 11:04:00
09-Esbuild 插件开发实战
11-Rollup打包机制及插件开发

← 09-Esbuild 插件开发实战 11-Rollup打包机制及插件开发→

最近更新
01
如何理解浏览器的 user agent 用户代理的含义?
11-05
02
浏览器事件循环机制
10-31
03
浏览器页面渲染机制【2023】
10-15
更多文章>
Theme by Vdoing | Copyright © 2020-2023
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式