rollup - 快速入门

文章介绍了在项目开发中如何选择使用Webpack或Rollup。Webpack适合大型项目,处理各种资源,但体积较大;而Rollup则轻量级,适用于开发库,特别是其Tree-Shaking功能能优化代码体积。文章详细讲解了Rollup的配置、格式转换、插件使用以及与浏览器和Node.js的兼容性,还提供了配置文件示例和集成其他工具的方法。
摘要由CSDN通过智能技术生成

介绍

如果需要直接开发项目,webpack 是合适的,它将图片、js、css等视作资源,但本身比较笨重,会稍微增大代码的体积;

如果要开发js库,就可以使用配置简单且轻量的 rollup 了。

特性

  • 能够支持模块化开发,使开发者能够使用 ES6 模块的方式编写代码;

  • 支持 ES6 模块,能够从库中单独引入需要的函数;

  • 拥有 Tree-Shaking 的能力,能够对代码进行静态分析,并剔除未使用到的代码;

    import { ajax } from './utils';
    
  • 对比 commonJS:如果使用 commonJS,需要导入整个三方库,然后简单的通过代码压缩工具查找未使用变量,效率没这么高;

    const utils = require( './utils' );
    
  • 输入:可以通过使用插件来支持 commonJS 模块;

  • 输出:可以将代码编译为 umd/commonJS 格式实现对 Node.js 等环境的支持。

安装

npm install --global rollup

🐢 实际做项目时,也可以进行本地安装。

配置方式-命令行

下面的例子将 main.js 作为应用的入口,将所有的引入都编译到单文件 bundle.js 中。

用于浏览器:

# 编译为供 <script> 调用的立即执行函数
rollup main.js --file bundle.js --format iife

用于 Node.js:

# 编译为 CommonJS 模块
rollup main.js --file bundle.js --format cjs

同时用于浏览器和 Node.js:

# 需要为 UMD 格式的包指定一个名称,否则会报错
rollup main.js --file bundle.js --format umd --name "myBundle"

配置方式-配置文件

配置文件是一个导出配置对象的ES模块,通常位于项目根目录,并命名为 rollup.config.js

export default {
  input: 'src/main.js',
  output: {
    file: 'bundle.js',
    format: 'cjs'
  }
};

使用 .cjs 的拓展名,配置文件可以使用 commonJS 模块,就能支持 requiremodule.exports 语法;

构建不同的输出

  • 根据不同的入口构建不同的 bundle,可配置为对象数组;
  • 为相同的入口构建多个 bundle,可以将输出项写成数组。
export default [{
  input: 'main-a.js',
  output: {
    file: 'dist/bundle-a.js',
    format: 'cjs'
  }
}, {
  input: 'main-b.js',
  output: [
    {
      file: 'dist/bundle-b1.js',
      format: 'cjs'
    },
    {
      file: 'dist/bundle-b2.js',
      format: 'es'
    }
  ]
}];

异步构建

Rollup 可以处理结果为对象/数组形式的 promise。

例子一

import fetch from 'node-fetch';
export default fetch('/some-remote-service-or-file-which-returns-actual-config');

例子二

export default Promise.all([
  fetch('get-config-1'),
  fetch('get-config-2')
])

自定义文件路径

在命令行加上 --config 或者 -c 的选项,就可以使用指定的配置文件。

rollup --config rollup.config.dev.js

忽略文件名,会按照特定顺序加载配置文件

rollup.config.mjs -> rollup.config.cjs -> rollup.config.js

rollup --config

使用插件

使用插件能够拓展 Rollup 本身的行为,如使用 NPM 安装导入模块,使用 Babel 编译代码,运行 JSON 文件。

示例一

使 Rollup 支持从 JSON 文件中导入数据。

安装

npm install --save-dev @rollup/plugin-json

使用

src/main.js

import { version } from '../package.json';

export default function () {
  console.log('version ' + version);
}

配置

rollup.config.js

import json from '@rollup/plugin-json';

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

🐢 不使用这个插件,也能从 JSON 文件中导入数据,参考官方示例

示例二

对输出的代码进行压缩,来生成压缩后的 bundles。

npm install --save-dev rollup-plugin-terser

配置

rollup.config.js

import {terser} from 'rollup-plugin-terser';

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

🌟 注意插件的使用时机,压缩适合在 Rollup 分析代码后使用,故配置在 output.plugins 中。

集成三方工具

使用npm包

在代码中使用任意包

npm install the-answer

src/main.js

import answer from 'the-answer';

export default function () {
  console.log('the answer is ' + answer);
}

支持 Rollup 找到外部模块

npm install --save-dev @rollup/plugin-node-resolve

rollup.config.js

import resolve from '@rollup/plugin-node-resolve';

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

🐙 如果没有使用插件 @rollup/plugin-node-resolve,那么输出的 bundle.js 将不会注入使用到的包,并在控制台提示:

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

处理commonJS

使用插件 @rollup/plugin-commonjs 能够支持依赖中的 commonJS,注意应该在其他插件前调用。

前置依赖

