# rollup.js 快速入門

---
### 為什麼我需要 Rollup
* 我有很多工具類的函式
* 想要以 ES6 模組化的方式開發
* 要能打包成一支 JS
* 要支援各種模組環境都能使用的格式
* 可按需引入函式庫 (Tree-Shaking)
---
### Rollup 剛好都符合我的需求
* JavaScript 模組打包工具
* Rollup 使用 ES6 版本模組標準
* 可將多個小的程式片段編譯為函式庫和應用
* 可輸出 IIFE、CommonJS、ESM、UMD…等
* 支援 Tree-Shaking
---
### Rollup 與 Webpack 有什麼區別?
---
### Rollup 更輕量
rollup 產生的程式碼並不會像 webpack 一樣被注入大量的內部結構,相對來說更加精簡,保持原有程式碼的狀態。
---
### Rollup 更好地支持 tree-shaking
由於 rollup 是基於 ES6 模組標準來進行打包,擁有演算法優勢上的支持。因此更好地支持 tree-shaking,可以將沒有被使用到的程式碼進行消除,從而減小代碼體積。
---
### Rollup 的生態系統不如 webpack 強大
相對於 webpack,rollup 的插件生態系統相對較小,目前它仍然是一個小眾的打包工具。
但是 Vite 就是使用 rollup 來打包 production 環境。
---
### Rollup 沒有 devServer
Rollup 沒有官方的 devServer 工具,這可能需要使用其他的工具來替代。
---
### Webpack 的優勢
對於程式碼分割 (Code-splitting) 和靜態資源 (Static assets) 導入具有先天優勢,並且支持熱模組替換 (HMR)。
---
### Rollup 的優勢
由於 Rollup 不會將整個應用程式打包成一個文件,因此它更適合用於打包函式庫,可以將多個小的代碼片段編譯為完整的函式庫和應用。
---
### 該怎麼選?
Use webpack for apps, and Rollup for libraries
對於`應用程式`使用 `Webpack`,
對於`函式庫`使用 `Rollup`,
以上是一個很好的經驗法則,
但這不是一個絕對的規則。
---
## 比較有無模組的程式碼

---
### JS 模組的種類
ESM、CommonJS、AMD、UMD
---
### ESM
```javascript=
// 檔案:log.js
const log = () => {
console.log('ES module system')
}
export default log
// 檔案:index.js
import log from './log'
log()
```
* 匯入時可以繫結原值(非複製)
* 使用 import 匯入,export 匯出
* 靜態解析 - 可以在編譯時匯入/匯出時確定載入的程式碼
* Tree shaking
---
### CommonJS (Node.js)
```javascript=
// 檔案:log.js
function log () {
console.log('CJS module system')
}
module.exports = { log }
// 檔案:index.js
var logger = require('./log')
logger.log()
```
* 使用 require 來載入模組
* 使用 module.exports 來匯出模組
* 當我們匯入模組時,實際上是取得一個物件
* 不支援 tree shaking
---
### AMD
```javascript=
// 檔案:log.js
define(['log'], function () {
return {
log: function () { console.log('AMD module system')}
}
})
// 檔案:index.js
require(['log'], function (logger) {
logger.log()
})
```
* 使用 RequireJS 實作
* 常用於瀏覽器(客戶端),當我們需要動態載入模組的時候適合使用
* 使用 require 來匯入
---
### UMD
```javascript=
(function (global, factory) {
if (typeof define === 'function' && define.amd) {
define(['exports'], factory)
} else if (typeof exports !== 'undefined') {
factory(exports)
} else {
var mod = {
exports: {}
}
factory(mod.exports)
global.log = mod.exports
}
})(this, function (exports) {
"use strict";
function log () {
console.log('Example of UMD module system')
}
exports.log = log
})
```
* 結合 CommonJS + AMD
* 支援全域變數的方式。
---
### Rollup 實作時間
---
### 建立一個 JS 專案
```bash=
example-lib/
├── dist/
├── src/
│ └── index.js
└── package.json
```
---
### 安裝 Rollup
```bash=
$ npm install --save-dev rollup
```
---
### 建立 rollup.config.js
```javascript=
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'iife'
}
};
```
---
### 設定說明
* input - 定義函式庫或應用程式的進入點
* output.file - 輸出打包模組的檔案名稱
* output.format - 輸出打包模組的檔案格式
* 瀏覽器環境可用 `iife`
* ES6環境可用 `es`
* Node.js 環境可用 `cjs`
* 瀏覽器與 Node.js 環境通用可用 `umd`
---
### 編譯模組
在 package.json 中的 scripts 的加入
```json=
{
"scripts": {
"build": "rollup -c"
}
}
```
上述 `-c` 為選項 `--config` 的簡寫,代表使用 rollup.config.js 的配置進行打包處理。
---
### 執行打包命令
```bash=
$ npm run build
```
打包好的模組會輸出至 dist/bundle.js
---
### 使用插件
Rollup 提供了許多豐富的 [plugins](https://github.com/rollup/plugins)
列舉比較常用的幾項:
* [rollup-plugin-node-resolve](https://github.com/rollup/plugins/tree/master/packages/commonjs):
允許載入 node_modules 模組
* [rollup-plugin-commonjs](https://github.com/rollup/rollup-plugin-commonjs):
將 CommonJS 模組轉換至 ES6
* [rollup-plugin-terser](https://github.com/TrySound/rollup-plugin-terser):
將打包的檔案進行 minify 處理
---
### 使用樣版快速建立 Library
https://github.com/cgh20xx/rollup-lib-template
---
Thank You
{"metaMigratedAt":"2023-06-18T02:00:21.365Z","metaMigratedFrom":"YAML","title":"rollup.js 快速入門","breaks":true,"contributors":"[{\"id\":\"4c53a2bf-2bd7-4fea-a91b-a4a27944df83\",\"add\":5082,\"del\":1245}]"}