官网 https://cn.rollupjs.org/introduction/
ES 模块语法:https://cn.rollupjs.org/es-module-syntax/#importing

1. 简介

将项目分解为较小的独立部分通常可以使软件开发更加容易,因为这通常可以消除意外的交互,并大大减少你需要解决的问题的复杂性,在 ES6 版本的 JavaScript 中引入了一种新语法,用于导入导出函数和数据,以便它们可以在单独的脚本之间共享。

Rollup 是一个用于 JavaScript 的模块打包工具,它将小的代码片段编译成更大、更复杂的代码,例如库或应用程序。它使用 JavaScript 的 ES6 版本中包含的新标准化代码模块格式,而不是以前的 CommonJS 和 AMD 等特殊解决方案。

Rollup 是一款 ES Modules 打包器。它也可以将项目中散落的细小模块打包为整块代码,从而使得这些划分的模块可以更好的运行在浏览器环境或者 Node.js 环境。

从作用上来看,Rollup 与 Webpack 非常类似。不过相比于 Webpack,Rollup 要小巧的多。因为 Webpack 在配合一些插件的使用下,几乎可以完成开发过程中前端工程化的绝大多数工作。而 Rollup 可以说仅仅是一个 ESM 打包器,没有其它。

除了可以使用 ES 模块之外,Rollup 还可以静态分析你导入的代码,并将排除任何实际上没有使用的内容。这使你可以在现有的工具和模块的基础上构建,而不需要添加额外的依赖项或使项目的大小变得臃肿。

2. 使用

  1. 创建一个项目

    yarn init
  2. 安装依赖

    yarn add rollup -D
  3. 编写文件

    ├── package.json
    ├── src
    │   ├── index.js
    │   ├── logger.js
    │   └── message.js
    └── yarn.lock
  4. 打包

    # Usage: rollup [options] <entry file>
    
    yarn rollup ./src/index.js --file dist/bundle.js 
  5. 查看输出文件
    从打包结果中看出:
  • 代码结果几乎没有发生变化
  • rollup 支持 tree shaking,打包的结果中只包含了我们实际使用到的代码。
    image.png

rollup 支持 配置文件

  1. 创建配置文件 rollup.config.js

    export default {
      input: "src/index.js",
      output: {
     file: "dist/bundle.js",
     format: "iife",
      },
    };
    
  2. 执行命令

    yarn rollup --config rollup.config.js

3. 插件

rollup 自身的能力是 ES 模块的合并打包,其他项目需求:如 加载其他类型资源模块、导入 commonjs 模块、编译 ECMAScript新特性 ,rollup 支持以插件的形式进行扩展。
插件是 rollup 唯一的扩展形式。

比如 :

加载json文件

  1. 安装插件

    yarn add rollup rollup-plugin-json -D
  2. 修改配置文件

    import json from "rollup-plugin-json";
    
    export default {
      input: "src/index.js",
      output: {
       file: "dist/bundle.js",
       format: "iife",
      },
      plugins: [json()],
    };
  3. 修改 src/index.js 文件,在文件中导入 package.json 文件

    // 导入模块成员
    import { log } from "../src/logger";
    import message from "../src/message";
    
    import { name, version } from "../package.json"; // 支持结构,没有使用的部分,会被tree shaking
    
    // 使用模块成员
    const msg = message.hi;
    
    log(msg);
    
    log(`${name}@${version}`);
    
  4. 执行打包

    yarn rollup --config rollup.config.js

image.png

加载 npm 模块

rollup 默认只能按照文件路径来加载模块,不能像webpack一样,通过 模块名 来引入第三方模块,为了实现这个特性,需要安装插件。

  1. 安装插件

    yarn add rollup-plugin-node-resolve -D
    yarn add lodash-es
  2. 修改配置文件

    import json from "rollup-plugin-json";
    import resolve from "rollup-plugin-node-resolve";
    
    export default {
      input: "src/index.js",
      output: {
     file: "dist/bundle.js",
     format: "iife",
      },
      plugins: [json(), resolve()],
    };
  3. 修改 src/index.js

    // 导入模块成员
    import { log } from "../src/logger";
    import message from "../src/message";
    import { camelCase } from "lodash-es";
    
    import { name, version } from "../package.json";
    
    // 使用模块成员
    const msg = message.hi;
    
    log(msg);
    
    log(`${name}@${version}`);
    
    log(camelCase("hello word"));
    