如果构建一个具有前置依赖的库(类似 React / Loadsh),按照下面的方式设置,rollup 将会打包所有的引入项:

import _ from 'lodash';
  • 可以通过 external 指定外部引入,它们不会被打包到 bundle 当中去;
  • 构建的包如果是提供给浏览器使用,指定 external 会导致依赖找不到。
// rollup.config.js
import resolve from '@rollup/plugin-node-resolve';

export default {
  input: 'src/main.js',
  output: {
    file: 'bundle.js',
    format: 'cjs'
  },
  plugins: [resolve({
    // 将自定义选项传递给解析插件,【推测为外部引入的查找路径】
    customResolveOptions: {
      moduleDirectory: 'node_modules'
    }
  })],
  // 指出哪些模块需要被视为外部引入
  external: ['lodash']
};

Babel

能够使 rollup 支持最新的 JavaScript 特性。

安装插件并配置

npm i -D @rollup/plugin-babel @rollup/plugin-node-resolve
npm i -D @babel/core @babel/preset-env

rollup.config.js

import resolve from '@rollup/plugin-node-resolve';
import babel from '@rollup/plugin-babel';

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

配置 babel

src/.babelrc.json

{
  "presets": [
    ["@babel/env", {"modules": false}]
  ]
}

👻 设置 modules: false 来避免 babel 将模块转化为 commonJS;

🐢 babel 将在正在编译的文件的当期目录中查找 .babelrc,如果不存在,就顺着目录往上找。

添加es6语法以方便测试

src/main.js

import answer from 'the-answer';

export default () => {
  console.log(`the answer is ${answer}`);
}

Gulp

Gulp 可以理解 Rollup 返回的 Promise。

const gulp = require('gulp');
const rollup = require('rollup');
const rollupTypescript = require('@rollup/plugin-typescript');

gulp.task('build', async function () {
  const bundle = await rollup.rollup({
    input: './src/main.ts',
    plugins: [
      rollupTypescript()
    ]
  });

  await bundle.write({
    file: './dist/library.js',
    format: 'umd',
    name: 'library',
    sourcemap: true
  });
});

🐳 这里使用了 Rollup 的 JavaScript API,在内存中构建包,然后输出到硬盘中。

示例一

rollup.config.js

import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import pkg from './package.json';

export default [
  // 对浏览器友好的umd构建
  {
    input: 'src/main.js',
    output: {
      name: 'howLongUntilLunch',
      file: pkg.browser, // 输出文件名
      format: 'umd'
    },
    plugins: [
      resolve(), // 支持 Rollup 找到外部模块
      commonjs() // 支持依赖中的 commonJS
    ]
  },

  // commonJS(用于Node)
  // ES module(用于bundlers)
  {
    input: 'src/main.js',
    // 指出模块为外部引入,将不会被打包到 bundle 中
    external: ['ms'],
    output: [
      { file: pkg.main, format: 'cjs' },
      { file: pkg.module, format: 'es' }
    ]
  }
];

🐳 示例项目安装了外部依赖 ms,并引入到 src/main.js 文件中。

package.json

"scripts": {
  "build": "rollup -c",
  "dev": "rollup -c -w"
}

-c 指定配置文件,默认是 rollup.config.js;

-w 监听,在输入(包括依赖)改变时重新构建(bundle)。

示例二

rollup.config.js

import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import { terser } from 'rollup-plugin-terser';

// 通过命令行的(-w/-watch)判断是否生产环境
const production = !process.env.ROLLUP_WATCH;

export default {
  input: 'src/main.js',
  output: {
    file: 'public/bundle.js',
    format: 'iife', // 供 <script> 调用的立即执行函数
    sourcemap: true // 生成sourcemap,使错误和日志能够指向原模块
  },
  plugins: [
    resolve(),
    commonjs(),
    production && terser() // 生产环境时,压缩
  ]
};

🐳 示例项目安装了外部依赖 date-fns/format,并作为 src/main.js 的深层依赖。

package.json

"scripts": {
  "build": "rollup -c",
  "watch": "rollup -c -w",
  "dev": "npm-run-all --parallel start watch", // 并行执行
  "start": "serve public"
}

生成bundle规律总结

  • 编写源码(作为配置入口)使用 es 语法,编写配置使用 commonJs 语法,可以生成 bundle

使用 es 的语法编写源码和配置文件

编译方式导入语法导出语法
cjs无,内容被注入commonJS
es无,内容被注入es

使用 commonJS 的语法编写源码和配置文件

编译方式导入语法导出语法
cjscommonJScommonJS
escommonJScommonJS

使用 commonJS 的语法编写源码和配置文件 + @rollup/plugin-commonjs 处理

编译方式导入语法导出语法
cjs无,内容被注入commonJS
es无,内容被注入es

附录

类型说明
文档命令行标志
文档配置选项
文档插件列表
文档插件开发
未总结特性JavaScript API、代码分割

参考资料:

补充的话

如果这篇笔记能够帮助到你,请帮忙在 github 上点亮 star,这对我非常重要,感谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值