Rollup.js: 開源JS庫的打包利器
前言
Rollup 是一個JavaScript模組打包器,說到模組打包器,自然就會想到webpack。webpack是一個現代JavaScript應用程式的靜態模組打包器,那麼在 webpack 已經成為前端構建主流的今天,為什麼還要用 Rollup 呢?
Rollup 中文文件中介紹到,它可以將小塊程式碼編譯成大塊複雜的程式碼,例如 library 或應用程式。可以看到它的應用場景之一,就是打包js庫。自己寫個js庫,在我們開發工作中和開源專案中還是比較常見的。可謂是生命不息,造輪子不止。如果還沒寫過,那就趕緊來提升下自己的技(逼)術(格)吧。
對比 webpack
用過 webpack 的都知道,它可以將所有的靜態資源,匯入到應用程式中,也是因為它強大的功能,所以打包 bundle 檔案時,會產生很多冗餘的程式碼,在大型的應用中,這點冗餘程式碼就會顯得微不足道,但是在一個小小的庫中,就會顯得比較明顯了。比如這麼一個類:
class People{
constructor(){
this.name = 'linxin'
}
getName(){ return this.name; }
}
export default People;
經過 webpack 打包之後,變成下面這樣(案例移除了具體內容),多出了很多方法,這顯然不是我們想要的。
/******/ (function(modules) { // webpackBootstrap
/******/ var installedModules = {};
/******/ function __webpack_require__(moduleId) { **** }
/******/ __webpack_require__.m = modules;
/******/ __webpack_require__.c = installedModules;
/******/ __webpack_require__.d = function(exports, name, getter) { *** };
/******/ __webpack_require__.r = function(exports) { *** };
/******/ __webpack_require__.t = function(value, mode) { *** };
/******/ __webpack_require__.n = function(module) { *** };
/******/ __webpack_require__.o = function(object, property) { *** };
/******/ __webpack_require__.p = "";
/******/ return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/******/ ([ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__);
class People{
const ructor(){
this.name = 'linxin'
}
getName(){
return this.name;
}
}
/* harmony default export */ __webpack_exports__["default"] = (People); }) ]);
而 Rollup 打包之後的程式碼跟原始碼基本一致,作為一個 JS 庫,我們還是希望簡潔一點,程式碼量少點。畢竟實現相同的功能,誰都不想去引入一個更繁重的庫吧。
特性
ES模組
Rollup 使用 ES6 的模組標準,而不像 CommonJS 和 AMD,雖然也叫模組化,其實只是一種臨時的解決方案。Rollup 的模組可以使我們開發時可以獨立的開發每個小模組,程式碼小而簡單,更加方便測試每個小模組,在構建時才打包成一個完成的 JS 庫。
Tree-shaking
tree shaking 指的是移除 JavaScript 上下文中的未引用程式碼,它依賴於 ES2015 模組系統中的靜態結構特性,例如 import 和 export。靜態結構的 import 就好像是變數引用一樣,不需要執行程式碼,在編譯時就可以確定它是否有引用到,如果沒引用,就不把該段程式碼打包進來。比如用到了一個第三方庫的一個功能,但我肯定不要把它完整的庫都打包進來,我只需要打包用到的程式碼即可,這時候 tree shaking 就可以發揮出它的作用了。
應用
開發一個 JS 庫,我需要 Rollup 能為我提供些常用的功能:
- 支援 ES6 轉 ES5
- 程式碼壓縮
- ESLint
- 支援 Typescript
基本配置
Rollup 使用一個 rollup.config.js 檔案進行配置。
// rollup.config.js
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'umd'
}
};
配置跟其他工具基本一致,從入口檔案 index.js 打包後輸出檔案 bundle.js。format 是生成包的格式,可選有amd,cjs,es,iife,umd,umd 是通用模組定義,打包後可以通過<script>標籤引入,也可以通過 import 等方式引入,作為一個 JS 庫要適用各個場景,應選擇 umd 。
babel
Rollup 通過外掛在打包的關鍵過程中更改行為,babel的外掛就是 rollup-plugin-babel,需要先安裝相關依賴
npmi rollup-plugin-babel@latest@babel/core@babel/preset-env -D
新建 .babelrc 檔案,配置 babel
{
"presets": ["@babel/preset-env"]
}
程式碼壓縮
npmi rollup-plugin-uglify -D
因為 rollup-plugin-uglify 無法壓縮 ES6 的語法,所以必須先用 babel 轉。如果想直接壓縮 ES6 的語法,可換成rollup-plugin-terser
ESLint
開發一個 JS 庫,不能亂七八糟,隨心所欲的寫程式碼,必須規範起來,當別人為你的開源庫做貢獻時,也必須遵循你的開發規範。安裝 ESLint 外掛
npmi rollup-plugin-eslint -D
然後初始化生成一個 ESLint 配置檔案./node_modules/.bin/eslint --init
那麼最終的 rollup.config.js 配置檔案如下:
import babel from 'rollup-plugin-babel';
import { uglify } from 'rollup-plugin-uglify';
import { eslint } from "rollup-plugin-eslint";
export default {
input: './index.js',
output: {
file: 'dist/bundle.js',
name: 'People',
format: 'umd'
},
plugins: [
eslint({
fix: true,
exclude: 'node_modules/**'
}),
babel({
exclude: 'node_modules/**'
}),
uglify()
]
};
TypeScript
如果使用 TypeScript 進行開發,則需要安裝 rollup-plugin-typescript2 外掛和相關依賴
npmi rollup-plugin-typescript2 typescript -D
然後初始化生成一個 tsconfig.js 配置檔案tsc --init,那麼使用 TypeScript 的打包檔案如下:
import typescript from 'rollup-plugin-typescript2';
export default {
input: './index.ts',
output: {
file: 'dist/bundle.js',
name: 'People',
format: 'umd'
},
plugins: [
typescript()
]
}
資源搜尋網站大全 http://www.szhdn.com 廣州VI設計公司https://www.houdianzi.com
外掛
除了以上用的這些外掛之外,還有一些可能根據專案需求也有需要
- rollup-plugin-commonjs:讓 Rollup 識別 commonjs 型別的包,預設只支援匯入ES6
- rollup-plugin-node-resolve:讓 Rollup 能識別 node_modules 中的包,引入第三方庫,預設識別不了的
- rollup-plugin-json:支援 json 檔案
- rollup-plugin-replace:支援字串替換
- rollup-plugin-sourcemaps:能生成 sourcemaps 檔案