写点什么

【入门教程】Rollup 模块打包器整合

作者:小鑫同学
  • 2022-10-12
    北京
  • 本文字数:4722 字

    阅读完需:约 15 分钟

【入门教程】Rollup模块打包器整合

Rollup 是一个用于 JavaScript 的模块打包器,它将小段代码编译成更大更复杂的东西,例如库或应用程序。它对 JavaScript 的 ES6 修订版中包含的代码模块使用新的标准化格式,而不是以前的特殊解决方案,例如 CommonJS 和 AMD。 ES 模块让您可以自由无缝地组合您最喜欢的库中最有用的单个函数。这最终将在任何地方本地实现,但 Rollup 让您今天就可以做到。————《rollupjs.org》

特点:

  1. 选用 ES6 标准模块化格式;

  2. 支持静态分析导入代码进行 Tree-Shaking。

兼容:

  1. 支持导入 CommonJs 模块;

  2. 方便使用到 CommonJS 模块的工具,如:Node.js、webpack。

ES 模块语法:

思维导图地址:es模块语法


快速开始:

常见编译输出风格:

编译案例演示:

rollup 采用 ES6 标准模块化格式

定义一个待编译的 ES6 模块:

// 文件名:main.jsconst main = {    hello: () => {        console.log('Hello');    },    world: () => {        console.log('World');    },};export default main;
复制代码

编译为 IIFE 风格:

命令示例:
rollup <入口文件> --file <输出文件> --name <输出模块名称> --format <输出模块类型>
复制代码


注意:name 为推荐选项,未指明打包后的模块名称,虽然打包产物可以正常加载但无法触发执行。

编译命令:
rollup .\main.js --file bundle.iife.js --name myBundle --format iife
复制代码
输出产物:
// 文件名:bundle.iife.jsvar myBundle = (function () {    'use strict';
const main = { hello: () => { console.log('Hello'); return 'Hello'; }, world: () => { console.log('World'); return 'World'; }, };
return main;
})();
复制代码
在浏览器中使用:
<head>    <script src="../bundle.iife.js"></script></head>
<body> <script> myBundle.hello(); </script></body>
复制代码

编译为 CJS 风格:

命令示例:
rollup <入口文件> --file <输出文件> --exports <导出模式> --format <输出模块类型>
复制代码


注意:exports 为推荐选项,当使用默认导出时将抛出警告,建议使用命名导出。

编译命令:
rollup .\main.js --file bundle.cjs.js --exports auto --format cjs
复制代码
输出产物:
// 文件名:bundle.cjs.js'use strict';
const main = { hello: () => { console.log('Hello'); }, world: () => { console.log('World'); },};
module.exports = main;
复制代码
在 Node 环境中使用:
const main = require('../bundle.cjs.js');console.log(main.hello());
复制代码

编译为 UMD 风格:

命令示例:
rollup <入口文件> --file <输出文件> --name <输出模块名称> --format <输出模块类型>
复制代码


注意:name 为必填项,缺少后将抛出异常,打包产物在没有模块加载的环境将无法使用。

编译命令:
rollup main.js --file bundle.umd.js  --name myBundle --format umd
复制代码
输出产物:
// 文件名:bundle.umd.js(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.myBundle = factory());})(this, (function () { 'use strict';
const main = { hello: () => { console.log('Hello'); }, world: () => { console.log('World'); }, };
return main;
}));
复制代码
在浏览器中使用:
<head>    <script src="../bundle.umd.js"></script></head>
<body> <div id="content"></div> <script> const output = myBundle.hello(); document.getElementById("content").innerHTML = output </script></body>
复制代码
在 Node 环境中使用:
const main = require('../bundle.umd.js');console.log(main.hello());
复制代码

使用配置文件:

虽然在命令行可以完成大量的编译配置,但是同样提供了通过配置文件的方式来进行简化。


使用配置文件说明:


  1. 使用 ES6 模块导出风格编写配置文件:建议将扩展名修改成.mjs,执行期间会快速转换为 CommonJS 使用。

  2. 使用 CommonJs 模块导出风格编写配置文件:将扩展名修改成.cjs,NodeJs13+将阻止 Rollup 进行转义。

  3. 使用 ts 来编写配置文件:需要在执行命令时指定 configPlugin 为 typescript。

典型配置文件:

下面是一个典型的使用 ES6 模块默认导出风格的配置,将 main.js 文件编译为 CommonJs 模块风格,输出到 bundle.js 中。


// 文件名称:rollup.config.jsexport default {    input: 'main.js',    output: {        file: 'bundle.js',        format: 'cjs',        exports: 'auto'    },};
复制代码

多入口,多出口配置文件:

下面是一个支持同时编译多个入口文件,且支持同时编译成多种模块风格的参考配置:


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'      }    ]  }];
复制代码

异步创建配置文件:

支持我们通过异步的形式创建配置文件,例如我们的配置文件放置在云端,我们就可以通过 fetch 来获取不同的配置后再进行编译:


import fetch from 'node-fetch';export default fetch('<某个远程服务或文件返回实际配置>');
// orexport default Promise.all([fetch('get-config-1'), fetch('get-config-2')]);
复制代码

使用配置文件:

通过命令的 config 选项来指明配置文件。

显示执行
rollup --config my.config.js
复制代码
隐式执行

执行顺序:rollup.config.mjs -> rollup.config.cjs -> rollup.config.js


rollup --config
复制代码

