vite插件打包更順暢使用技巧示例
前言
在上一篇給大家?guī)砹恕?a href="http://www.dbjr.com.cn/article/252603.htm" rel="external nofollow" target="_blank">如何入門去寫一個(gè) vite 插件》,能看的出來同學(xué)們也甚是喜歡,如果大家對(duì) vite 感興趣,可以關(guān)注我的專欄《vite 從入門到精通》;
因?yàn)楣灸壳按蟛糠猪?xiàng)目都已轉(zhuǎn)為 vite,為了給社區(qū)添加一份貢獻(xiàn),故開發(fā)了一個(gè)已經(jīng)應(yīng)用到項(xiàng)目中的vite 前端打包進(jìn)度條 的插件 vite-plugin-progress;
介紹
vite-plugin-progress 插件是一個(gè)在打包時(shí)展示進(jìn)度條的插件,如果您覺得該插件對(duì)您的項(xiàng)目有幫助,歡迎 star ?? 支持一下,感謝!
用法
安裝
# npm npm i vite-plugin-progress -D # yarn yarn add vite-plugin-progress -D # pnpm pnpm i vite-plugin-progress -D
使用(不帶參數(shù)):在 vite.config.js / vite.config.ts 中配置
import progress from 'vite-plugin-progress' export default { plugins: [ progress() ] }
參數(shù) 0ptions:
- format :自定義進(jìn)度條的格式;
- width :進(jìn)度條在終端中的寬度;
- complete :完成后的默認(rèn)字符 \u2588 ;
- incomplete :未完成的默認(rèn)字符 \u2591 ;
- renderThrottle :間隔更新時(shí)間默認(rèn)16(毫秒);
- clear :完成后是否清除終端,默認(rèn) false;
- callback :完成后執(zhí)行的回調(diào)函數(shù);
- stream 終端中的輸出格式流,默認(rèn) stderr ;
- head :進(jìn)度條的頭字符;
參數(shù) options 中的 format 中各個(gè)標(biāo)記含義:
- :bar :代表進(jìn)度條;
- :current :當(dāng)前執(zhí)行到哪的刻度;
- :total :總刻度;
- :elapsed :所用時(shí)間(秒);
- :percent :完成的百分比;
- :eta :預(yù)計(jì)完成時(shí)間(秒);
- :rate :每一秒的速率;
使用(帶參數(shù)):
// vite.config.js / vite.config.ts import progress from 'vite-plugin-progress' export default { plugins: [ progress({ format: 'building [:bar] :percent', total: 200, width: 60, complete: '=', incomplete: '', }) ] }
給自定義進(jìn)度條加點(diǎn)顏色:
安裝 picocolors :
pnpm i picocolors -D
使用:
// vite.config.js / vite.config.ts import progress from 'vite-plugin-progress' import colors from 'picocolors' export default { plugins: [ progress({ format: `${colors.green(colors.bold('Bouilding'))} ${colors.cyan('[:bar]')} :percent` }) ] }
如果您只想使用該插件的話,那么現(xiàn)在就去安裝使用吧!
如果您對(duì)實(shí)現(xiàn)思路感興趣的話,那么您可以繼續(xù)向下滾動(dòng)查閱喲 ~
實(shí)現(xiàn)思路
其實(shí)實(shí)現(xiàn)這個(gè)功能,我們最主要的考慮就是當(dāng)前 vite 打包的進(jìn)度到哪里了,那么我們思考兩個(gè)問題:
- 考量當(dāng)前 vite 打包的進(jìn)度是到哪里了?
- 如何知道當(dāng)前打包的進(jìn)度?
熟悉 webpack 的朋友,肯定對(duì) webpack 的打包進(jìn)度條也不陌生;會(huì)發(fā)現(xiàn)在 webpack 中,webpack 暴露了一個(gè) webpack.ProgressPlugin 的事件鉤子,這樣就導(dǎo)致在 webpack 中實(shí)現(xiàn)進(jìn)度條會(huì)很容易,直接通過該鉤子去封裝即可;
但是在 vite 中由于是基于 Rollup 來構(gòu)建打包代碼,所以我們是沒法知道當(dāng)前 vite 打包進(jìn)度的;
借用 vite 其中某位作者的原話:
簡(jiǎn)單理解意思就是說在 vite 打包時(shí),是沒法知道進(jìn)度條的 0%-100%,因?yàn)槟仨毾却_定要構(gòu)建的模塊的總數(shù)
雖然我們不知道模塊總數(shù),但是我們可以在第一次打包時(shí)模擬一個(gè);
并且在第一次打包的時(shí)候,我們 記錄下對(duì)應(yīng)的模塊數(shù)量,然后 緩存起來,這樣我們不就可以知道對(duì)應(yīng)的模塊數(shù)量了嗎?
說干就干 ~
第一次打包(模擬模塊總數(shù))
因?yàn)槲覀兛梢灾?src 目錄 下所有的文件總數(shù),所以就可以假設(shè)在第一次打包時(shí)用該總數(shù)來代替模塊總數(shù);
那么簡(jiǎn)單公式:進(jìn)度條百分比 = 當(dāng)前轉(zhuǎn)換的模塊 / 模擬的模塊總數(shù)
import type { PluginOption } from 'vite'; import rd from 'rd'; export default function viteProgressBar(options?: PluginOptions): PluginOption { // 文件類型總數(shù) let fileCount = 0 let transformCount = 0 let transformed = 0 // 當(dāng)前已轉(zhuǎn)換的數(shù)量 retun { ... config(config, { command }) { if (command === 'build') { const readDir = rd.readSync('src'); const reg = /\.(vue|ts|js|jsx|tsx|css|scss||sass|styl|less)$/gi; readDir.forEach((item) => reg.test(item) && fileCount++); } }, transform(code, id) { transformCount++ const reg = /node_modules/gi; if (!reg.test(id){ percent = +(transformed / fileCount).toFixed(2) } } } }
與進(jìn)度條配合
那么既然我們已經(jīng)算出了基本的進(jìn)度條,也知道了基本思路,那么我們就把進(jìn)度條加進(jìn)去
import type { PluginOption } from 'vite'; import progress from 'progress'; import rd from 'rd'; export default function viteProgressBar(options?: PluginOptions): PluginOption { let fileCount = 0 // 文件類型總數(shù) let transformCount = 0 // 轉(zhuǎn)換的模塊總數(shù) let transformed = 0 // 當(dāng)前已轉(zhuǎn)換的數(shù)量 let lastPercent = 0; // 記錄上一次進(jìn)度條百分比 const bar: progress; retun { ... config(config, { command }) { if (command === 'build') { // 初始化進(jìn)度條 options = { width: 40, complete: '\u2588', incomplete: '\u2591', ...options }; options.total = options?.total || 100; const transforming = isExists ? `${colors.magenta('Transforms:')} :transformCur/:transformTotal | ` : '' const chunks = isExists ? `${colors.magenta('Chunks:')} :chunkCur/:chunkTotal | ` : '' const barText = `${colors.cyan(`[:bar]`)}` const barFormat = options.format || `${colors.green('Bouilding')} ${barText} :percent | ${transforming}${chunks}Time: :elapseds` delete options.format; bar = new progress(barFormat, options as ProgressBar.ProgressBarOptions); // 統(tǒng)計(jì)目錄下的文件總數(shù) const readDir = rd.readSync('src'); const reg = /\.(vue|ts|js|jsx|tsx|css|scss||sass|styl|less)$/gi; readDir.forEach((item) => reg.test(item) && fileCount++); } }, transform(code, id) { transformCount++ const reg = /node_modules/gi; if (!reg.test(id){ lastPercent = percent = +(transformed / fileCount).toFixed(2) } // 更新進(jìn)度條 bar.update(lastPercent, { transformTotal: cacheTransformCount, transformCur: transformCount, chunkTotal: cacheChunkCount, chunkCur: 0, }) }, closeBundle() { // close progress bar.update(1) bar.terminate() } } }
添加緩存
為了更準(zhǔn)確的知道打包的進(jìn)度,那么我們?cè)诘谝淮文M了總數(shù)的時(shí)候,也要同時(shí)把真實(shí)的模塊總數(shù)給緩存起來,這樣在下一次打包時(shí)才能更加準(zhǔn)確的計(jì)算出進(jìn)度條;
新增緩存文件 cache.ts
import fs from 'fs'; import path from 'path'; const dirPath = path.join(process.cwd(), 'node_modules', '.progress'); const filePath = path.join(dirPath, 'index.json'); export interface ICacheData { /** * 轉(zhuǎn)換的模塊總數(shù) */ cacheTransformCount: number; /** * chunk 的總數(shù) */ cacheChunkCount: number } /** * 判斷是否有緩存 * @return boolean */ export const isExists = fs.existsSync(filePath) || false; /** * 獲取緩存數(shù)據(jù) * @returns ICacheData */ export const getCacheData = (): ICacheData => { if (!isExists) return { cacheTransformCount: 0, cacheChunkCount: 0 }; return JSON.parse(fs.readFileSync(filePath, 'utf8')); }; /** * 設(shè)置緩存數(shù)據(jù) * @returns */ export const setCacheData = (data: ICacheData) => { !isExists && fs.mkdirSync(dirPath); fs.writeFileSync(filePath, JSON.stringify(data)); };
使用緩存
// 緩存進(jìn)度條計(jì)算 function runCachedData() { if (transformCount === 1) { stream.write('\n'); bar.tick({ transformTotal: cacheTransformCount, transformCur: transformCount, chunkTotal: cacheChunkCount, chunkCur: 0, }) } transformed++ percent = lastPercent = +(transformed / (cacheTransformCount + cacheChunkCount)).toFixed(2) }
實(shí)現(xiàn)架構(gòu)圖
最后
該系列會(huì)是一個(gè)持續(xù)更新系列,關(guān)于整個(gè)專欄 《Vite 從入門到精通》,我主要會(huì)從如下圖幾個(gè)方面講解,請(qǐng)大家拭目以待吧!?。?/p>
更多關(guān)于vite打包插件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
在Vue項(xiàng)目中引入JQuery-ui插件的講解
今天小編就為大家分享一篇關(guān)于在Vue項(xiàng)目中引入JQuery-ui插件的講解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-01-01淺談mvvm-simple雙向綁定簡(jiǎn)單實(shí)現(xiàn)
本篇文章主要介紹了淺談mvvm-simple雙向綁定簡(jiǎn)單實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-04-04vue之?dāng)?shù)據(jù)交互實(shí)例代碼
本篇文章主要介紹了vue之?dāng)?shù)據(jù)交互實(shí)例代碼,vue中也存在像ajax和jsonp的數(shù)據(jù)交互,實(shí)現(xiàn)向服務(wù)器獲取數(shù)據(jù),有興趣的可以了解一下2017-06-06vue3使用自定義指令實(shí)現(xiàn)el dialog拖拽功能示例詳解
這篇文章主要為大家介紹了vue3使用自定義指令實(shí)現(xiàn)el dialog拖拽功能示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09vue和iview結(jié)合動(dòng)態(tài)生成表單實(shí)例
這篇文章主要介紹了vue和iview結(jié)合動(dòng)態(tài)生成表單實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10vuex state中的數(shù)組變化監(jiān)聽實(shí)例
今天小編就為大家分享一篇vuex state中的數(shù)組變化監(jiān)聽實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-11-11