1. 程式人生 > 實用技巧 >Rollup.js: 開源JS庫的打包利器

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 檔案