使用 rollup 打包 JS

前言

rollup 採用 es6 原生的模塊機制進行模塊的打包構建,rollup 更着眼於將來,對 commonjs 模塊機制不提供內置的支持,是一款更輕量的打包工具。rollup 比較適合打包 js 的 sdk 或者封裝的框架等,例如,vue 源碼就是 rollup 打包的。而 webpack 比較適合打包一些應用,例如 SPA 或者同構項目等等。html

建立項目

目錄結構是這樣的:vue

hey-rollup/
├── dist
│   ├── bundle-name.js
│   └── bundle-name.min.js
├── example
│   ├── dist
│   │   └── example.js
│   ├── index.html
│   └── index.js
├── package-lock.json
├── package.json
├── rollup.config.js
├── src
│   └── index.js
└── test
    └── index.js
複製代碼

你能夠在你的終端中執行下面的命令來安裝此項目node

# cd /path/to/your/projects
git clone https://github.com/daixwu/hey-rollup.git
複製代碼

安裝 Rollup

經過下面的命令安裝 Rollup:webpack

npm install --save-dev rollup
複製代碼

建立配置文件

在 hey-rollup 文件夾中建立一個新文件 rollup.config.js。以後在文件中添加下面的內容:git

export default {
  input: "src/main.js",
  output: {
    file: "dist/js/main.min.js",
    format: "umd",
    name: 'bundle-name'
  }
};
複製代碼

下面是每個配置選項都作了些什麼:es6

  • input —— 要打包的文件github

  • output.file —— 輸出的文件 (若是沒有這個參數,則直接輸出到控制檯)web

  • output.format —— Rollup 輸出的文件類型 (amd, cjs, es, iife, umd)npm

    • amd – 異步模塊定義,用於像 RequireJS 這樣的模塊加載器json

    • cjs – CommonJS,適用於 Node 和 Browserify/Webpack

    • es – 將軟件包保存爲 ES 模塊文件

    • iife – 一個自動執行的功能,適合做爲<script>標籤。(若是要爲應用程序建立一個捆綁包,您可能想要使用它,由於它會使文件大小變小。)

    • umd – 通用模塊定義,以 amd,cjs 和 iife 爲一體

  • output.name --生成包名稱,表明你的 iife/umd 包,同一頁上的其餘腳本能夠訪問它(iife/umd 沒有 name 會報錯的)

搭配 babel 7

rollup 的模塊機制是 ES6 Modules,但並不會對 es6 其餘的語法進行編譯。所以若是要使用 es6 的語法進行開發,還須要使用 babel 來幫助咱們將代碼編譯成 es5。

安裝模塊

rollup-plugin-babel 將 rollup 和 babel 進行了完美結合。

npm install --save-dev rollup-plugin-babel@latest
複製代碼

建立 .babelrc

{
    "presets": [
      [
        "@babel/preset-env",
        {
          "modules": false
        }
      ]
    ]
}
複製代碼

更新 rollup.config.js

import babel from "rollup-plugin-babel";

export default {
  plugins: [
    babel({
      exclude: 'node_modules/**',
    }),
  ],
};
複製代碼

爲了不轉譯第三方腳本,咱們須要設置一個 exclude 的配置選項來忽略掉 node_modules 目錄

babel 7 必要模塊

npm install --save-dev @babel/core

npm install --save-dev @babel/preset-env
複製代碼

ESLint 檢查

在你的代碼中使用 linter 無疑是十分好的決定,由於它會強制執行一致的編碼規範來幫助你捕捉像是漏掉了括弧這種棘手的 bug。

在這個項目中,咱們將會使用 ESLint。

安裝模塊

爲了使用 ESLint,咱們將要安裝 ESLint Rollup plugin

npm install --save-dev rollup-plugin-eslint
複製代碼

生成一個 .eslintrc.json

爲了確保咱們只獲取咱們想要的錯誤,咱們須要首先配置 ESLint。這裏能夠經過下面的代碼來自動生成大多數配置:

./node_modules/.bin/eslint --init
複製代碼

更新 rollup.config.js

接下來,import ESLint 插件並將它添加到 Rollup 配置中:

import eslint from 'rollup-plugin-eslint';

export default {
  plugins: [
    eslint({
      exclude: [
        throwOnError: true,
        throwOnWarning: true,
        include: ['src/**'],
        exclude: ['node_modules/**']
      ]
    }),
  ],
};
複製代碼

eslint插件有兩個屬性須要說明:throwOnError 和 throwOnWarning 設置爲 true 時,若是在 eslint 的檢查過程當中發現了 error 或warning,就會拋出異常,阻止打包繼續執行(若是設置爲false,就只會輸出eslint檢測結果,而不會中止打包)

