Rollup同樣是一款ES Module打包器,從作用來看,Rollup與Webpack很相似,但Rollup更為小巧,僅僅是一款ESM打包器;比如Rollup中不不支持類似的HMR這種高級特性
Rollup是為了提供一個充分利用ESM各項特性的高效(結(jié)構(gòu)比較扁平,性能比較出眾的類庫)打包器
Rollup快速上手
安裝rollup模塊yarn add rollup --dev
在node_modules/.bin目錄就會有rollup.cmd,通過yarn rollup就可以直接使用
yarn rollup .\src\index.js --format iife --file dist/bundle.js指定打包格式為iife,并指定打包文件-
打包結(jié)束,輸出打包結(jié)果到bundle.js中
(function () { 'use strict'; const log = msg => { console.log('---------- INFO ----------'); console.log(msg); console.log('--------------------------'); }; var messages = { hi: 'Hey Guys, I am zce~' }; // 導(dǎo)入模塊成員 // 使用模塊成員 const msg = messages.hi; log(msg); }());可以看出,代碼中未使用的代碼會被自動清除,因為Rollup默認(rèn)開啟tree-shaking,如果用webpack,雖然可以實現(xiàn)tree-shaking,但需要配置并且打包的代碼非常臃腫
Rollup配置文件
項目根目錄添加rollup.config.js,如下
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js', // rollup支持的多種輸出格式(有amd,cjs, es, iife 和 umd)
format: 'iife',
},
}
可以通過yarn rollup --config直接運行默認(rèn)配置文件,也可以指定文件yarn rollup --config rollup.config.js,這樣可以針對不同的環(huán)境使用不同的配置
Rollup使用插件
Rollup支持使用插件的方式,并不像webpack中分為loader、plugins和minimize三種擴展方式,插件時Rollip唯一擴展途徑
-
rollup-plugin-json插件
安裝yarn add rollup-plugin-json --dev
rollup.config.js中通過esm模式引入,import json from 'rollup-plugin-json',并添加到plugins中
在index.js中獲取json文件中的字段,
import { name, version } from '../package.json'-
打包結(jié)果如下
(function () { ... var name = "01-getting-started"; var version = "0.1.0"; log(name); log(version); ... }());
-
加載Npm模塊
Rollup不能像Webpack一樣,直接使用模塊的名稱導(dǎo)入第三方模塊,需要使用rollup-plugin-node-resolve
安裝和使用同rollup-plugins-json插件一樣,安裝成功后導(dǎo)入lodash模塊,Rollup默認(rèn)處理esm模式的打包,所以需要導(dǎo)入import _ from 'lodash-es',使用console.log(_.camelCase('hello world')),打包結(jié)果如下
(function () { ... console.log(lodash.camelCase('hello world')); ... }()); -
加載CommonJS模塊
Rollup設(shè)計只處理ESModule的打包,導(dǎo)入CommonJS模塊是不支持的;需使用rollup-plugin-commonjs
-
創(chuàng)建cjs-module.js文件,以commonJS模式導(dǎo)出一個對象
module.exports = { foo: 'bar' } 安裝插件,并在plugins中配置
index.js引用模塊,并使用
-
打包結(jié)果如下
(function () { ... var cjsModule = { foo: 'bar' }; log(cjsModule); ... }());
Rollup代碼拆分
可以使用import()的方式動態(tài)導(dǎo)入文件,返回是一個promise對象
import('./logger').then(({ log }) => { log('hello') })此時通過yarn rollup --config運行打包報錯
UMD and IIFE output formats are not supported for code-splitting builds,因為立即執(zhí)行函數(shù)會將所有模塊放入同一個函數(shù),沒法實現(xiàn)代碼拆分,需使用amd或commonjs標(biāo)準(zhǔn)并且code-splitting會輸出多個文件,rollup輸出需要使用dir的方式,修改rollup.config.js
// rollup默認(rèn)入口 import json from 'rollup-plugin-json' import resolve from 'rollup-plugin-node-resolve' import commonjs from 'rollup-plugin-commonjs' export default { input: 'src/index.js', output: { // file: 'dist/bundle.js', // format: 'iife', dir: 'dist', format: 'amd', }, plugins: [ json(), resolve(), commonjs() ] }再次打包,就會在dist目錄下生成入口bundle和動態(tài)導(dǎo)入生成的bundle,并且都是使用amd標(biāo)準(zhǔn)輸出
Rollup多入口打包
多入口打包只需將input改為對象的模式
// 多入口打包內(nèi)部會提取公共模塊,內(nèi)部會使用代碼拆分,所以需使用amd foo: 'src/home.js', bar: 'src/album.js'打包過后,就可在dist目錄下生成amd標(biāo)準(zhǔn)的文件,不能直接使用,需要使用require.js,并指定data-main入口
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <script src="https://unpkg.com/requirejs@2.3.6/require.js" data-main="foo.js"></script> </body> </html> -
Rollup與Webpack
- Rollup優(yōu)勢:
- 輸出結(jié)果更加扁平,執(zhí)行效率自然更高
- 自動移除未引用代碼
- 打包結(jié)果依然完全可讀
- Rollup缺陷:
- 加載非ESM的第三方模塊比較復(fù)雜
- 模塊最終打包到一個函數(shù)中,無法實現(xiàn)HMR
- 瀏覽器環(huán)境中,代碼拆分依賴amd
如果正在開發(fā)應(yīng)用程序,需要引用第三方模塊、需要使用HMR提升開發(fā)效率,應(yīng)用大時需要使用分包,這些需求Rollup在滿足上都會有欠缺;而去過正在開發(fā)一個框架或類庫,很少依賴第三方模塊,像React/Vue都在使用Rollup作為模塊打包器
Webpack大而全,Rollup小而美
Parcel 零配置的前端應(yīng)用打包器
yarn init --yes初始化項目
安裝parcel模塊,yarn add parcel-bundler --dev后,在node-modules/.bin目錄就生成了parcel的cli程序,后續(xù)使用這個cli執(zhí)行對整個應(yīng)用的打包
-
執(zhí)行yarn parcel src/index.html,不僅會打包應(yīng)用,同時開啟一個開發(fā)服務(wù)器
和webpack的dev server一樣,支持自動刷新和模塊熱替換
// hot對象是否存在 如果存在就可以使用熱替換的api if (module.hot) { // 僅支持一個參數(shù) // 當(dāng)前模塊或當(dāng)前所依賴的模塊發(fā)生更新會自動執(zhí)行 module.hot.accept(() => { console.log('hmr') }) }parcel還支持自動安裝依賴,比如引用jquery,之前并沒有安裝,當(dāng)代碼保存成功后,就會自動安裝所導(dǎo)入的模塊
import $ fropm 'jquery' $(document.body).append('<h1>hello parcel</h1>')parcel支持加載其他類型的模塊,相比其他的模塊打包器,在parcel加載任意類型的文件都是零配置
parcel支持動態(tài)導(dǎo)入,如果使用了動態(tài)導(dǎo)入,會自動拆分代碼
import('jquery').then($ => { $(document.body).append('<h1>Hello Parcel</h1>') $(document.body).append(`<img src="${logo}" />`) }) 生產(chǎn)模式打包,parcel build src/*.html,parcel打包構(gòu)建速度會比webpack快很多,因為parcel內(nèi)部使用多進程同時工作