Rollup.js是什麼?

做者:docoder@毛豆前端html

Overview

  • Rollup 是前端模塊化的一個打包工具,能夠將小塊代碼編譯成大塊複雜的代碼,例如 library 或應用程序。
  • Rollup 對代碼模塊能夠使用新的標準化格式,如:ES6,而不是先前的解決方案,如:CommonJS 和 AMD。
  • Rollup 被普遍用於 Javascript libraries 的打包

Quick Start

For the browser

# compile to a <script> containing a self-executing function ('iife')
$ rollup main.js --flie bundle.js --format iife
複製代碼

For Node.js

# compile to a CommonJS module ('cjs')
$ rollup main.js --file bundle.js --format cjs
複製代碼

For browsers and Node.js

# UMD format requires a bundle name
$ rollup main.js --file bundle.js --format umd --name "myBundle"
複製代碼

For es module

$ rollup ./src/main.js --file ./dist/bundle.js --format es
複製代碼

Why Rollup

Tree-shaking

  • 也稱爲:live code inclusionreact

  • 使用 Rollup 處理代碼模塊, 採用 ES6 標準(使用 import/export),能夠對模塊文件進行靜態分析,並能夠排除任何未實際使用的代碼webpack

  • 爲何 ES Module 要優於 CommonJSgit

    • ES Module 是官方標準,有一個直接清晰的發展方向
    • CommonJS 只是在 ES Module 出現以前的一個特殊的暫時性的傳統E標準
    • ES Module 能夠對文件進行靜態分析,進行 Tree-shaking 優化
    • ES Module 提供了更高級的特性,如,循環引用和動態綁定
    • Rollup ES6 modules Playgroup
// 使用 CommonJS,必須導入整個庫

// Import a full utils object using CommonJS
var utils = require( 'utils' );
var query = 'Rollup';
// Use the ajax method of the utils object
utils.ajax( 'https://api.example.com?search=' + query ).then( handleResponse );

// 使用 ES6 module,無須導入整個庫

// Import ajax function using the ES6 import statement
import { ajax } from 'utils';
var query = 'Rollup';
// Calling ajax function
ajax( 'https://api.example.com?search=' + query ).then( handleResponse );
複製代碼

Use Rollup in a CommonJS module

  • Rollup 堅決支持 ES module,CommonJS 沒有在 Rollup kernel 中。
  • 須要使用插件 rollup-plugin-commonjs ,來將其轉換爲 ES Module,前提還須要安裝和引入 rollup-plugin-node-resolve 插件,緣由是 Rollup 不一樣於 Webpack 和 Browserify,它不知道如何處理模塊中的依賴,因此 rollup-plugin-node-resolve 插件能夠告訴 Rollup 如何查找外部模塊。
  • 目前大部分的 npm 包都是以 commonjs 模塊形式出現的,以防萬一,仍是須要安裝和引入插件 rollup-plugin-commonjs 。另外,爲了防止其餘插件的改變破壞 commonjs 的檢測,rollup-plugin-commonjs 應該用在其餘插件轉換模塊以前。

Use it over Webpack ?

  • A number of open-source projects use it over Webpackgithub

  • Webpack 得到了巨大成功,每個月有百萬級的下載,賦能了成千上萬的網站和應用,有巨大的生態和資金支持,相比之下,Rollup 無足輕重web

  • Facebook 採用 Rollup 來實現 React 的 build process,merge 了大量 pull requestajax

  • Vue, Ember, Preact, D3, Three.js, Moment, and dozens of other well-known libraries also use Rolluptypescript

  • Rollup 以不一樣的目的被建立,Rollup 目的是要儘量的高效的構建扁平的可分配的 Javascript libraries,充分使用 ES Module 的優勢, 會將全部代碼放在同一個位置統一進行驗證,更快的生成更輕量級的代碼。Rollup 不支持 code-splittingHMR,並且處理 CommonJS 時須要插件。

  • Webpack 支持 code-splitting , 實現了一個瀏覽器友好的 require ,將每一個模塊一個接一個的驗證再打包。若是須要 on-demand loading,會很好;不然會形成性能浪費,尤爲若是打包大量模塊時,性能較差。

結論:

Use webpack for apps, and Rollup for libraries

  • 若是你須要 code-splitting,有不少 static assets,須要使用不少 CommonJS 依賴,使用 Webpack
  • 若是你的 codebase 是ES Module,寫一些給其餘人使用的代碼或庫,那麼使用 Rollup