注意:rollup 默认只能处理 es 模块,所以使用的是 es 版本的lodash,要使用普通版本的lodash,需要额外处理。

加载 commonjs 模块

rollup 默认处理 esm 模块,如果在项目中导入 commonjs 模块,默认是不被支持的,但是目前有大量的npm包使用了 commonjs 来导出成员,所以为了兼容这些模块,官网提供了 rollup-plugin-commonjs 插件。

  1. 安装插件

    yarn add rollup-plugin-commonjs -D
  2. 修改 src/index.js

    // 导入模块成员
    import { log } from "../src/logger";
    import message from "../src/message";
    import cjs from "./cjs-module"; // 导入整个commonjs模块
    
    // 使用模块成员
    const msg = message.hi;
    
    log(msg);
    
    log(cjs);
    
  3. 打包
    image.png

4. 代码拆分

使用 ESM 中的动态导入方式,可以实现模块的按需加载,rollup 内部也会进行代码拆分。

import() 函数可以用在任何地方,不仅仅是模块,非模块的脚本也可以使用。它是运行时执行,也就是说,什么时候运行到这一句,就会加载指定的模块。另外,import()函数与所加载的模块没有静态连接关系,这点也是与import语句不相同。import()类似于 Node.js 的require()方法,区别主要是前者是异步加载,后者是同步加载。

  1. 修改 src/index.js 文件,使用动态导入

    import("./logger").then(({ log }) => {
      log("code split~");
    });
    
  2. 新增 rollup.config2.js

    import json from "rollup-plugin-json";
    import resolve from "rollup-plugin-node-resolve";
    import commonjs from "rollup-plugin-commonjs";
    
    export default {
      input: "src/index.js",
      output: {
       dir: "dist", // 使用 代码拆分 时,需要执行 dir,而不是 file
       format: "amd", // iife 格式 会将结果 打包到一个函数中,不能拆分。因此需要修改 format 格式为 amd,amd可以在浏览器环境使用
      },
      plugins: [json(), resolve(), commonjs()],
    };
    
  3. 打包

    yarn rollup --config rollup.config2.js

    image.png

5. 多入口打包

rollup 同样支持多入口打包,并且对于多入口中公共的部分也会被抽取出来放在单个文件中作为单独的bundle。

配置多入口文件,只需要将 配置文件中的 input 属性修改为数组即可,或者对象配置形式。

需要注意的是,多入口打包时,内部会提取公共模块,也就涉及到代码拆分,因此无法使用 iife 的输出格式,只能输出为 amd 格式。

6. 浏览器

对于 amd 输出格式的 js 文件,不能直接引入到页面上,而需要通过实现了 amd 标准的库(比如 require.js)去加载。

  1. 新增 dist/index.html 文件

    <!DOCTYPE html>
    <html lang="en">
    <head>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>Document</title>
    </head>
    <body>
     <script src="https://unpkg.com/requirejs@2.3.6/require.js" data-main="index.js"></script>
    </body>
    </html>
  2. 启动本地静态服务器

    npm install http-server -g
    
    http-server dist # 启动
  3. 访问
    image.png

rollup 优缺点

优点:

  1. 输出结果更加扁平
  2. 自动移除未引用代码
  3. 打包结果依然完全可读

缺点:

  1. 加载非 ESM 到第三方模块比较复杂
  2. 模块最终都被打包到一个函数中,无法实现 HMR
  3. 浏览器环境中,代码拆分功能依赖 AMD 😭

如果我们正在开发应用程序,推荐使用 webpack,如果正在开发一个框架或者类库,可以使用 rollup


清风
1 声望0 粉丝

引用和评论

0 条评论