跳到內容

將 Rollup 與其他工具整合

使用 NPM 套件

在某些時候,您的專案可能會依賴已安裝至 node_modules 資料夾的 NPM 套件。相較於其他套件管理工具,例如 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。如果你按照上述說明設定 externals,你的 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 會傳回 gulp 可以理解的 Promises,因此整合相對容易。

語法與組態檔非常類似,但屬性會分割在兩個不同的操作中,對應到 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 授權條款下發布。