pkg.module

  • 將來,ES Module ( importexport) 會使統一標準,庫的使用也會無縫。但如今不少瀏覽器以及 Node.js 不支持 importexport , 須要使用 UMD 或 CommonJS (Nodejs)
  • package.json 文件中增長 "module": "dist/my-library.es.js" , 能夠同時更好的支持 UMD 和 ES Module
  • Webpack 和 Rollup 都會利用 pkg.module 來儘量生成更高效的代碼, 在某些狀況下都會 tree-shaking

Example: Create a Typescript and React Module

ALL JS LIBRARIES SHOULD BE AUTHORED IN TYPESCRIPT

Install

$ yarn add typescript rollup rollup-plugin-typescript2 rollup-plugin-commonjs  rollup-plugin-peer-deps-external rollup-plugin-node-resolve --dev

$ yarn add react @types/react --dev
$ yarn add react-dom @types/react-dom --dev
複製代碼

tsconfig.json

{
  "compilerOptions": {
    "outDir": "build",
    "module": "esnext",
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "sourceMap": true,
    "allowJs": false,
    "jsx": "react",
    "declaration": true, // 自動生成 .d.ts
    "moduleResolution": "node",
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "resolveJsonModule": true,
    "downlevelIteration": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true
  },
  "include": ["src"], // 查找 ts 文件路徑
  "exclude": ["node_modules", "build"] // 排出路徑避免 build
}
複製代碼

rollup.config.js

import typescript from "rollup-plugin-typescript2";
import commonjs from "rollup-plugin-commonjs";
import external from "rollup-plugin-peer-deps-external";
import resolve from "rollup-plugin-node-resolve";

import pkg from "./package.json";

export default {
  input: "src/index.tsx",
  output: [
    {
      file: pkg.main,
      format: "cjs",
      // exports: "named",
      sourcemap: true
    },
    {
      file: pkg.module,
      format: "es",
      // exports: "named",
      sourcemap: true
    }
  ],
  external: [
    ...Object.keys(pkg.dependencies || {}),
    ...Object.keys(pkg.peerDependencies || {})
  ],
  plugins: [
    commonjs({  // 置於最前 ( 不然可能須要配置 namedExports 才能阻止保錯 )
      include: ["node_modules/**"],
    }),
    external(),
    resolve(),
    typescript({
      rollupCommonJSResolveHack: true,
      exclude: "**/__tests__/**",
      clean: true
    })
  ]
};
複製代碼

package.json

{
  "name": "...",
  "version": "...",
  "description": "...",
  "author": "...",
  "main": "build/index.js",
  "module": "build/index.es.js", // pkg.module
  "jsnext:main": "build/index.es.js",
  "types": "build/index.d.ts",
  "license": "...",
  "repository": "...",
  "keywords": ['...', '...'],
  "scripts": {
    "build": "rollup -c",
    "start": "rollup -c -w",
    "prepare": "npm run build" // npm publish 時會先調用進行打包
  },
  "files": [ // 僅 build 文件夾被打包進庫裏
    "build"
  ],
  "peerDependencies": {
    "react": ">=16.8.0",
    "react-dom": ">=16.8.0"
  },
  "dependencies": {
    ...
  },
  "devDependencies": {
    "@types/react": "^16.8.23",
    "@types/react-dom": "^16.8.4",
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "rollup": "^1.16.6",
    "rollup-plugin-commonjs": "^10.0.1",
    "rollup-plugin-node-resolve": "^5.2.0",
    "rollup-plugin-peer-deps-external": "^2.2.0",
    "rollup-plugin-typescript2": "^0.21.2",
    "typescript": "^3.5.2"
  }
}
複製代碼

Developing locally

# 在開發的庫文件目錄下
$ yarn link # 會在全局生成一個 link 文件 (如:.nvm/versions/node/v10.15.3/lib/node_modules/your-package-name),link 到此庫文件目錄

# 在要使用庫的 example project 文件目錄下
$ yarn link your-package-name # link 到全局的 link 文件,從而又 link 到開發的庫文件目錄

# Fix Duplicate React: https://github.com/facebook/react/issues/15315#issuecomment-479802153
$ npm link ../example/node_modules/react
複製代碼
相關文章
相關標籤/搜索