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

2022-12-26 12:51:40 浏览数 (2)

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

特点:

  1. 选用ES6标准模块化格式;
  2. 支持静态分析导入代码进行Tree-Shaking。

兼容:

  1. 支持导入CommonJs模块;
  2. 方便使用到CommonJS模块的工具,如:Node.js、webpack。

ES 模块语法:

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

快速开始:

常见编译输出风格:

命名

风格

适用

iife

立即执行函数

浏览器

cjs

CommonJs

NodeJs

umd

通用模块定义

浏览器/NodeJs

编译案例演示:

rollup采用ES6标准模块化格式

定义一个待编译的ES6模块:
代码语言:javascript复制
// 文件名:main.js
const main = {
    hello: () => {
        console.log('Hello');
    },
    world: () => {
        console.log('World');
    },
};
export default main;
编译为IIFE风格:
命令示例:
代码语言:javascript复制
rollup <入口文件> --file <输出文件> --name <输出模块名称> --format <输出模块类型>

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

编译命令:
代码语言:javascript复制
rollup .main.js --file bundle.iife.js --name myBundle --format iife
输出产物:
代码语言:javascript复制
// 文件名:bundle.iife.js
var myBundle = (function () {
    'use strict';

    const main = {
        hello: () => {
            console.log('Hello');
            return 'Hello';
        },
        world: () => {
            console.log('World');
            return 'World';
        },
    };

    return main;

})();
在浏览器中使用:
代码语言:javascript复制
<head>
    <script src="../bundle.iife.js"></script>
</head>

<body>
    <script>
        myBundle.hello();
    </script>
</body>
编译为CJS风格:
命令示例:
代码语言:javascript复制
rollup <入口文件> --file <输出文件> --exports <导出模式> --format <输出模块类型>

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

编译命令:
代码语言:javascript复制
rollup .main.js --file bundle.cjs.js --exports auto --format cjs
输出产物:
代码语言:javascript复制
// 文件名:bundle.cjs.js
'use strict';

const main = {
    hello: () => {
        console.log('Hello');
    },
    world: () => {
        console.log('World');
    },
};

module.exports = main;
在Node环境中使用:
代码语言:javascript复制
const main = require('../bundle.cjs.js');
console.log(main.hello());
编译为UMD风格:
命令示例:
代码语言:javascript复制
rollup <入口文件> --file <输出文件> --name <输出模块名称> --format <输出模块类型>

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

编译命令:
代码语言:javascript复制
rollup main.js --file bundle.umd.js  --name myBundle --format umd
输出产物:
代码语言:javascript复制
// 文件名:bundle.umd.js
(function (global, factory) {
    typeof exports === 'object' &amp;&amp; typeof module !== 'undefined' ? module.exports = factory() :
    typeof define === 'function' &amp;&amp; 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;

}));
在浏览器中使用:
代码语言:javascript复制
<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环境中使用:
代码语言:javascript复制
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中。

代码语言:javascript复制
// 文件名称:rollup.config.js
export default {
    input: 'main.js',
    output: {
        file: 'bundle.js',
        format: 'cjs',
        exports: 'auto'
    },
};
多入口,多出口配置文件:

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

代码语言:javascript复制
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来获取不同的配置后再进行编译:

代码语言:javascript复制
import fetch from 'node-fetch';
export default fetch('<某个远程服务或文件返回实际配置>');

// or
export default Promise.all([fetch('get-config-1'), fetch('get-config-2')]);
使用配置文件:

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

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

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

代码语言:javascript复制
rollup --config
自定义命令行选项:

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

代码语言:javascript复制
// rollup.config.js
import 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提供的帮助程序完成,如下:

代码语言:javascript复制
// rollup.config.js
import { defineConfig } from 'rollup';

export default defineConfig({
  // ...
});
Node 13 注意事项:
  1. 只能从 CommonJS 插件中获得默认导出;
  2. 无法直接导入 JSON 文件使用;
代码语言:javascript复制
// load-package.cjs
module.exports = require('./package.json');

// rollup.config.mjs
import pkg from './load-package.cjs';
...
配置大全:

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

代码语言:javascript复制
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,的命令行参数大全:

简写

命令

参数

用途

-c

--config

filename

Use this config file (if argument is used but valueis unspecified, defaults to rollup.config.js)

-d

--dir

dirname

Directory for chunks (if absent, prints to stdout)

-e

--external

ids

Comma-separate list of module IDs to exclude

-f

--format

format

Type of output (amd, cjs, es, iife, umd, system)

-g

--globals

pairs

