Rollup - 基础介绍

Rollup 是一个 JavaScript 的打包工具,目前我们常使用的 Webpack 也常拿来跟他做比较,基本上两者皆能达到我们想要的效果,但其各自有较擅长的领域,Webpack 适合应用程式的打包,而 Rollup 则比较适合 library 的打包,另外他使用上也比 Webpack 简单一些,接着就看一下怎么使用吧!

建立专案

首先我们开一个新专案,使用指令建立 package.json

$ npm init -y

然后我们简单的写一些东西

// index.jsconst myFunction = async () => {  console.log('myFunction')}myFunction()export default myFunction

运行后可以看到结果,如下:

$ node index.jsmyFunction

ES6 Module

Rollup 是一个针对 ES6 Module 所设计的打包工具,所以我们必须使用 ES6 Module 来做撰写,而使用方法有以下两种,选一种即可开始使用啰

ES Module 档案的副档名改为 .mjspackage.json 内加入 { "type": "module" }

开始打包

首先安装今天的主角 Rollup

$ npm install --global rollup

接着可以执行指令进行打包

$ rollup index.js --file dist/bundle.js --format umd --name "myBundle"
-f, --format:档案输出格式(amd, cjs, es, iife, umd, system)-n, --name:档案全域名称-m, --sourcemap:产生 sourcemap-w, --watch:监听档案变化即时编译-c, --config:使用 rollup.config.js 的设定

rollup.config.js

当需要的设定变多之后,我们可以创建 rollup.config.js 来详细写入相关的设定,以下有几个常用设定,详细的可以看官方文件

// rollup.config.jsconst config = {  input: 'index.js', // 进入点  plugins: [], // 插件  external: [], // 外部插件  onwarn(warning, warn) { // 自定义警告    // do something...  },  treeshake: true, // 删除没用到的程式码  output: { // 输出档案    name: 'bundle', // 全域名称    file: 'dist/bundle.js', // 输出档案    format: umd, // 输出格式    sourcemap: true // 是否产生 sourcemap  }}export default config

最后我们可以在 package.json 加入指令,方便之后编译

// package.json{  "scripts": {    "build": "rollup -c"  }}

打包成果如下:

(function (global, factory) {  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :  typeof define === 'function' && define.amd ? define(factory) :  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.bundle = factory());}(this, (function () { 'use strict';  const myFunction = async () => {    console.log('myFunction');  };  myFunction();  return myFunction;})));

安装插件

通常打包时我们通常还会用到许多其他的功能,而插件就是来补齐这些功能,首先我们先修改一下程式码,安装一个 Demo 用的插件,并小小修改一下程式码

$ npm install the-answer

接着程式码如下:

// index.jsimport answer from 'the-answer'const action = () => {  return new Promise((res, rej) => {    setTimeout(() => {      res(answer)    }, 3000)  })}const myFunction = async () => {  const answer = await action()  console.log(answer)}myFunction()export default myFunction

打包后会发现有一些错误,这些错误会靠着插件来解决,所以我们先看看有哪些常见的插件可以使用

@rollup/plugin-node-resolve

resolve 协助我们从 node_modules 中找到我们安装的插件

$ npm install @rollup/plugin-node-resolve --save-dev
// rollup.config.jsimport { nodeResolve } from '@rollup/plugin-node-resolve'const config = {  input: 'index.js',  output: {    name: 'bundle',    file: 'dist/bundle.js',    format: 'umd'  },  plugins: [    nodeResolve()    // 如果要在浏览器使用需要加入设定如下    // nodeResolve({ browser: true, preferBuiltins: true })  ]}export default config

@rollup/plugin-commonjs

commonjs 将 CommonJS 转换为 ES6 Module

$ npm install @rollup/plugin-commonjs --save-dev
// rollup.config.jsimport commonjs from '@rollup/plugin-commonjs'const config = {  input: 'index.js',  output: {    name: 'bundle',    file: 'dist/bundle.js',    format: 'umd'  },  plugins: [    commonjs()    // Node.js 有些套件需要加入以下设定才会正常    // commonjs({ include: ['node_modules/**'] })  ]}export default config

@rollup/plugin-json

json 将 .json 档案转换为 ES6 Module

$ npm install @rollup/plugin-json --save-dev
// rollup.config.jsimport json from '@rollup/plugin-json'const config = {  input: 'index.js',  output: {    name: 'bundle',    file: 'dist/bundle.js',    format: 'umd'  },  plugins: [    json()  ]}export default config

