本文檔地址javascript
本文引用參考文檔地址html
Rollup 是一個 JavaScript 模塊打包器,能夠將小塊代碼編譯成大塊複雜的代碼,例如 library 或應用程序。java
Rollup 對代碼模塊使用新的標準化格式,這些標準都包含在 JavaScript 的 ES6 版本中,而不是之前的特殊解決方案,如 CommonJS 和 AMD。ES6 模塊可使你自由、無縫地使用你最喜好的 library 中那些最有用獨立函數,而你的項目沒必要攜帶其餘未使用的代碼。ES6 模塊最終仍是要由瀏覽器原生實現,但當前 Rollup 可使你提早體驗。node
Rollup
着眼於將來,採用原生的ES
標準的模塊機制進行構建,將來ES
規範確定會由瀏覽器實現,也是JavaScript語言明確的發展方向。機制更加優於CommonJS
webpack
CommonJS
是在ES
規範以前被提出的一種暫時性性解決方案,是一種特殊的傳統格式,git
相比較ES
模塊容許進行靜態分析,從而實現像 tree-shaking 的優化,並提供諸如循環引用和動態綁定等高級功能github
Tree-shaking
, 也被稱爲 "live code inclusion," 它是清除實際上並無在給定項目中使用的代碼的過程,可是它能夠更加高效。web
打包工具 | 體積 | 注入代碼 | code spliting | dynamic import | Tree-shaking |
---|---|---|---|---|---|
webpack | large | more | ✅ | ✅ | ❌ |
rollup | small | less | ❌ | ❌ | ✅ |
webpack 是一款強大的 bundle
構建工具,經過 loader
機制能夠處理各類類型的文件,良好的 code splitting
和dynamic import
支持使得webpack
成爲了應用程序,單頁應用的全能型的的打包工具。npm
可是由於其打包體積相對較大,注入代碼更多,沒有良好的Tree-shaking
因此在Library
的打包工做中,不如rollup
打包的精簡。json
rollup
定位是一款輕量級的構建工具,其配置也相對很簡單,可是因爲不支持CommonJs
,在配置rollup-plugin-commonjs
將CommmonJS
轉化成ES
模塊方式的時候,須要配置babel
轉譯
因爲babel 7+
升級改動比較大,命名空間改動,市面上的教程大部分說的不夠清楚,並且基本上停留在babel 6
的配置,致使一直拋(plugin commonjs) SyntaxError: Unexpected token
在後文中會着力介紹這個部分,分析babel 7+
配置以及各個presets
和plugins
的做用。
npm install --save-dev rollup
複製代碼
在項目根目錄建立rollup.config.js
文件。
rollup
配置比較的簡潔,通常包括input
,output
,plugins
,external
這是一段簡單的配置文件
export default {
input: 'src/index.js',
output: {
name: 'amapUpper',
file: 'dist/amapUpper.js',
format: 'umd' //兼容模式
},
external: ['@amap/amap-jsapi-loader'],// 配置引入的包是否要打包,在這裏配置的會忽略掉,不打包到咱們的程序裏面
plugins: []
};
複製代碼
當你的配置文件須要配置多個打包策略的時候,你還能夠這樣配置
export default [{
input: 'main-a.js',
output: {
file: 'dist/bundle-a.js',
format: 'cjs'
}
}, {
input: 'main-b.js',
output: [
{
file: 'dist/bundle-b1.js',
format: 'cjs'
},
{
file: 'dist/bundle-b2.js',
format: 'es'
}
]
}]
複製代碼
你還可使用多個配置文件,使用--config
來使用配置文件
# pass a custom config file location to Rollup
rollup --config my.config.js
複製代碼
::: danger 使用了umd
模式必須指定 Name for UMD export
:::
配置gollup 的plugin 相似babel 所有移植到了@rollup
下,在官方提供的 一站式配置商店,能夠下載所需的插件, 做用在於可維護學習被誤導成本下降,更有利於長期維護。
rollup plugin
是一個遵循rollup
插件規範的object
,通常經過一個工廠函數返回一個對象實現
一段簡單的示例:
export default function myExample () {
return {
name: 'my-example', // this name will show up in warnings and errors
resolveId ( source ) {
if (source === 'virtual-module') {
return source; // this signals that rollup should not ask other plugins or check the file system to find this id
}
return null; // other ids should be handled as usually
},
load ( id ) {
if (id === 'virtual-module') {
return 'export default "This is virtual!"'; // the source code for "virtual-module"
}
return null; // other ids should be handled as usually
}
};
}
複製代碼
而後在配置文件中引用該插件,在plugins中,傳入執行返回的對象
import myExample from 'myExample'
plugins: [ myExample() ]
複製代碼
A Rollup plugin is an object with one or more of the properties
, build hooks
, and output generation hooks
熟悉webpack loader
機制的都應該知道loader
其實是從右到左,自下而上執行的,在頁頭的 rollup打包js的注意點 裏面提到的錯誤記錄/錯誤2裏面,類比webpack loader
機制, 實際上是一個錯誤的類比,實際上rollup
的plugin
機制是從左往右,自上而下而下的執行順序。
一個測試例子
// rollup.config.js
function myExample1() {
return {
name: 'my-example1', // this name will show up in warnings and errors
resolveId(source) {
console.log('111 resolve_______________-------------------------------------------');
return null; // other ids should be handled as usually
},
load(id) {
console.log('111 load_______________-------------------------------------------');
return null; // other ids should be handled as usually
}
};
}
function myExample2() {
return {
name: 'my-example1', // this name will show up in warnings and errors
resolveId(source) {
console.log('222 resolve_______________-------------------------------------------');
return null; // other ids should be handled as usually
},
load(id) {
console.log('222 load_______________-------------------------------------------');
return null; // other ids should be handled as usually
}
};
}
export default {
input: 'src/index.js',
output: {
name: 'test',
file: 'dist/test.js',
format: 'umd'
},
plugins: [
myExample1(),
myExample2()
]
};
複製代碼
能夠看到load
,resolve
鉤子函數都是從左往右,自上而下而下的執行順序。
下面介紹正常打包中須要用到的插件,和通常配置。
@rollup/plugin-json
原rollup-plugin-json
@rollup/plugin-commonjs
原rollup-plugin-commonjs
@rollup/plugin-node-resolve
原rollup-plugin-node-resolve
rollup-plugin-terser
首先,須要做爲開發依賴安裝這些插件
npm i @rollup/plugin-json -D
npm i @rollup/plugin-commonjs -D
npm i @rollup/plugin-node-resolve -D
npm i rollup-plugin-terser -D
複製代碼
而後須要引用配置文件
import json from '@rollup/plugin-json';
import commonjs from '@rollup/plugin-commonjs';
import nodeResolve from '@rollup/plugin-node-resolve';
import babel from 'rollup-plugin-babel';
import { terser } from 'rollup-plugin-terser';
export default {
...
plugins: [
json(),
terser(),
nodeResolve(),
commonjs(),
babel({
exclude: '*', // 排除node_modules 下的文件
runtimeHelpers: true // 防止生成多個 打包helper 函數
}),
]
};
複製代碼
在跟着 rollup 搭建打包 JS 一文配置的過程當中,用到的插件不是官方一站式插件提供的長期維護版本,遇到了 rollup-plugin-commonjs
插件打包報錯的問題
針對使用了放棄維護的rollup-plugin-commonjs
插件的打包拋出的這個SyntaxError
,能夠有兩種解決方案。推薦方案二。
查找了不少資料都顯示,應該是babel
配置問題,主要分爲:
babel
配置問題babel
轉譯執行順序問題綜合這些資料,這個報錯應該是因爲該commonjs 插件庫 被移動到 @rollup/plugin-commonjs
下維護,致使非長期維護版本缺乏某些轉譯後的輔助函數,屬性,致使拋出異常。
因此須要babel
輔助編譯以後才能正確執行commonjs
插件。
babel 配置的一些問題
因爲babel 7+
版本中,將babel 的各個庫所有移植到了@babel/***
下統一官方維護,而市面上大部分的babel
教程實際上沒有對這點進行詳細說明,並且教程裏安裝babel
組件的時候並無指定版本,實際上致使可能安裝了7+ 版本的babel
核心庫,而安裝了放棄維護的babel-plugins-***
下的插件預設之類的。就會致使一系列的問題。
這裏要注意一下這個@
這個符號,這個是隻有babel7
才特有的,babel6
都木有,市面上大量代碼都是基於6的因此要特別注意,安裝的時候要使用 npm install i -S @babel\cli
而不能是npm install i -S babel-cli
了 這是 babel 7
的一大調整,原來的 babel-xx
包統一遷移到babel
域 下 - 域由 @
符號來標識
參閱文章開頭提到的 babel 7 的使用的我的理解
配置
因爲這裏使用@rollup/plugin-babel
,執行babel
轉譯 因此不須要安裝@babel/cli
命令行工具。
首先咱們須要安裝:
@babel/core
@babel/preset-env
@babel/runtime
@babel/plugin-transform-runtime
npm i -D @babel/core
npm i -D @babel/preset-env
npm i -D @babel/runtime
npm i -D @babel/plugin-transform-runtime
複製代碼
而後在項目根目錄下建立.babelrc
的配置文件
{
"presets": [
[
"@babel/preset-env",
{
"modules": false,
"targets": {
"browsers": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}
}
]
],
"plugins": ["@babel/plugin-transform-runtime"]
}
複製代碼
而後若是你用的是rollup-plugin-commonjs
很是期維護版本的插件的話,因爲和babel
有依賴關係,你須要:
在commonjs
插件以前引入babel
插件,並配置須要匹配編譯的文件,目錄。和編譯配置
// rollup.config.js
export default {
input: 'src/index.js',
output: {
name: 'amapUpper',
file: 'dist/amapUpper.js',
format: 'umd'
},
plugins: [
babel({
exclude: '/node_modules/**', // 排除node_modules 下的文件
runtimeHelpers: true // 與plugin-transform-runtime 插件對應配置,生成統一化helper。
}),
commonjs()
]
};
複製代碼
使用rollup
新的官方提供的移動後的一站式插件庫裏面的插件
使用了新的插件庫以後,babel
仍是須要配置的,只是解決了commonjs
插件依賴babel
的問題。
而babel 其實是解決各類瀏覽器,引擎之間的差別,而存在的。因此爲了更好的支持,須要配備良好的babel配置。
歡迎各位看官大佬們點贊,糾錯。