[note] rollup-js 筆記
keywords: 打包, bundle
rollup.js @ official website
Quick Start
可以參考 Rollup 的這兩個啟動專案:
- rollup-starter-lib:用 rollup.js 建立套件的起始架構
- rollup-starter-app:用 rollup.js 建立應用程式的起始架構
假設應用程式的進入點(entry point)是 main.js,打包後的檔案稱作 bundle.js,則
給瀏覽器(iife):
# compile to a <script> containing a self-executing function ('iife')
rollup main.js --file bundle.js --format iife
給 Node.js(cjs):
# compile to a CommonJS module ('cjs')
rollup main.js --file bundle.js --format cjs
同時給瀏覽器和 Node.js(umd):
# UMD format requires a bundle name
rollup main.js --file bundle.js --format umd --name "myBundle"
發佈 ES Modules
為了確保你的 ES Modules 可以立即 Node.js 或 Webpack 這類 CommonJS 的工具所使用,你可以使用 Rollup 來編譯成 UMD 或 CommonJS 的格式,接著在 package.json 中的 main 屬性指定該打包好的檔案,如果你的 package.json 中也有 module 這個屬性,則 ESM-aware 的工具(例如,Rollup 和 web pack 2+)將會直接載入 ES Module 的版本。
Plugins
- rollup plugins @ rollupjs Github
- using-output-plugin @ rollupjs docs
- rollup-plugin-terser @ github
- @rollup/plugin-commonjs:可以將以 CommonJS 寫的模 組轉換成 ES6,如此就可以在 Rollup 中匯入 CommonJS 的模組。
- @rollup/plugin-node-resolve:rollup 才會解析
node_modules裡面的第三方套件,如果自己的套件中有用到其他第三方的套件時需安裝。 - rollup-plugin-terser:可以用來壓縮打包後的檔案
Command Line Interface (CLI)
Command Line 可用參數
Command line flags @ rollup.js > CLI
# 直接透過 CLI 打包
# -f 是 --format <format>, -o 是 --file <output>
$ rollup index.js -f cjs -o bundle.js
# 根據 rollup.config.js 打包
# -c 是 --config <filename>,沒填 filename 預設會直接吃 rollup.config.js
$ rollup -c
設定檔(Configuration Files)
configuration files @ rollup.js > CLI
若下面情況一定要使用 Rollup 設定檔:
- 一個專案打包成多支 output 檔案
- 使用 Rollup 的外掛(plugin),像是 @rollup/plugin-node-resolve、 @rollup/plugin-commonjs
透過 rollup CLI 的 --config 或 -c 可以執行設定檔 :
# Rollup 會讀取 rollup.config.js
rollup --config
# Rollup 會讀取自定義檔名的設定檔
rollup --config my.config.js
# .js and .mjs are supported
rollup --config my.config.mjs
Rollup 的設定檔名稱為 rollup.config.js,它用 ES Module 或 CommonJS 來寫都可以:
// rollup.config.js
import babel from 'rollup-plugin-babel';
import commonjs from 'rollup-plugin-commonjs';
import external from 'rollup-plugin-peer-deps-external';
import resolve from 'rollup-plugin-node-resolve';
import url from 'rollup-plugin-url';
import pkg from './package.json';
export default {
input: 'src/index.js',
output: [
{
file: pkg.main, // 會去讀取 package.json 的 main 欄位
format: 'cjs', // Common JS
sourcemap: true,
},
{
file: pkg.module, // 會去讀取 package.json 的 module 欄位
format: 'es', // ES Module
sourcemap: true,
},
{
name: 'myBundle',
file: 'dist/bundle.umd.js',
format: 'umd', // 給瀏覽器和 Node.js
sourcemap: true,
},
{
file: 'dist/bundle.js',
format: 'iife', // 給瀏覽器
sourcemap: true,
},
],
plugins: [
external(),
url({ exclude: ['**/*.svg'] }),
babel({
exclude: 'node_modules/**',
}),
resolve(),
commonjs(),
],
};
其他
With NPM Packages
keywords: @rollup/plugin-node-resolve, @rollup/plugin-commonjs
With NPM Packages @ GitHub
+ import resolve from '@rollup/plugin-node-resolve';
+ import commonjs from '@rollup/plugin-commonjs';
export default {
input: 'src/index.js',
output: [
{
file: 'dist/index.cjs.js',
format: 'cjs',
},
{
file: 'dist/index.esm.js',
format: 'esm',
},
],
+ plugins: [resolve(), commonjs()]
};
(!) Unresolved dependencies: @rollup/plugin-node-resolve
碰到這個問題時要考慮的情況是:「這個 modules 有沒有要打包到最後 build 好的檔案中」
- 如果沒有,並沒有要放到最終 build 好的檔案中,而是只要當作依賴,使用者仍須自己安裝該套件的話,則把該套件放到
external欄位中,如下一段「Peer Dependencies:告訴 rollup 哪些 module 不需要被打包」所述。 - 如果要,這個 modules 執行後的結果是需要被打包進去的,那麼才需要使用
@rollup/plugin-node-resolve。
需要安裝 @rollup/plugin-node-resolve,它會讓 rollup 知道如何找到外部的模組,並把它放入打包好的檔案中。
如果沒有使用此 plugin 的話,安裝的套件不會一起被打包,使用者需要自行安裝:
import answer from 'the-answer';
function index() {
console.log('answer ' + answer);
}
export default index;
若有使用此 plugin,則會一併把該套件或套件執行後的結果打包進去:
// 搭配 resolve 打包後的結果
var index = 42;
const A = `I am A, and the answer is ${index}`;
export { A as a };
沒有使用 resolve 的話,node_modules 的內容即使在打包後,仍會透過 import 的方式:
// 搭配 resolve 打包後的結果
import answer from 'the-answer';
const A = `I am A, and the answer is ${answer}`;
export default A;
@rollup/plugin-commonjs
@rollup/plugin-commonjs @ guide > with npm packages
由於打包過的檔案不一定支援 ESM 的使用,透過 @rollup/plugin-commonjs 可以把 CommonJS modules 轉成 ES6 後,放到 Rollup 打包好的檔案內。
Peer Dependencies:告訴 rollup 哪些 module 不需要被打包
keywords: external
透過 external 可以告訴 rollup 哪些檔案不需要一起被打包,這些檔案通常是 peerDependencies,像是 lodash 或 React,是需要使用此套件的人自己安裝的。
// rollup.config.js
export default {
// 可以用陣列的方式來定義
external: ['lodash', 'styled-components', '/@babel/runtime/'], // 陣列不接受 wildcard 的用法
// 可以用 function 的方式,回傳 true 表示它是 external
external: (id) => /lodash/.test(id),
};
另外,external 也接受正規式的使用:
export const rollupExternal = [
'prop-types',
'react',
/react\/jsx-runtime/,
'styled-components',
/@od-lego\/*/, // all @od-lego packages will treat as external
/@babel\/runtime/,
];
export default {
input: 'src/index.js',
output: [
/* ... */
],
external: rollupExternal,
plugins: rollupPluginList,
};
Babel
用途
使用 Babel 的話可以把專案程式碼打包成支援更舊版本語法。
--- a/dist/index.esm.js
+++ b/dist/index.esm.js
@@ -2,15 +2,14 @@ var version = "1.0.0";
var index$1 = 42;
-// 沒使用 babel
-var getAnswer = () => {
- console.log(`the answer is ${index$1}`);
-};
+// 有使用 babel
+var getAnswer = (function () {
+ console.log("the answer is ".concat(index$1));
+});
function index () {
console.log('version ' + version);
getAnswer();
}
-
console.log('version ' + version);
getAnswer();