RollupJavaScript模块打包器入门教程

文章目录

嘿,前端开发小伙伴们!今天咱们来聊一聊Rollup这个有点低调但超级实用的JavaScript模块打包工具。说实话,在webpack一统江湖的年代,Rollup这样的工具往往被很多人忽略了。但它绝对是个宝藏工具,尤其是对于库的开发者来说简直是福音!

什么是Rollup?为啥要学它?

Rollup是一个JavaScript模块打包器,专注于ES模块(ESM)的处理。它于2015年由Rich Harris(没错,就是Svelte的创造者!)开发,主打简洁高效。

你可能会问:"都有webpack了,为啥还要学Rollup?"(我刚开始也是这么想的...)

几个超级吸引人的原因:

  1. 代码精简 - Rollup生成的包体积小,这是因为它有个杀手锏功能------Tree Shaking!它能自动移除未使用的代码。
  2. 适合库开发 - 如果你在开发一个JavaScript库,Rollup绝对是首选(Vue、React、Three.js等都在用它)。
  3. 配置简单 - 相比webpack复杂的配置,Rollup配置文件简单易懂,新手友好!
  4. 输出格式灵活 - 支持多种模块格式,包括ESM、CommonJS、UMD等。

总之,如果你厌倦了webpack的复杂配置,或者正准备开发一个库,是时候了解一下Rollup了!

开始使用Rollup

安装

首先,我们需要安装Rollup。可以全局安装或者作为项目依赖安装:

bash 复制代码
# 全局安装
npm install --global rollup

# 项目依赖安装(推荐)
npm install --save-dev rollup

我个人更推荐第二种方式,这样不同项目可以使用不同版本的Rollup,避免兼容性问题。

基本使用

让我们从一个简单的例子开始!

首先,创建一个项目结构:

复制代码
my-rollup-project/
├── src/
│   ├── main.js
│   └── modules/
│       └── calculator.js
├── package.json
└── rollup.config.js

calculator.js中,我们定义一些简单的计算函数:

javascript 复制代码
// src/modules/calculator.js
export function add(a, b) {
  return a + b;
}

export function subtract(a, b) {
  return a - b;
}

export function multiply(a, b) {
  return a * b;
}

export function divide(a, b) {
  if (b === 0) {
    throw new Error("除数不能为零!");
  }
  return a / b;
}

然后在main.js中引入并使用这些函数:

javascript 复制代码
// src/main.js
import { add, multiply } from './modules/calculator.js';

console.log(add(1, 2)); // 输出: 3
console.log(multiply(3, 4)); // 输出: 12

export default function calculator() {
  return {
    add,
    multiply
  };
}

注意看,我们只导入了addmultiply函数,没有用到subtractdivide。这就是Tree Shaking大显身手的地方!

接下来,创建一个Rollup配置文件rollup.config.js

javascript 复制代码
// rollup.config.js
export default {
  input: 'src/main.js',
  output: {
    file: 'dist/bundle.js',
    format: 'cjs' // CommonJS格式
  }
};

这个配置文件超级简单:

  • input: 入口文件
  • output: 输出配置
    • file: 输出文件路径
    • format: 输出格式(这里用的是CommonJS)

最后,在package.json中添加构建脚本:

json 复制代码
{
  "name": "my-rollup-project",
  "version": "1.0.0",
  "scripts": {
    "build": "rollup -c"
  },
  "devDependencies": {
    "rollup": "^3.20.0"
  }
}

运行构建命令:

bash 复制代码
npm run build

完成后,查看生成的dist/bundle.js文件,你会发现它只包含了我们实际使用的addmultiply函数,subtractdivide函数被自动移除了!这就是Tree Shaking的魔力!

输出格式

Rollup支持多种输出格式,适应不同的使用场景:

  • esm/es: ES模块格式,现代浏览器原生支持
  • cjs: CommonJS格式,适用于Node.js环境
  • umd: 通用模块定义,同时支持浏览器和Node.js
  • iife : 立即执行函数,适合作为<script>直接在浏览器中使用