兼容 commonjs

npm 生態已經繁榮了多年,commonjs 規範做爲 npm 的包規範,大量的 npm 包都是基於 commonjs 規範來開發的,所以在完美支持 es6 模塊規範以前,咱們仍舊須要兼容 commonjs 模塊規範。

rollup 提供了插件 rollup-plugin-commonjs,以便於在 rollup 中引用 commonjs 規範的包。該插件的做用是將 commonjs 模塊轉成 es6 模塊。

rollup-plugin-commonjs 一般與 rollup-plugin-node-resolve 一同使用,後者用來解析依賴的模塊路徑。

安裝模塊

npm install --save-dev rollup-plugin-commonjs rollup-plugin-node-resolve
複製代碼

更新 rollup.config.js

import babel from 'rollup-plugin-babel';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';

export default {
  plugins: [
    resolve({
      jsnext: true,
      main: true,
      browser: true,
    }),
    commonjs(),
    babel({
      exclude: 'node_modules/**',
    }),
  ],
};
複製代碼

注意: jsnext 表示將原來的 node 模塊轉化成 ES6 模塊,main 和 browser 則決定了要將第三方模塊內的哪些代碼打包到最終文件中。

替代環境變量

安裝模塊

rollup-plugin-replace 本質上是一個用來查找和替換的工具。它能夠作不少事,但對咱們來講只須要找到目前的環境變量並用實際值來替代就能夠了。(例如:在 bundle 中出現的全部 ENV 將被 "production" 替換)

npm install --save-dev rollup-plugin-replace
複製代碼

更新 rollup.config.js

配置很簡單:咱們能夠添加一個 key:value 的配對錶,key 值是準備被替換的鍵值,而 value 是將要被替換的值。

import replace from "rollup-plugin-replace";

export default {
  plugins: [
    replace({
      ENV: JSON.stringify(process.env.NODE_ENV)
    })
  ]
};
複製代碼

在咱們的配置中找到每個 ENV 並用 process.env.NODE_ENV 去替換,JSON.stringify 用來確保值是雙引號的,不像 ENV 這樣。

壓縮 bundle

添加 UglifyJS 能夠經過移除註上釋、縮短變量名、重整代碼來極大程度的減小 bundle 的體積大小 —— 這樣在必定程度下降了代碼的可讀性,可是在網絡通訊上變得更有效率。

安裝插件

用下面的命令來安裝 rollup-plugin-uglify

npm install --save-dev rollup-plugin-uglify
複製代碼

更新 rollup.config.js

接下來,讓咱們在 Rollup 配置中添加 Uglify 。然而,爲了在開發中使代碼更具可讀性,讓咱們來設置只在生產環境中壓縮混淆代碼:

import uglify from "rollup-plugin-uglify";

export default {
  plugins: [
    process.env.NODE_ENV === "production" && uglify()
  ]
};
複製代碼

這裏使用了短路計算策略,只有在 NODE_ENV 設置爲 production 時加載 uglify()。

完整配置

最後附上個人 rollup.config.js 配置

import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import { eslint } from 'rollup-plugin-eslint';
import babel from 'rollup-plugin-babel';
import replace from 'rollup-plugin-replace';
import { uglify } from 'rollup-plugin-uglify';

const packages = require('./package.json');

const ENV = process.env.NODE_ENV;

const paths = {
    input: {
        root: ENV === 'example'
            ? 'example/index.js'
            : 'src/index.js',
    },
    output: {
        root: ENV === 'example'
            ? 'example/dist/'
            : 'dist/',
    },
};

const fileNames = {
    development: `${packages.name}.js`,
    example: `example.js`,
    production: `${packages.name}.min.js`
};

const fileName = fileNames[ENV];

export default {
    input: `${paths.input.root}`,
    output: {
        file: `${paths.output.root}${fileName}`,
        format: 'umd',
        name: 'bundle-name'
    },
    plugins: [
        resolve(),
        commonjs(),
        eslint({
            include: ['src/**'],
            exclude: ['node_modules/**']
        }),
        babel({
            exclude: 'node_modules/**',
            runtimeHelpers: true,
        }),
        replace({
            exclude: 'node_modules/**',
            ENV: JSON.stringify(process.env.NODE_ENV),
        }),
        (ENV === 'production' && uglify()),
    ],
};
複製代碼

參考資料

rollup.js wiki zh

如何經過 Rollup.js 打包 JavaScript

rollup打包js的注意點

babel 7 教程

S打包工具rollup——徹底入門指南

相關文章
相關標籤/搜索