Rollup
簡介
Rollup 是一個模塊打包工具, 可以將我們按照 ESM (ES2015 Module) 規范編寫的源碼構建輸出如下格式:
- IIFE: 自執行函數, 可通過
<script>
標簽加載 - AMD: 通過
RequireJS
加載 - CommonJS: Node 默認的模塊規范, 可通過
Webpack
加載 - UMD: 兼容 IIFE, AMD, CJS 三種模塊規范
- ESM: ES2015 Module 規范, 可用
Webpack
,Rollup
加載
優點:
支持動態導入。
支持tree shaking。僅加載模塊里用得到的函數以減小文件大小。
Scope Hoisting。 rollup可以將所有小文件生成到一個大文件中,所有代碼都在同一個函數作用域里:, 不會像 Webpack 那樣用很多函數來包裝模塊。
沒有其他冗余代碼, 執行很快。除了必要的 cjs
, umd
頭外,bundle 代碼基本和源碼差不多,也沒有奇怪的 __webpack_require__
, Object.defineProperty
之類的東西,
缺點:
不支持熱更新功能;對於commonjs模塊,需要額外的插件將其轉化為es2015供rollup 處理;無法進行公共代碼拆分。
輸入:
options.input 單/多文件入口點
輸出:
rollup支持生成 iife、cjs、amd 、esm、umd格式的文件; 單/多js文件輸出
文件資源處理:
rollup 通過插件來編譯處理各類靜態資源:
- rollup-plugin-typescript2
- rollup-plugin-babel
- rollup-plugin-uglify
- rollup-plugin-commonjs
- rollup-plugin-postcss
- rollup-plugin-img
- rollup-plugin-json
基本使用參考
https://www.cnblogs.com/tugenhua0707/p/8179686.html
適用場景:
由純js開發的第三方庫; 需要生成單一的umd文件的場景
案例:
純js/ts編寫的第三方庫:
React、Vue
UI組件庫 evergreen
使用 babel 將 js/ts 編譯成 esm 和 cjs 格式的模塊文件, 使用 rollup 將庫打包成 umd 格式的 evergreen.min.js 和 evergreen.js , 打包出來的代碼比較干凈。
使用rollup打包TypeScript的SDK項目
項目目錄:
初始化項目
npm init -y
安裝 項目依賴
npm install --save-dev @babel/core @babel/plugin-external-helpers @babel/preset-env @babel/preset-typescript cross-env rollup rollup-plugin-babel @babel/plugin-transform-runtime @rollup/plugin-commonjs @rollup/plugin-json @rollup/plugin-node-resolve @types/jest @types/node babel-preset-latest jest rollup-plugin-replace rollup-plugin-terser rollup-plugin-uglify ts-jest ts-node
package.json 的內容如下
{ "name": "xcplayer", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "jest", "dev": "cross-env NODE_ENV=development rollup -c -w", "build": "cross-env NODE_ENV=production rollup -c", "build-dev": "cross-env NODE_ENV=development rollup -c", "unit": "jest --coverage" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "typescript": "^4.5.4" }, "devDependencies": { "@babel/core": "^7.16.7", "@babel/plugin-external-helpers": "^7.16.7", "@babel/plugin-transform-runtime": "^7.16.8", "@babel/preset-env": "^7.16.8", "@babel/preset-typescript": "^7.16.7", "@rollup/plugin-commonjs": "^21.0.1", "@rollup/plugin-json": "^4.1.0", "@rollup/plugin-node-resolve": "^13.1.3", "@types/jest": "^27.4.0", "@types/node": "^17.0.8", "babel-preset-latest": "^6.24.1", "cross-env": "^7.0.3", "jest": "^27.4.7", "rollup": "^2.63.0", "rollup-plugin-babel": "^4.4.0", "rollup-plugin-replace": "^2.2.0", "rollup-plugin-terser": "^7.0.2", "rollup-plugin-uglify": "^6.0.4", "ts-jest": "^27.1.2", "ts-node": "^10.4.0" } }
創建 rollup.config.js 可根據具體需求修改
import commonjs from "@rollup/plugin-commonjs" import json from "@rollup/plugin-json" import { nodeResolve } from "@rollup/plugin-node-resolve" // 告訴rollup去哪里找依賴庫 import babel from "rollup-plugin-babel" import replace from "rollup-plugin-replace" import { terser } from "rollup-plugin-terser" // 壓縮 const pkg = require("./package.json") // Version const pkgVersion = process.env.NODE_ENV === "production" ? pkg.version : `${pkg.version}_beta` // Name of package const pkgName = pkg.name // banner const banner = "/*!\n" + ` * xrtc.js v${pkgVersion}\n` + ` * (c) 2020-${new Date().getFullYear()} \n` + " * Released under the MIT License in iflytek.\n" + " */\n" const isProduction = process.env.NODE_ENV === "production" const destFolder = isProduction ? "dist" : "demo/lib" const output = isProduction ? [ { file: `./${destFolder}/${pkgName}-${pkgVersion}.js`, format: "umd", // 模塊輸出格式:es、cjs、amd、umd、iife、system name: "XRTC", // 指定打包后模塊的輸出結果接收變量 globals: { crypto: "crypto", }, banner: banner, }, { file: `./${destFolder}/${pkgName}-${pkgVersion}.esm.js`, format: "esm", // 模塊輸出格式:es、cjs、amd、umd、iife、system name: "XRTC", // 指定打包后模塊的輸出結果接收變量 globals: { crypto: "crypto", }, banner: banner, }, ] : [ { file: `./${destFolder}/${pkgName}.js`, format: "esm", // 模塊輸出格式:es、cjs、amd、umd、iife、system name: "XRTC", // 指定打包后模塊的輸出結果接收變量 globals: { crypto: "crypto", }, banner: banner, }, ] const extensions = ["*", ".js", ".ts"] const configuration = { input: "./src/index.ts", output, plugins: [ json({ namedExports: false, }), nodeResolve({ extensions, }), babel({ exclude: "node_modules/**", // 排除node_modules 下的文件 runtimeHelpers: true, extensions, }), commonjs({ sourceMap: true, }), replace({ ENV: JSON.stringify(process.env.NODE_ENV), __VERSION__: JSON.stringify(pkgVersion), }), ], } if (isProduction) { const { terser } = require("rollup-plugin-terser") const output = configuration.output.map((output) => { const buildOutput = Object.assign({}, output) buildOutput.file = buildOutput.file.replace(/\.js$/, ".min.js") buildOutput.plugins = [ terser({ module: true, compress: { ecma: 2015, pure_getters: true, }, }), ] return buildOutput }) configuration.output = [...configuration.output, ...output] } export default configuration
添加.babelrc文件
{ "presets": ["@babel/preset-env", "@babel/preset-typescript"], "plugins": [ [ "@babel/plugin-transform-runtime" ] ] }
添加jest.config.js 文件(前端自動化測試 - Jest基礎配置篇) npx jest --init