我們常常面臨Webpack復雜配置或是Babel轉譯后的冗余代碼,結果導致最終的包體積居高不下加載速度也變得異常緩慢,而在眾多打包工具中Rollup作為一個輕量且高效的選擇,正悄然改變著這一切,本文將帶你深入了解這個令人驚艷的打包工具
目錄
入門Rollup
配置Rollup
Babel轉換代碼
打包多入口代碼
加載三方依賴模塊
使用TS模塊
壓縮JS代碼
模板生成html頁面
啟動開發服務器
處理vue組件
壓縮CSS代碼
設置環境變量
配置css預處理器
排除第三方庫
打包文件拆分
生成sourcemap
配置路徑別名
入門Rollup
????????初識Rollup:是一個現代js的打包工具,主要用于將多個js文件打包成一個或多個最終的輸出文件,它特別適用于構建庫和模塊化的應用程序,與Webpack等其他打包工具相比,Rollup 的一個顯著優勢是它能生成非常精簡的代碼,因為它能夠進行更好的tree-shaking(去除未使用的代碼)和模塊優化,其使用特點如下所示:
1)打包后的代碼體積小,性能優異
2)支持 ES 模塊(ESM)格式
3)插件豐富,能夠進行高度自定義
4)支持 tree shaking(去除無用代碼)
所以說如果想構建庫和小型應用,尤其是需要發布成npm包時,選擇Rollup是一個不錯的選擇,如果想了解更為詳細的內容,參考:官網?:
??????? 項目初始化:接下來我們開始對項目進行一個初始化,首先終端執行如下命令直接全局安裝rollup,如下所示:
npm install --global rollup
接下來我們創建一個項目文件夾,然后終端自行pnpm init初始化一個package.json文件,然后執行如下命令來安裝一下rollup,安裝完成之后,我們在項目根目錄創建一個src文件夾,里面新建一個index.js文件,來展示一下要打包的代碼:
pnpm i rollup -D
function random() {return Math.random().toString(16).slice(2);
}
console.log(random(), '變化1')
console.log(random(), '變化2')
然后我們根據官網給的入門提示,配置如下的打包命令:
可以看到打包出來的文件,基本上也是能夠看懂的
配置Rollup
Rollup作為一個強大的js打包工具,在構建高效優化的模塊化代碼時展現了其獨特的優勢,然而Rollup的配置可以有很多細節,本文將帶你逐步了解Rollup的配置過程,探討如何通過Rollup配置優化打包提升代碼的加載速度和運行效率,如下所示:
Babel轉換代碼
現代JavaScript特性(如箭頭函數、模板字符串、類、模塊化等)并不是所有瀏覽器都支持,特別是一些舊版瀏覽器(例如 Internet Explorer),Babel可以將這些新特性轉換為舊版瀏覽器可以理解的代碼以確保不同環境下的兼容性,接下來我們需要終端安裝如下依賴:
// @babel/core babel的核心包
// @babel/preset-env 預設
// @rollup/plugin-babel babel插件
// @babel/runtime 減小最終構建文件的體積
// @babel/plugin-transform-runtime 減少轉換過程中出現的重復代碼
pnpm i @rollup/plugin-babel @babel/core @babel/preset-env @babel/runtime @babel/plugin-transform-runtime -D
安裝完插件之后,我們在根目錄創建一個?.babelrc 的babel配置文件,然后進行如下配置:
{"presets": [["@babel/preset-env",{"modules": false}]],"plugins": ["@babel/plugin-transform-runtime"]
}
配置完成之后我們來到config文件中進行如下babel插件的設置:
然后我們在入口文件寫一個ES6模塊的箭頭函數,打包之后就會變成普通的function函數,兼容了低版本瀏覽器不支持ES6高級語法的情況:
打包多入口代碼
上面我們配置的都是打包單入口的代碼,如果想配置打包多入口的代碼需要通過如下操作進行:
打包代碼之前,我們需要先將打包文件中原本的文件先刪除掉,這里需要借助如下插件:
pnpm i rollup-plugin-clear -D
然后我們引入插件之后進行如下插件的注冊即可:
如下我們在dist文件下隨便建一些文件,當我們執行打包之后,這些無關的文件都會被清除掉:
加載三方依賴模塊
如果想rollup支持三方依賴插件的打包,這里我們需要安裝如下插件然后進行一些配置:
pnpm i @rollup/plugin-node-resolve @rollup/plugin-commonjs -D
安裝完成之后,我們仍然需要在配置文件當中進行如下插件的設置:
設置完成之后,我們可以安裝一個三方依賴嘗試一下,如下:
pnpm i lodash -s
如下當我們執行打包的時候就會把三方插件的依賴全部打包到文件當中:
當然可能還會有一些情況,比如說我們引入的第三方依賴當中含有的node語法,瀏覽器是無法識別的,這里我們需要替換一下打包結果中的關鍵字,終端執行如下命令:
pnpm i @rollup/plugin-replace -D
安裝完成之后,在rollup配置文件當中進行如下配置即可:
replace({ // 替換打包結果中在瀏覽器中不兼容的代碼,例如process.env.NODE_ENV'process.env.NODE_ENV': JSON.stringify('production'), // 替換代碼中的環境變量preventAssignment: true // 防止替換賦值表達式,例如process.env.NODE_ENV = 'production'
}),
使用TS模塊
如果想編譯TS文件為js代碼的話,需要終端安裝如下插件:
pnpm i @rollup/plugin-typescript tslib -D
然后在配置文件中注冊插件即可:
如下當執行打包的時候,TS文件編譯成JS文件:
然后如果想對我們的ts編譯進行一些操作的話,直接執行tsc --init生產ts配置文件,然后在里面調整即可,如下所示:
然后我們可以根據自身情況進行一個配置,例如如下所示:
{"compilerOptions": {"target": "ES6", // 編譯目標為ES6 "module": "ESNext", // 模塊系統為ESNext "strict": false, // 啟用所有嚴格類型檢查選項 "skipLibCheck": true, // 跳過所有聲明文件的類型檢查 "esModuleInterop": true, // 允許從默認導出導入模塊 "forceConsistentCasingInFileNames": false, // 禁止對同一個文件的不一致的引用 }
}
壓縮JS代碼
如果我們想對JS代碼進行一個壓縮,這里我們可以終端執行如下命令安裝插件:
pnpm i @rollup/plugin-terser -D
安裝完插件之后,還是對插件進行一個導入并使用:
然后我們執行打包,可以看到我們的代碼已經真正被壓縮了:
模板生成html頁面
如果我們想根據模板html生成html單頁面,這里我們可以終端執行如下命令安裝插件:
pnpm i rollup-plugin-generate-html-template -D
安裝完成之后,這里我們仍然需要在rollup配置文件當中,設置該模板插件,如下所示:
添加完成之后我們在src目錄下新建一個index.html文件,這里可以演示作為vue的根節點:
<!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><!-- vue的掛載點 --><div id="app"></div>
</body>
</html>
當我們執行打包命令之后,html頁面就會自動被打包到dist文件下,并且會自動注入js代碼,注入js代碼的類型也是我們設置的module,當我們執行html之后,瀏覽器也會執行js中的代碼邏輯:
啟動開發服務器
上面我們通過模板生成index.htm文件之后,如果想方便的運行項目的話,這里我們可以安裝如下插件來幫助我們快捷的實現服務器的運行:
pnpm i rollup-plugin-serve -D
安裝完插件之后,我們就可以在rollup配置文件當中進行如下配置:
然后我們可以在package.json文件當中針對不同的環境執行不同的文件,這里本地環境就執行dev命令即可,生產環境就執行build命令即可,然后針對不同的環境也可執行不同的配置文件:
比如說生產的配置文件中,不需要執行啟動開發服務器的插件,本地環境不需要執行壓縮代碼的插件,然后不同的環境替換關鍵字的命令也不同,如下所示:
然后我們運行pnpm run dev命令,打開本地環境,如下可以看到會自動打開瀏覽器,查看f12可以看到我們打包的命令被執行了:
如果想設置完開發服務器之后,后期對代碼修改瀏覽器能夠自動更新,可以終端執行如下命令:
pnpm i rollup-plugin-live-server -D
安裝完插件之后,我們在配置文件中進行一個導入,然后我們修改頁面代碼之后,頁面可以實時更新了,如下所示:
import { liveServer } from 'rollup-plugin-live-server'liveServer({port: 3000, // 設置端口號host: 'localhost', // 設置主機名root: 'dist', // 設置根目錄file: 'index.html', // 設置默認打開的文件open: true, // 自動打開瀏覽器
})
當然我們還可以安裝下面的插件,進行插件之間的配合操作,如下所示:
pnpm i rollup-plugin-livereload -D
import serve from 'rollup-plugin-serve'
import livereload from 'rollup-plugin-livereload';// 開發服務器:使用 serve 和 livereload 組合
serve({open: true, // 只在首次啟動時打開瀏覽器verbose: true,contentBase: ['dist'],port: 3000,host: 'localhost',onListening(server) {const address = server.address();const host = address.address === '::1' ? 'localhost' : address.address;const port = address.port;console.log(`Server running at http://${host}:${port}/`);}
}),
// 監聽 dist 目錄變化并自動刷新頁面
livereload({watch: 'dist',verbose: false, // 關閉過多的日志輸出delay: 1000, // 延遲時間,防止頻繁刷新
}),
處理vue組件
如果我們想基于vue來開發一些功能的話,這里需要終端執行如下命令安裝插件:
pnpm i vue -s
pnpm i rollup-plugin-vue -D
安裝完插件之后,我們需要引入該插件,然后把vue編譯放在插件列表的第一個:
然后我們開始編寫vue模板并在入口文件中進行引入即可:
這里順便為vue文件添加類型聲明,如下所示:
終端執行打包命令之后,可以看到我們的瀏覽器已經打印了我們定義的內容:
壓縮CSS代碼
如果相對我們CSS代碼進行一個壓縮,這里我們可以終端執行如下命令安裝插件,后面兩個插件分別是對壓縮和瀏覽器版本進行的控制:
pnpm i rollup-plugin-postcss cssnano autoprefixer -D
完整完插件之后,我們來到配置文件當中,進行如下配置:
import postcss from 'rollup-plugin-postcss';
import cssnano from 'cssnano';
import autoprefixer from 'autoprefixer'// 處理 CSS
postcss({extract: 'bundle.css', // 提取CSS到單獨的文件modules: false, // 禁用 CSS Modulesminimize: true, // 開啟壓縮plugins: [autoprefixer, cssnano], // 使用 cssnano 插件進行壓縮
}),
這里我們還需要來到package.json文件當中,設置browserslist指定項目所支持的瀏覽器范圍的配置,如下所示:
"browserslist": ["defaults","not ie < 8","last 2 versions","> 1%","iOS 7","last 3 iOS versions"
]
執行打包命令之后,可以看到我們的css文件已經被壓縮,并且瀏覽器的樣式也成功生成,并且也兼容了其他瀏覽器的版本:
設置環境變量
如果想實現環境變量的配置以及實現跨平臺等操作,可以安裝如下插件:
pnpm i cross-env -D
然后我們在配置文件當中打印一下當前的環境變量,如下所示:
當我們在package包中配置好執行腳本命令之后,打包生產可以看到控制臺打印了當前的環境變量為生產,與我們設置的是一樣的:
然后我們根據打印的環境變量來控制臺當前的rollup的一些配置,后期打包的話就會根據打包環境變量的不同來控制不同配置的生效:?
const isPro = process.env.NODE_ENV === 'production'// 處理 CSS
postcss({extract: 'bundle.css', // 提取CSS到單獨的文件modules: false, // 禁用 CSS Modulesminimize: true, // 開啟壓縮plugins: [autoprefixer, // 使用 autoprefixer 插件添加瀏覽器前綴isPro && cssnano // 使用 cssnano 插件進行壓縮],
}),// 替換打包結果中在瀏覽器中不兼容的代碼,例如process.env.NODE_ENV
replace({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV), // 替換代碼中的環境變量preventAssignment: true // 防止替換賦值表達式,例如process.env.NODE_ENV = 'production'
}),// 壓縮打包后的文件
isPro && terser(), // 生產環境才壓縮代碼
配置css預處理器
如果想使用一些css預處理器如scss的話,可以終端執行如下命令安裝:
pnpm i sass -D
// 或
pnpm i less -D
安裝完預處理器之后,我們可以直接使用這種css方式,如下所示:
然后瀏覽器的樣式依然生效:?
排除第三方庫
正常我們編寫完vue項目之后打包項目,打包的文件里面就會把vue的項目全部打印到文件當中,可以看到打包后的文件為236kb,還是蠻大的,有什么辦法能夠減少打包體積呢?
這里我們可以排除第三方庫的引入,通過第三方cdn方式引入來減少打包提交,如下我們可以在我們的index.html中引入vue對應版本的第三方cdn鏈接:
引入完之后我們可以在rollup的配置文件當中排除第三方vue的引入, 這里需要排除項配置和輸出文件配置中的globals進行搭配使用,如下所示:
接下來當我們再次運行打包之后可以看到我們的打包體積已經大幅度被壓縮了,有原本的200多kb的體積壓縮到了只有1kb:
可以看到我們打包后的js文件是只有我們代碼中真正寫的內容,像vue的一些配置都被抽離出去通過cdn方式來引入使用了:
再比如當我們使用vue-router插件之后,配置完路由內容之后,如下所示:
雖然我們的項目被成功運行了,但是我們打包后的配置文件仍然還是比較大:
這里我們仍然可以通過排除第三方庫的方式來減少打包體積,這里引入對應版本的vue-router文件
然后再配置文件當中,對路由依賴進行一個排除,如下所示:
可以看到我們的項目最終的打包體積被壓縮到了3kb左右:
打包文件拆分
除了上面我們排除第三方庫能夠壓縮打包體積操作,我們還可以對我們大體積的文件進行一個拆分操作,如果想對打包文件進行拆分,這里我們設置的打包模式就不能是iife,因為該模式不支持打包文件拆分,所有這里我們還是需要將其設置為esm模式,也就是es6里面所提供的瀏覽端標準的模塊化解決方案,如下所示:
然后導入路由的方式我們采用異步方式導入,打包后的文件就會拆分成對應的路由文件,后面跟著一個隨機的字符串避免瀏覽器緩存:
當然我們還可以對第三方庫進行一個拆分,如下所示:
生成sourcemap
如果想我們壓縮后的代碼運行瀏覽器后,發生報錯之后想精準定位報錯文件,這里我們可以開啟sourcemap操作,如下我們設置sourcemap為true的情況下,打包文件就會生成對應的map文件:
這些map文件就會被瀏覽器所識別并解析成我們項目真正的源代碼,當然也可以設置如下選項,將這些map文件內嵌到對應的文件當中:
配置路徑別名
如果想配置路徑別名操作,可以終端執行如下命令安裝插件:
pnpm i @rollup/plugin-alias -D
安裝完插件之后,我們就需要在配置文件中進行一些設置,因為rollup配置文件中采用的是ES模塊的寫法,所有絕對路徑我們需要改成ES寫法:
import path from 'path'
import { fileURLToPath } from 'url';
import { dirname } from 'path';// 獲取 __dirname 的 ES 模塊寫法
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
接下來我們在插件列表中進行如下配置:
// 配置別名路徑
alias({entries: [{ find: '@', replacement: path.resolve(__dirname, 'src') }, // 將@替換為/src],
}),
然后路由代碼中我們使用別名操作:
最終瀏覽器運行,沒有問題,別名配置成功:
最后總結:Rollup作為一款專注于 ES 模塊的打包工具,憑借其簡潔的配置和強大的插件生態,為現代前端項目提供了高效、靈活的構建解決方案。通過本文的探討,我們不僅掌握了從基礎配置到高級優化的全流程技巧,還深入理解了如何根據項目需求選擇合適的插件組合,解決實際開發中的各種挑戰。無論是處理 Vue 組件、TypeScript 代碼,還是實現熱更新和代碼分割,Rollup 都能以優雅的方式應對。掌握 Rollup 的配置藝術,不僅能提升項目的構建效率和運行性能,更能讓開發者在模塊化開發的道路上走得更加從容。未來,隨著前端技術的不斷演進,Rollup 也將持續為我們的開發工作注入新的活力,成為構建高質量JS應用不可或缺的利器。