自定义命令行选项:

在下面的配置文件中我们导入了两份提前写好的不同环境的配置文件,我们通过接收命令行传入的“configDebug”选项来选择使用哪一个配置文件进行执行。默认情况下命令行传入的选项的优先级最高,当然也可以在解析到传入的选项后进行拦截删除。


// rollup.config.jsimport defaultConfig from './rollup.default.config.js';import debugConfig from './rollup.debug.config.js';
export default commandLineArgs => { if (commandLineArgs.configDebug === true) { return debugConfig; } return defaultConfig;};
复制代码

编程提示:

Rollup 附带了 TypeScript 类型,可以通过 IDE 的智能提示和 JSDoc 进行编写时的提示。也可以使用 Rollup 提供的帮助程序完成,如下:


// rollup.config.jsimport { defineConfig } from 'rollup';
export default defineConfig({ // ...});
复制代码

Node 13+注意事项:

  1. 只能从 CommonJS 插件中获得默认导出;

  2. 无法直接导入 JSON 文件使用;


// load-package.cjsmodule.exports = require('./package.json');
// rollup.config.mjsimport pkg from './load-package.cjs';...
复制代码

配置大全:

下面是摘录自rollupjs.org,的配置大全:


export default {  // 核心输入选项  external,  input, // conditionally required  plugins,
// 高级输入选项 cache, onwarn, preserveEntrySignatures, strictDeprecations,
// danger zone acorn, acornInjectPlugins, context, moduleContext, preserveSymlinks, shimMissingExports, treeshake,
// 实验性的配置 experimentalCacheExpiry, perf,
// 必需的(可以是一个数组,用于多个输出) output: { // 核心输出选项 dir, file, format, // required globals, name, plugins,
// 高级输出选项 assetFileNames, banner, chunkFileNames, compact, entryFileNames, extend, footer, hoistTransitiveImports, inlineDynamicImports, interop, intro, manualChunks, minifyInternalExports, outro, paths, preserveModules, preserveModulesRoot, sourcemap, sourcemapExcludeSources, sourcemapFile, sourcemapPathTransform, validate,
// danger zone amd, esModule, exports, externalLiveBindings, freeze, indent, namespaceToStringTag, noConflict, preferConst, sanitizeFileName, strict, systemNullSetters },
watch: { buildDelay, chokidar, clearScreen, skipWrite, exclude, include }};
复制代码

命令行参数大全:

下面是摘录自rollupjs.org,的命令行参数大全:


编译完整版流程:

准备基础环境:

  1. 安装 rollup,并使用 rollup 命令验证;

  2. 创建目录,准备内容;


src├─── main.js└─── foo.js
复制代码


// src/main.jsimport foo from './foo.js';export default function () {    console.log(foo);}
复制代码


// src/foo.jsexport default 'hello world!';
复制代码


  1. 只编译,不输出到文件:


执行命令:rollup src/main.js -f cjs


// 输出内容'use strict';
var foo = 'hello world!';
function main () { console.log(foo);}
module.exports = main;
复制代码


  1. 编译并输出到 bundle 文件:


执行命令:rollup src/main.js -o bundle.js -f cjs


// 输出内容'use strict';
var foo = 'hello world!';
function main () { console.log(foo);}
module.exports = main;
复制代码


  1. 在 node 中使用这个 bundle 文件:


node> var myBundle = require('./bundle.js');> myBundle();'hello world!'
复制代码

使用配置文件:

创建 rollup.config.js 配置文件,执行命令缩短为:rollup -c。


// rollup.config.jsexport default {  input: 'src/main.js',  output: {    file: 'bundle.js',    format: 'cjs'  }};
复制代码

使用插件:

awesome

为了安装插件需要更新项目环境:

  1. 初始化目录:npm init -y;

  2. 安装处理 JSON 文件的开发依赖:@rollup/plugin-json;

更新 main.js,支持读取 package.json:

import { version } from '../package.json';
export default function () { console.log('version ' + version);}
复制代码

更新配置文件,配置安装的 @rollup/plugin-json 插件:

// rollup.config.jsimport json from '@rollup/plugin-json';
export default { ... plugins: [json()]};
复制代码

再次编译并在 node 中使用:

编译后的产物将只包含使用到得 version,体现了 Tree-Shaking 的作用。


'use strict';
var version = "1.0.0";
function main () { console.log('version ' + version);}
module.exports = main;
复制代码


node> var myBundle = require('./bundle.js');> myBundle();version 1.0.0
复制代码

使用针对输出的插件:

使用 rollup-plugin-terser 插件对输出内容压缩:

// rollup.config.jsimport json from '@rollup/plugin-json';import { terser } from 'rollup-plugin-terser';
export default { input: 'src/main.js', output: [ { file: 'bundle.js', format: 'cjs', }, // 针对iife风格的输出处理 { file: 'bundle.min.js', format: 'iife', name: 'version', plugins: [terser()], }, ], plugins: [json()],};
复制代码

iife 风格的输出产物将被压缩成一行:

var version=function(){"use strict";return function(){console.log("hello world!"),console.log("version 1.0.0")}}();
复制代码


发布于: 刚刚阅读数: 4
用户头像

小鑫同学

关注

⚡InfoQ签约作者 2018-12-10 加入

还未添加个人简介

评论

发布
暂无评论
【入门教程】Rollup模块打包器整合_前端_小鑫同学_InfoQ写作社区