跳至内容

将 Rollup 与其他工具集成

使用 NPM 包

在某些时候,您的项目可能会依赖于从 NPM 安装到您的 node_modules 文件夹中的包。与 Webpack 和 Browserify 等其他捆绑器不同,Rollup 不“开箱即用”地知道如何处理这些依赖项 - 我们需要添加一些配置。

让我们添加一个名为 the-answer 的简单依赖项,它导出对生命、宇宙和万物的终极问题的答案。

shell
npm install the-answer
# or `npm i the-answer`

如果我们更新我们的 src/main.js 文件…

js
// src/main.js
import answer from 'the-answer';

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

…并运行 Rollup…

shell
npm run build

…我们将看到类似这样的警告

(!) Unresolved dependencies
https://github.com/rollup/rollup/wiki/Troubleshooting#treating-module-as-external-dependency
the-answer (imported by main.js)

生成的 bundle.js 仍然可以在 Node.js 中工作,因为 import 声明被转换为 CommonJS require 语句,但 the-answer 不会 被包含在捆绑包中。为此,我们需要一个插件。

@rollup/plugin-node-resolve

@rollup/plugin-node-resolve 插件教 Rollup 如何查找外部模块。安装它…

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

…并将其添加到您的配置文件中

js
// rollup.config.js
import resolve from '@rollup/plugin-node-resolve';

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

这次,当您 npm run build 时,不会发出警告 - 捆绑包包含导入的模块。

@rollup/plugin-commonjs

一些库公开 ES 模块,您可以按原样导入 - the-answer 就是这样的一个模块。但目前,NPM 上大多数包都以 CommonJS 模块的形式公开。在这种情况改变之前,我们需要在 Rollup 处理它们之前将 CommonJS 转换为 ES2015。

@rollup/plugin-commonjs 插件正是这样做的。

请注意,大多数情况下 @rollup/plugin-commonjs 应该放在其他转换模块的插件之前 - 这是为了防止其他插件进行破坏 CommonJS 检测的更改。此规则的一个例外是 Babel 插件,如果您使用它,请将其放在 commonjs 插件之前。

对等依赖

假设您正在构建一个具有对等依赖项的库,例如 React 或 Lodash。如果您按照上述方法设置外部依赖项,您的 rollup 将捆绑所有导入

js
import answer from 'the-answer';
import _ from 'lodash';

您可以微调哪些导入被捆绑以及哪些被视为外部依赖项。对于此示例,我们将 lodash 视为外部依赖项,但 the-answer 则不是。

这是配置文件

js
// rollup.config.js
import resolve from '@rollup/plugin-node-resolve';

export default {
	input: 'src/main.js',
	output: {
		file: 'bundle.js',
		format: 'cjs'
	},
	plugins: [
		resolve({
			// pass custom options to the resolve plugin
			moduleDirectories: ['node_modules']
		})
	],
	// indicate which modules should be treated as external
	external: ['lodash']
};

瞧,lodash 现在将被视为外部依赖项,并且不会与您的库捆绑在一起。

external 键接受模块名称数组或一个函数,该函数接受模块名称并返回 true(如果它应该被视为外部依赖项)。例如

js
export default {
	// ...
	external: id => /lodash/.test(id)
};

如果您使用 babel-plugin-lodash 来挑选 lodash 模块,您可能会使用这种形式。在这种情况下,Babel 将转换您的导入语句,使其看起来像这样

js
import _merge from 'lodash/merge';

external 的数组形式不处理通配符,因此此导入仅在函数形式中被视为外部依赖项。

Babel

许多开发人员在他们的项目中使用 Babel 为了使用浏览器和 Node.js 尚未支持的最新 JavaScript 功能。

使用 Babel 和 Rollup 的最简单方法是使用 @rollup/plugin-babel。首先,安装插件

shell
npm i -D @rollup/plugin-babel @rollup/plugin-node-resolve

将其添加到 rollup.config.js

js
// 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

json
{
	"presets": ["@babel/env"]
}

我们将 .babelrc.json 文件放在 src 中,而不是项目根目录中。这使我们能够为测试等内容拥有不同的 .babelrc.json,如果我们以后需要的话 - 有关项目范围和文件相对配置的更多信息,请参阅 Babel 文档

现在,在我们运行 rollup 之前,我们需要安装 babel-coreenv 预设

shell
npm i -D @babel/core @babel/preset-env

现在运行 Rollup 将创建一个捆绑包 - 除了我们实际上没有使用任何 ES2015 功能。让我们通过编辑 src/main.js 来改变这一点

js
// src/main.js
import answer from 'the-answer';

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

使用 npm run build 运行 Rollup,并检查捆绑包

js
'use strict';

var index = 42;

var main = function () {
	console.log('the answer is ' + index);
};

module.exports = main;

Gulp

Rollup 返回 Promise,这些 Promise 为 gulp 所理解,因此集成相对容易。

语法与配置文件非常相似,但属性分布在两个不同的操作中,分别对应于 JavaScript API

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

gulp.task('build', () => {
	return rollup
		.rollup({
			input: './src/main.ts',
			plugins: [rollupTypescript()]
		})
		.then(bundle => {
			return bundle.write({
				file: './dist/library.js',
				format: 'umd',
				name: 'library',
				sourcemap: true
			});
		});
});

您也可以使用 async/await 语法

js
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
	});
});

Deno

如果您想在 Deno 中运行 Rollup,您可以使用 esm.sh,如下所示

js
import { rollup } from "https://esm.sh/@rollup/browser";

const bundle = await rollup({ //...

但这不适合复杂的编译。或者,您可以从 npm 安装 rollup

js
import { rollup } from "npm:rollup";

const bundle = await rollup({ //...

注意:Deno 在运行 Rollup 时会请求一些权限。

根据 MIT 许可发布。