修改配置文件以输出多种格式:

javascript 复制代码
export default {
  input: 'src/main.js',
  output: [
    {
      file: 'dist/bundle.cjs.js',
      format: 'cjs'
    },
    {
      file: 'dist/bundle.esm.js',
      format: 'es'
    },
    {
      file: 'dist/bundle.umd.js',
      format: 'umd',
      name: 'MyCalculator' // UMD格式需要指定一个全局变量名
    }
  ]
};

这样一次构建就能生成三种不同格式的文件,超级方便!

使用插件

Rollup的核心功能相当精简,但通过插件系统可以扩展其功能。这些插件能帮助处理各种资源、转换代码、优化输出等。

以下是一些常用的Rollup插件:

1. @rollup/plugin-node-resolve

这个插件允许Rollup从node_modules中引入第三方模块。

bash 复制代码
npm install --save-dev @rollup/plugin-node-resolve

修改配置文件:

javascript 复制代码
import resolve from '@rollup/plugin-node-resolve';

export default {
  input: 'src/main.js',
  output: {
    file: 'dist/bundle.js',
    format: 'cjs'
  },
  plugins: [
    resolve()
  ]
};

2. @rollup/plugin-commonjs

这个插件将CommonJS模块转换为ES模块,这样Rollup就能处理它们了。

bash 复制代码
npm install --save-dev @rollup/plugin-commonjs

修改配置文件:

javascript 复制代码
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';

export default {
  // ...
  plugins: [
    resolve(),
    commonjs()
  ]
};

3. @rollup/plugin-babel

如果你需要使用Babel来转换代码(比如使用最新的JavaScript特性),可以使用这个插件:

bash 复制代码
npm install --save-dev @rollup/plugin-babel @babel/core @babel/preset-env

创建Babel配置文件.babelrc

json 复制代码
{
  "presets": [["@babel/preset-env", { "modules": false }]]
}

修改Rollup配置:

javascript 复制代码
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import babel from '@rollup/plugin-babel';

export default {
  // ...
  plugins: [
    resolve(),
    commonjs(),
    babel({
      babelHelpers: 'bundled',
      exclude: 'node_modules/**'
    })
  ]
};

4. @rollup/plugin-terser

对打包后的代码进行压缩:

bash 复制代码
npm install --save-dev @rollup/plugin-terser

修改配置:

javascript 复制代码
import terser from '@rollup/plugin-terser';

export default {
  // ...
  plugins: [
    // ...其他插件
    terser()
  ]
};

实际项目配置示例

下面是一个较为完整的Rollup配置,包含了开发库时常用的设置:

javascript 复制代码
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import babel from '@rollup/plugin-babel';
import terser from '@rollup/plugin-terser';
import pkg from './package.json' assert { type: 'json' };

export default [
  // 浏览器友好的UMD构建
  {
    input: 'src/main.js',
    output: {
      name: 'myLibrary',
      file: pkg.browser,
      format: 'umd'
    },
    plugins: [
      resolve(),
      commonjs(),
      babel({
        babelHelpers: 'bundled',
        exclude: ['node_modules/**']
      }),
      terser()
    ]
  },
  // CommonJS和ES模块构建
  {
    input: 'src/main.js',
    output: [
      { file: pkg.main, format: 'cjs' },
      { file: pkg.module, format: 'es' }
    ],
    plugins: [
      babel({
        babelHelpers: 'bundled',
        exclude: ['node_modules/**']
      })
    ]
  }
];

对应的package.json配置:

json 复制代码
{
  "name": "my-awesome-library",
  "version": "1.0.0",
  "main": "dist/my-library.cjs.js",
  "module": "dist/my-library.esm.js",
  "browser": "dist/my-library.umd.js",
  "scripts": {
    "build": "rollup -c",
    "dev": "rollup -c -w"
  }
}

Rollup vs Webpack:何时选择哪个?

很多人会问:"Rollup和Webpack到底哪个更好?"

老实说,这不是非此即彼的选择。它们各有优势,适合不同场景:

选择Rollup的情况:

  1. 开发JavaScript库或组件 - Rollup的Tree Shaking和干净的输出使其成为库开发的理想选择。
  2. 代码体积敏感 - 如果你需要最小化的输出体积。
  3. 配置简单 - 如果你厌倦了复杂的webpack配置。
  4. 项目结构简单 - 主要处理JavaScript模块,没有复杂的资源需求。

选择Webpack的情况:

  1. 开发应用程序 - 特别是有大量静态资源的复杂应用。
  2. 需要代码分割和动态导入 - Webpack在这方面更成熟。
  3. 需要处理多种资源 - 图片、CSS、字体等各种资源。
  4. HMR需求 - 热模块替换在开发体验上很重要。

个人经验:我会在开发库时使用Rollup,开发应用时使用Webpack或Vite(基于Rollup但针对应用开发优化)。

进阶技巧

1. 外部依赖

开发库时,你通常不想将所有依赖都打包进去。可以使用external选项标记外部依赖:

javascript 复制代码
export default {
  // ...
  external: ['lodash', 'react'],
  // ...
};

这样,这些依赖将不会被打包,而是作为引用保留在代码中。

2. Sourcemaps

为了方便调试,可以生成sourcemaps:

javascript 复制代码
export default {
  // ...
  output: {
    // ...
    sourcemap: true
  }
};

3. 动态导入

Rollup支持代码分割和动态导入:

javascript 复制代码
// 动态导入示例
import('./modules/heavy-module.js').then(module => {
  // 使用模块
});

配置中需要指定代码分割的输出目录:

javascript 复制代码
export default {
  // ...
  output: {
    dir: 'dist',
    format: 'es',
    // file属性在使用代码分割时不能使用
  }
};

常见问题与解决方案

1. "Unresolved dependencies" 错误

如果你看到类似错误:

复制代码
(!) Unresolved dependencies
https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency

这通常意味着Rollup无法解析某些导入。解决方案是使用@rollup/plugin-node-resolve插件,或者将该依赖标记为外部依赖。

2. CommonJS模块问题

如果你使用的库是CommonJS格式,Rollup可能无法正确处理。使用@rollup/plugin-commonjs插件解决。

3. 全局变量访问

在UMD构建中,如果你需要访问全局变量(如windowdocument),可以使用globals选项:

javascript 复制代码
export default {
  // ...
  output: {
    // ...
    format: 'umd',
    globals: {
      jquery: '$' // 将jquery映射到全局变量$
    }
  },
  external: ['jquery'] // 标记jquery为外部依赖
};

小结

Rollup虽然没有Webpack那么出名,但它在JavaScript库开发领域绝对是一把利器!它的配置简单、输出干净、Tree Shaking出色,非常值得学习和使用。

如果你正在考虑开发一个JavaScript库,或者只是想尝试一个更轻量级的打包工具,绝对值得给Rollup一个机会!

最后,如果你已经习惯了Webpack,也不必急着完全迁移。两者可以共存,在适合的场景使用适合的工具。

希望这篇教程对你有所帮助!祝你编码愉快!

相关推荐
牛马的人生4 小时前
GitLab入门教程:打开DevOps全流程的大门
运维·其他·gitlab·devops
71-39 小时前
C语言——循环的嵌套小练习
c语言·笔记·学习·其他
沙砾59bf7de1ca29acb220 小时前
厦门旅游记录
其他
agilearchitect1 天前
MATLAB线性代数函数完全指南
线性代数·其他·决策树·matlab
kernelknight11 天前
MATLAB For循环详解:从入门到精通的完整指南
开发语言·其他·matlab
codecrafter1231 天前
MATLAB中的while循环:从入门到精通的完整指南
java·数据库·其他·matlab
syntaxseeker1 天前
Apache Beam入门教程:统一批流处理模型
其他·apache
zenithdev12 天前
开源库入门教程 Cesium:3D地球和地图库
其他·3d·arcgis
71-32 天前
C语言速成秘籍——跳转语句(goto)
c语言·笔记·学习·其他