前沿?
Rollup 是一個用于 JavaScript 的模塊打包工具,它將小的代碼片段編譯成更大、更復雜的代碼,例如庫或應用程序。它使用 JavaScript 的 ES6 版本中包含的新標準化代碼模塊格式,而不是以前的 CommonJS 和 AMD 等特殊解決方案。ES 模塊允許你自由無縫地組合你最喜歡的庫中最有用的個別函數。這在未來將在所有場景原生支持,但 Rollup 讓你今天就可以開始這樣做。
目錄
前沿?
1、安裝
2、準備工作
3、快速開始
4、除屑優化(Tree-Shaking)?
5、配置文件?
6、導入 package.json
7、使用插件
1、安裝依賴
2、更新main.js入口文件?
3、使用@rollup/plugin-json插件?
4、執行編譯
8、使用輸出插件(壓縮)
1、安裝依賴
2、使用@rollup/plugin-terser插件
3、執行編譯
9、構建
1、安裝
使用 npm 全局安裝?rollup.js
$ npm install --global rollup
added 3 packages in 12s
安裝完畢,node安裝目錄(D:\AppData\nodejs)會生產出來這三個文件
?
輸入 rollup --help 可以查看當前rollup版本信息和其他選項操作
$ rollup --helprollup version 4.18.0
=====================================Usage: rollup [options] <entry file>Basic options:-c, --config <filename> 使用此配置文件(如果使用參數但未指定值,則默認為 rollup.config.js)
-d, --dir <dirname> 用于塊的目錄(如果不存在,則打印到 stdout)
-e, --external <ids> 排除模塊 ID 的逗號分隔列表
-f, --format <format> 輸出類型(amd、cjs、es、iife、umd、system)
-g, --globals <pairs> `moduleID:Global` 對的逗號分隔列表
-h, --help 顯示此幫助消息
-i, --input <filename> 輸入(替代 <entry file>)
-m, --sourcemap 生成源映射(`-m inline` 為內聯映射)
-n, --name <name> UMD 導出的名稱
-o, --file <output> 單個輸出文件(如果不存在,則打印到 stdout)
-p, --plugin <plugin> 使用指定的插件(可重復)
-v, --version 顯示版本號
-w, --watch 監視產物文件并在更改時重新構建
--amd.autoId 基于塊名稱生成 AMD ID
--amd.basePath <prefix> 要預先添加到自動生成的 AMD ID 的路徑
--amd.define <name> 在 `define` 位置使用的函數
--amd.forceJsExtensionForImports 在 AMD 導入中使用 `.js` 擴展名
--amd.id <id> AMD 模塊的 ID(默認為匿名)
--assetFileNames <pattern> 發布資源的名稱模式
--banner <text> 在產物頂部插入的代碼(位于包裝器之外)
--chunkFileNames <pattern> 發布次要塊的名稱模式
--compact 縮小包裝器代碼
--context <variable> 指定頂級 `this` 值
--no-dynamicImportInCjs 將外部動態 CommonJS 導入編寫為 require
--entryFileNames <pattern> 發布入口塊的名稱模式
--environment <values> 傳遞給配置文件的設置(請參閱示例)
--no-esModule 不添加 __esModule 屬性
--exports <mode> 指定導出模式(auto、default、named、none)
--extend 擴展由 --name 定義的全局變量
--no-externalImportAttributes 在 "es" 格式輸出中省略導入屬性
--no-externalLiveBindings 不生成支持實時綁定的代碼
--failAfterWarnings 如果生成的構建產生警告,則退出并顯示錯誤
--filterLogs <filter> 過濾日志信息
--footer <text> 在產物底部插入的代碼(位于包裝器之外)
--forceExit 當任務完成后,強制結束進程
--no-freeze 不凍結命名空間對象
--generatedCode <preset> 使用哪些代碼特性(es5/es2015)
--generatedCode.arrowFunctions 在生成的代碼中使用箭頭函數
--generatedCode.constBindings 在生成的代碼中使用 "const"
--generatedCode.objectShorthand 在生成的代碼中使用簡寫屬性
--no-generatedCode.reservedNamesAsProps 始終引用保留名稱作為 props
--generatedCode.symbols 在生成的代碼中使用符號
--hashCharacters <name> 使用指定的字符集來生成文件的哈希值
--no-hoistTransitiveImports 不將中轉導入提升到入口塊中
--importAttributesKey <name> 使用特定的關鍵詞作為導入屬性
--no-indent 不縮進結果
--inlineDynamicImports 使用動態導入時創建單次打包
--no-interop 不包括交互操作塊
--intro <text> 在產物頂部插入的代碼(位于包裝器內部)
--logLevel <level> 要顯示哪種類型的日志
--no-makeAbsoluteExternalsRelative 不規范化外部導入
--maxParallelFileOps <value> 并行讀取的文件數
--minifyInternalExports 強制或禁用內部導出的縮小
--noConflict 為 UMD 全局生成 noConflict 方法
--outro <text> 在產物底部插入的代碼(位于包裝器內部)
--perf 顯示性能計時
--no-preserveEntrySignatures 避免入口點的門面塊
--preserveModules 保留模塊結構
--preserveModulesRoot 將保留的模塊放置在根路徑下的此路徑下
--preserveSymlinks 解析文件時不要跟隨符號鏈接
--no-reexportProtoFromExternal 在使用重新導出星號('*')時,忽略 __proto__
--no-sanitizeFileName 不要替換文件名中的無效字符
--shimMissingExports 為丟失的導出創建卡扣變量
--silent 不打印警告
--sourcemapBaseUrl <url> 使用給定的基本 URL 發出絕對源映射 URL
--sourcemapExcludeSources 在源映射中不包括源代碼
--sourcemapFile <file> 指定源映射的包位置
--sourcemapFileNames <pattern> 編譯后 sourcemap 的命名模式
--stdin=ext 指定用于標準輸入的文件擴展名
--no-stdin 不要從 stdin 讀取 "-"
--no-strict 不在生成的模塊中發出 `"use strict";`
--strictDeprecations 拋出有關不推薦使用的功能的錯誤
--no-systemNullSetters 不要將空的 SystemJS setter 替換為 `null`
--no-treeshake 禁用除屑優化
--no-treeshake.annotations 忽略純調用注釋
--treeshake.correctVarValueBeforeDeclaration 在聲明之前將變量取消優化
--treeshake.manualPureFunctions <names> 手動將函數聲明為純函數
--no-treeshake.moduleSideEffects 假設模塊沒有副作用
--no-treeshake.propertyReadSideEffects 忽略屬性訪問副作用
--no-treeshake.tryCatchDeoptimization 不要關閉 try-catch-tree-shaking
--no-treeshake.unknownGlobalSideEffects 假設未知的全局變量不會拋出異常
--validate 驗證輸出
--waitForBundleInput 等待打包輸入文件
--watch.buildDelay <number> 節流觀察重建
--no-watch.clearScreen 重建時不要清除屏幕
--watch.exclude <files> 排除要觀察的文件
--watch.include <files> 限制觀察到指定文件
--watch.onBundleEnd <cmd> 在 "BUNDLE_END" 事件上運行的 Shell 命令
--watch.onBundleStart <cmd> 在 "BUNDLE_START" 事件上運行的 Shell 命令
--watch.onEnd <cmd> 在 "END" 事件上運行的 Shell 命令
--watch.onError <cmd> 在 "ERROR" 事件上運行的 Shell 命令
--watch.onStart <cmd> 在 "START" 事件上運行的 Shell 命令
--watch.skipWrite 在監視時不要將文件寫入磁盤Examples:# use settings in config file
rollup -c# in config file, process.env.INCLUDE_DEPS === 'true'
# and process.env.BUILD === 'production'
rollup -c --environment INCLUDE_DEPS,BUILD:production# create CommonJS bundle.js from src/main.js
rollup --format=cjs --file=bundle.js -- src/main.js# create self-executing IIFE using `window.jQuery`
# and `window._` as external globals
rollup -f iife --globals jquery:jQuery,lodash:_ \-i src/app.js -o build/app.js -m build/app.js.mapNotes:* When piping to stdout, only inline sourcemaps are permittedFor more information visit https://rollupjs.org
2、準備工作
- 創建一個簡單的項目
mkdir -p Rollup
cd Rollup
- 創建入口文件main.js
# main.js
function test() {const d = new Date();console.log(d.getFullYear(), d.getMonth())
}
export default test();
3、快速開始
可以通過帶有可選配置文件的 命令行界面 或 JavaScript API 來使用 Rollup。
這些命令假定你的應用程序入口點命名為 main.js,并且希望將所有導入編譯到一個名為 bundle.js 的單個文件中。
?
- 對于瀏覽器
# 編譯為包含自執行函數('iife')的 <script>。
rollup main.js --file bundle.js --format iife
執行效果:
- 對于 Node.js
# 編譯為一個 CommonJS 模塊 ('cjs')
rollup main.js --file bundle.js --format cjs
執行效果:
- 對于瀏覽器和 Node.js
# UMD 格式需要一個包名
rollup main.js --file bundle.js --format umd --name "myBundle"
執行效果:
?
4、除屑優化(Tree-Shaking)?
除了可以使用 ES 模塊之外,Rollup 還可以靜態分析你導入的代碼,并將排除任何實際上沒有使用的內容。這使你可以在現有的工具和模塊的基礎上構建,而不需要添加額外的依賴項或使項目的大小變得臃腫。
例如,使用 CommonJS 必須導入整個工具或庫。
// 使用 CommonJS 導入整個 utils 對象
const utils = require('./utils');
const query = 'Rollup';
// 使用 utils 對象的 ajax 方法。
utils.ajax(`https://api.example.com?search=${query}`).then(handleResponse);
使用 ES 模塊,我們不需要導入整個 utils 對象,而只需導入我們需要的一個 ajax 函數:
// 使用 ES6 的 import 語句導入 ajax 函數。
import { ajax } from './utils';
const query = 'Rollup';
// 調用 ajax 函數
ajax(`https://api.example.com?search=${query}`).then(handleResponse);
因為 Rollup 只包含最少的內容,因此它生成的庫和應用程序更輕、更快、更簡單。由于這種方法可以利用顯式的 import 和 export 語句,因此它比僅運行最小化混淆工具更能有效檢測出已編譯輸出代碼中的未使用變量。
示例
這里更新了目錄結構,執行以下命令將 main.js 編譯為一個 es 模塊
1、創建src文件夾將main.js移入,創建output文件夾為打包bundle.js做存儲。
# 執行命令
rollup ./src/main.js --file ./output/bundle.js --format es
我們新增了一個 notCast 函數,但main.js的test函數并未使用它,output/bundle.js并未為其編譯
我們新增了一個 notCast 函數,將其引入到test函數中使用,編譯后發現已經編譯并使用
?
5、配置文件?
Rollup 配置文件是可選的,但它們非常強大和方便,因此推薦使用。配置文件是一個 ES 模塊,它導出一個默認對象,其中包含所需的選項:
# rollup.config.mjs
export default {input: 'src/main.js',output: {file: 'bundle.js',format: 'es'}
};
通常,它被稱為 rollup.config.js 或 rollup.config.mjs,并位于項目的根目錄中。
如果你想使用 require 和 module.exports 編寫 CommonJS 模塊的配置文件,你應該將文件擴展名更改為 .cjs。
要使用配置文件來運行 Rollup,請傳遞 --config 或 -c 標志:
# 向 Rollup 傳遞自定義配置文件位置
rollup --config my.config.js# 如果你沒有傳遞文件名,Rollup 將會嘗試
# 按照以下順序加載配置文件:
# rollup.config.mjs -> rollup.config.cjs -> rollup.config.js
rollup --config
執行效果
?
6、導入 package.json
導入你的 package 文件可能很有用,例如自動將你的依賴項標記為 “external”。
在 Rollup 中,可以通過 external 選項來指定哪些模塊應該被視為外部依賴。這些模塊不會被打包進最終的構建文件中,而是會被認為是已經存在于運行環境中的模塊,例如在瀏覽器端通過 script 標簽引入的第三方庫或者在 Node.js 中通過 require 引入的內置模塊。
external 選項有兩個作用:
- 減小打包后文件的體積:如果某個模塊被指定為外部依賴,那么它不會被打包進最終的構建文件中,這樣可以減小打包后文件的體積,優化加載速度和性能。
- 避免重復打包:如果多個模塊都引用了同一個外部依賴,而且每個模塊都把這個依賴打包進了自己的構建文件中,那么就會造成代碼冗余和重復打包的問題。通過 external 選項,我們可以把這個外部依賴從多個模塊中剔除出來,只在最終的構建文件中打包一次,避免了代碼冗余和重復打包的問題。
在實際應用中,external 選項特別適用于打包一些常用的第三方庫或者框架,例如 React、Vue、Lodash 等,這些庫通常已經被廣泛使用,并且已經存在于用戶的瀏覽器或者 Node.js 環境中,所以沒有必要再把它們打包進構建文件中。
構建package.json
$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.See `npm help init` for definitive documentation on these fields
and exactly what they do.Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.Press ^C at any time to quit.
package name: (rollup)
version: (1.0.0)
description: rollup test unit
entry point: (index.js) src/main.js
test command:
git repository:
keywords:
author: vinca
license: (ISC)
About to write to D:\vinca\Rollup\package.json:{"name": "rollup","version": "1.0.0","description": "rollup test unit","main": "src/main.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1"},"author": "vinca","license": "ISC"
}Is this OK? (yes)
安裝一下vue3依賴,為后續引入package.json?排除vue模塊做鋪墊
$ npm install vueadded 20 packages, and audited 21 packages in 15s3 packages are looking for fundingrun `npm fund` for detailsfound 0 vulnerabilities
完善你的rollup.config.mjs文件內容?
import { createRequire } from 'node:module';
const require = createRequire(import.meta.url);
const pkg = require('./package.json');
console.log(pkg)const config = {input: 'src/main.js',output: {file: 'output/bundle.js',format: 'es'},external: Object.keys(pkg.dependencies)}
export default config
輸出日志說明:?
# pkg
{name: 'rollup',version: '1.0.0',description: 'rollup test unit',main: 'src/main.js',scripts: { test: 'echo "Error: no test specified" && exit 1' },author: 'vinca',license: 'ISC',dependencies: { vue: '^3.4.27' }
}# Object.keys(pkg.dependencies)
[ 'vue' ]
?
7、使用插件
可以看到第六點是使用createRequire方式使用package.json文件,那么現在我們準備將其優化
1、安裝依賴
將 @rollup/plugin-json 安裝到開發依賴中:
npm install --save-dev @rollup/plugin-json
我們使用 --save-dev 而不是 --save,因為我們的代碼在運行時實際上不依賴于插件,只有在打包時才需要。
2、更新main.js入口文件?
# main.js
import { version } from '../package.json';export default function () {console.log('version ' + version);
}
3、使用@rollup/plugin-json插件?
# rollup.config.mjs
import json from '@rollup/plugin-json';
import pkg from './package.json' assert { type: 'json' };
console.log(pkg)
const config = {input: 'src/main.js',output: {file: 'output/bundle.js',format: 'es'},plugins: [json()],external: Object.keys(pkg.dependencies)}
export default config
4、執行編譯
rollup -c
如果rollup.config.mjs不添加plugins: [json()]插件會出現編譯錯誤(無法識別json文件)?
# bundle.js
var version = "1.0.0";function main () {console.log('version ' + version);
}export { main as default };
【注意】結果中只導入了我們實際需要的數據 ——version?;package.json 中其他內容都被忽略了。這就是 除屑優化 的作用。
8、使用輸出插件(壓縮)
讓我們擴展上一個示例,生產一個壓縮文件和一個不壓縮文件。
1、安裝依賴
npm install --save-dev @rollup/plugin-terser
完成后,你的package.json > devDependencies 模塊,將是這樣的:
# package.json
"devDependencies": {"@rollup/plugin-json": "^6.1.0","@rollup/plugin-terser": "^0.4.4"
}
?
2、使用@rollup/plugin-terser插件
更新你的rollup.config文件,內容如下:
# rollup.config.mjs
import json from '@rollup/plugin-json';
import terser from '@rollup/plugin-terser';
import pkg from './package.json' assert { type: 'json' };
console.log(pkg)
const config = {input: 'src/main.js',output: [{file: 'output/bundle.js',format: 'es'},{file: 'output/bundle.min.js',format: 'iife',name: 'version',plugins: [terser()]}],plugins: [json()],external: Object.keys(pkg.dependencies)}
export default config
?
3、執行編譯
在終端編譯 rollup -c? 命令后,將產生一個壓縮文件bundle.min.js和一個非壓縮文件bundle.js
9、構建
在你的 package.json 中加入構建命令
# package.json
{"scripts": {"build": "rollup -c"}
}
執行操作
或通過命令行模式,執行 npm run build
$ npm run build> rollup@1.0.0 build
> rollup -csrc/main.js → output/bundle.js...
created output/bundle.js in 52ms
效果和上面執行rollup命令(rollup -c)一樣,這樣會在output目錄產生bundle.js文件