rollup-plugin-node-builtins & rollup-plugin-node-globals

builtins 与 globals 将一些 Node.js 内的全域变数变成 ES6 Module

$ npm install rollup-plugin-node-builtins --save-dev$ npm install rollup-plugin-node-globals --save-dev
// rollup.config.jsimport builtins from 'rollup-plugin-node-builtins'import globals from 'rollup-plugin-node-globals'const config = {  input: 'index.js',  output: {    name: 'bundle',    file: 'dist/bundle.js',    format: 'umd'  },  plugins: [    globals(),    builtins()  ]}export default config

@rollup/plugin-babel

babel 将 ES6 的语法编译为浏览器看得懂的版本,另外还要下载它的核心

$ npm install @rollup/plugin-babel --save-dev$ npm install @babel/core --save-dev
// rollup.config.jsimport { babel } from '@rollup/plugin-babel'const config = {  input: 'index.js',  output: {    name: 'bundle',    file: 'dist/bundle.js',    format: 'umd'  },  plugins: [    babel({ babelHelpers: 'bundled' })  ]}export default config

接着要编写 babel 的设定档,我们在根目录建立一个 babel.config.js,并安装 babel 的预设设定

$ npm install @babel/preset-env --save-dev
// babel.config.jsconst config = {  presets: [    [      '@babel/preset-env'    ]  ]}export default config

最后在进入点加入 runtime.js 使其正常编译

// index.jsimport 'regenerator-runtime/runtime.js'

rollup-plugin-terser

terser 用来将程式码压缩

$ npm install rollup-plugin-terser --save-dev
// rollup.config.jsimport { terser } from 'rollup-plugin-terser'const config = {  input: 'index.js',  output: {    name: 'bundle',    file: 'dist/bundle.js',    format: 'umd'  },  plugins: [    terser()  ]}export default config

以上差不多就是常用的插件,那么我们来把刚刚编译的问题解决吧!

浏览器版本设定

// rollup.config.jsimport { nodeResolve } from '@rollup/plugin-node-resolve'import commonjs from '@rollup/plugin-commonjs'import { babel } from '@rollup/plugin-babel'import { terser } from 'rollup-plugin-terser'const config = {  input: 'index.js',  output: {    name: 'bundle',    file: 'dist/bundle.js',    format: 'umd'  },  plugins: [    nodeResolve({ browser: true, preferBuiltins: true }),    commonjs(),    babel({ babelHelpers: 'bundled' }),    terser()  ]}export default config

Node.js 版本设定

// rollup.config.jsimport { nodeResolve } from '@rollup/plugin-node-resolve'import builtins from 'rollup-plugin-node-builtins'import globals from 'rollup-plugin-node-globals'import commonjs from '@rollup/plugin-commonjs'import json from '@rollup/plugin-json'import { babel } from '@rollup/plugin-babel'import { terser } from 'rollup-plugin-terser'const config = {  input: 'index.js',  output: {    name: 'bundle',    file: 'dist/bundle.js',    format: 'umd'  },  plugins: [    nodeResolve(),    globals(),    builtins(),    commonjs({ include: ['node_modules/**'] }),    json(),    babel({ babelHelpers: 'bundled' }),    terser()  ]}export default config

到这边就可以正常打包啰!

外部插件

顺便补充一下,如果想要把插件当成外部插件引用可以照以下设定,以浏览器举例

// rollup.config.jsimport { nodeResolve } from '@rollup/plugin-node-resolve'import commonjs from '@rollup/plugin-commonjs'import { babel } from '@rollup/plugin-babel'const config = {  input: 'index.js',  output: {    name: 'bundle',    file: 'dist/bundle.js',    format: 'umd',    globals: {      'the-answer': 'the-answer' // 全域变数    }  },  plugins: [    nodeResolve({ browser: true, preferBuiltins: true }),    commonjs(),    babel({ babelHelpers: 'bundled' })  ],  external: ['the-answer'] // 告知为外部插件}export default config

最后另外提醒一下以下几点

Node.js 与浏览器环境有差异,要分开调整插件的载入顺序会有差异,要特别注意不使用 ES6 Module 撰写的话打包路径有可能会出现错误

结语

我只是想打包个 JavaScript 阿,搞这一大堆的搞了好几天,真的很苦啊呜呜,希望不要有人再掉进这个大坑


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章