Comma-separate list of moduleID:Globalpairs

-h

--help

Show this help message

-i

--input

filename

Input (alternative to )

-m

--sourcemap

Generate sourcemap (-m inlinefor inline map)

-n

--name

name

Name for UMD export

-o

--file

output

Single output file (if absent, prints to stdout)

-p

--plugin

plugin

Use the plugin specified (may be repeated)

-v

--version

Show version number

-w

--watch

Watch files in bundle and rebuild on changes

--amd.id

id

ID for AMD module (default is anonymous)

--amd.autoId

Generate the AMD ID based off the chunk name

--amd.basePath

prefix

Path to prepend to auto generated AMD ID

--amd.define

name

Function to use in place of define

--assetFileNames

pattern

Name pattern for emitted assets

--banner

text

Code to insert at top of bundle (outside wrapper)

--chunkFileNames

pattern

Name pattern for emitted secondary chunks

--compact

Minify wrapper code

--context

variable

Specify top-level thisvalue

--entryFileNames

pattern

Name pattern for emitted entry chunks

--environment

values

Settings passed to config file (see example)

--no-esModule

Do not add __esModule property

--exports

mode

Specify export mode (auto, default, named, none)

--extend

Extend global variable defined by --name

--no-externalLiveBindings

Do not generate code to support live bindings

--failAfterWarnings

Exit with an error if the build produced warnings

--footer

text

Code to insert at end of bundle (outside wrapper)

--no-freeze

Do not freeze namespace objects

--no-hoistTransitiveImports

Do not hoist transitive imports into entry chunks

--no-indent

Don't indent result

--no-interop

Do not include interop block

--inlineDynamicImports

Create single bundle when using dynamic imports

--intro

text

Code to insert at top of bundle (inside wrapper)

--minifyInternalExports

Force or disable minification of internal exports

--namespaceToStringTag

Create proper .toStringmethods for namespaces

--noConflict

Generate a noConflict method for UMD globals

--outro

text

Code to insert at end of bundle (inside wrapper)

--preferConst

Use constinstead of varfor exports

--no-preserveEntrySignatures

Avoid facade chunks for entry points

--preserveModules

Preserve module structure

--preserveModulesRoot

Put preserved modules under this path at root level

--preserveSymlinks

Do not follow symlinks when resolving files

--no-sanitizeFileName

Do not replace invalid characters in file names

--shimMissingExports

Create shim variables for missing exports

--silent

Don't print warnings

--sourcemapExcludeSources

Do not include source code in source maps

--sourcemapFile

file

Specify bundle position for source maps

--stdin=ext

Specify file extension used for stdin input

--no-stdin

Do not read "-" from stdin

--no-strict

Don't emit "use strict";in the generated modules

编译完整版流程:

准备基础环境:

  1. 安装rollup,并使用rollup命令验证;
  2. 创建目录,准备内容;
代码语言:javascript复制
src
├─── main.js
└─── foo.js
代码语言:javascript复制
// src/main.js
import foo from './foo.js';
export default function () {
    console.log(foo);
}
代码语言:javascript复制
// src/foo.js
export default 'hello world!';
  1. 只编译,不输出到文件:

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

代码语言:javascript复制
// 输出内容
'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

代码语言:javascript复制
// 输出内容
'use strict';

var foo = 'hello world!';

function main () {
    console.log(foo);
}

module.exports = main;
  1. 在node中使用这个bundle文件:
代码语言:javascript复制
node
> var myBundle = require('./bundle.js');
> myBundle();
'hello world!'

使用配置文件:

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

代码语言:javascript复制
// rollup.config.js
export 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:
代码语言:javascript复制
import { version } from '../package.json';

export default function () {
  console.log('version '   version);
}
更新配置文件,配置安装的@rollup/plugin-json插件:
代码语言:javascript复制
// rollup.config.js
import json from '@rollup/plugin-json';

export default {
  ...
  plugins: [json()]
};
再次编译并在node中使用:

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

代码语言:javascript复制
'use strict';

var version = "1.0.0";

function main () {
    console.log('version '   version);
}

module.exports = main;
代码语言:javascript复制
node
> var myBundle = require('./bundle.js');
> myBundle();
version 1.0.0

使用针对输出的插件:

使用rollup-plugin-terser插件对输出内容压缩:
代码语言:javascript复制
// rollup.config.js
import 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风格的输出产物将被压缩成一行:
代码语言:javascript复制
var version=function(){"use strict";return function(){console.log("hello world!"),console.log("version 1.0.0")}}();

0 人点赞