vue多頁面項目實現(xiàn)版本快照功能示例詳解
背景
App落地頁迭代頻繁,且需兼容App與各小App,目前是單向前進迭代,會存在以下問題:
- 跳轉(zhuǎn)原生交互;如:某個落地頁增加了只有主App的才有的原生功能,小App就無法投放;
- 歷史版本歸因與復(fù)用,歷史測試版本的落地頁都在主鏈上進行版本迭代,不利于落地頁成功、失敗版本的區(qū)分統(tǒng)計以及沉淀;
所以需實現(xiàn)一個快照版本的功能,將構(gòu)建產(chǎn)物以特定的命名規(guī)則給保留下來,并且支持鏈接訪問??梢越鉀Q已上問題;
- 若主App落地頁迭代了新的原生功能,小App可以更換投放歷史的鏈接,等小App支持了該原生功能,再恢復(fù)成主鏈接;
- 將每次迭代的鏈接利用管理后臺維護,生成完資源后將changelog等信息上傳至后臺,方便產(chǎn)品管理。
需要解決的問題:
- 如何保存頁面資源
- 只是項目中的幾個頁面需要支持這個功能,如何設(shè)計這個配置的開啟與關(guān)閉
- 每次只生成改動的頁面,實現(xiàn)增量生成。
實現(xiàn)思路:
在需要配置快照版本的頁面新增配置文件,構(gòu)建過程中獲取到這些需要快照版本功能的入口,由于迭代可能只更新到其中的某個頁面,還需要做到增量生成,利用hashchunk對比構(gòu)建上一次與這一次是否一致,若一致,則刪除,若不一致,則保留,最后以當(dāng)前提交的commitid作為目錄將產(chǎn)物保存至dist/目錄中,一同上傳服務(wù)器中。
實現(xiàn)過程:
資源命名;因為每次迭代都會生成新的commitid,符合唯一性與可追溯性,適合用于當(dāng)資源目錄。再以特定的目錄名標(biāo)識此文件夾屬于快照版本;最終命名snaps/{commitid}/pages/{頁面}.html
文件保存:
在以往項目配置項目打包會清除dist目錄內(nèi)容,打包完成再傳到服務(wù)器;為了實現(xiàn)歷史資源保存,需要改一下clean-webpack-plugin
的配置,每次只清除上一次的主構(gòu)建產(chǎn)物,而不是整個dist
目錄。
版本快照的webpack配置;主要思路為:每個頁面的配置文件新增快照版本標(biāo)識{snapshot: true}, 獲取到這些頁面的入口文件,傳入webpack的entry配置。
配置產(chǎn)物路徑; 產(chǎn)物文件名filename、產(chǎn)物路徑path、靜態(tài)資源路徑assetModuleFilename、靜態(tài)資源基礎(chǔ)路徑publicPath
filename: [name]/assets/js/main.[chunkhash:8].js
, 利用chunkhash做瀏覽器緩存
path:path.join(path.resolve(),
dist/snaps/${commit})
,以snaps作為父目錄,commit標(biāo)識每次生成快照版本的版本號。
assetModuleFilename: 將資源放入對應(yīng)頁面的目錄,如dist/snaps/${commit}/assets/images/a.png,再后續(xù)實現(xiàn)增量構(gòu)建時才能直接刪除。
assetModuleFilename: ({ module }) => { let ctx = module.context; let origin = path.resolve("src/assets"); let dir = ctx.replace(origin, "").replace(/\\/g, "/") return `${dir}/assets/images/[hash][ext]` }
publicPath: /snaps/{{${COMMIT_ID_PACEHOLDER}}}/
, 因為webpack靜態(tài)資源基礎(chǔ)路徑默認(rèn)配置是/
,需要將其指向快照版本目錄對應(yīng)的版本,確保資源能正常訪問。COMMIT_ID_PACEHOLDER
是commitid占位符,因為后續(xù)需要通過hashchunk
對比產(chǎn)物是否更新,如果這里指定commitid
,每次構(gòu)建產(chǎn)物hashchunk
都不一樣,就無法做到增量更新;所以這里需要一個唯一的字符串,在構(gòu)建完后用腳本去替換真實的commitid
。
實現(xiàn)增量生成與頁面信息上傳至管理后臺:SnapshotPlugin
在plugin的done鉤子,獲取到此次入口的chunkHash(compilation.entrypoints[i].chunks)
與上次的hashchunk記錄進行對比,若不相同,則保留文件,若相同,說明此次該頁面無改動,則將改頁面的資源刪除,則將該頁面生成的刪除刪除,最后將此次生成的hashchunk值保存下來,以供下次對比;對比文件數(shù)據(jù)結(jié)構(gòu)如下:
{ "test-page-1": "6e364aeafe957d7929223750b326a4f3", "test-page-2": "f586eeef3a1f37672d54b0e5a1d5c0c7", }
若是需要生成的頁面,還需要替換掉COMMIT_ID_PACEHOLDER
,遍歷此次生成的目錄中的js、css文件,將COMMIT_ID_PACEHOLDER
替換成此次的commitid
,確保資源能夠訪問。
最后通過調(diào)取接口存儲頁面鏈接、changelog、標(biāo)題等信息。
關(guān)鍵代碼:
module.exports = class SnapshotPlugin { constructor({ commitId }) { this.curCommitId = commitId } apply(compiler) { compiler.hooks.done.tap('snapshot-plugin', ({ compilation: { outputOptions, entrypoints } }) => { console.log('快照對比----snapshot-plugin'); const PAGES_ROOT = outputOptions.path // 獲取上次構(gòu)建的chunkhash值 const snapHashMap = getLastTimeSnapHash() // 獲取上次沒有上傳至管理后臺的頁面信息數(shù)據(jù),此次一同發(fā)送 const snapPages = getLastTimeSnapPages() let count = entrypoints.size for (const [key, val] of entrypoints) { // key是入口name, val中可以獲取此次的hash值 const curChunkHash = (val.chunks.map(item => item.hash).filter(item => item) || []).join(':') // 如果不相同,則說明有改動,將此添加到變更json中 if (!snapHashMap[key] || snapHashMap[key] !== curChunkHash) { snapHashMap[key] = curChunkHash // 獲取頁面的配置文件,得到頁面配置信息,如標(biāo)題等 const config = getPageConfig([key]) || {} // 生成管理后臺數(shù)據(jù) snapPages.push(genSnapConfig(getSnapLink(this.curCommitId, key), config[key].title || key)) } else { // 如果相同,則刪除對應(yīng)的文件目錄,因為此個版本沒有更新,不需要生成快照 removeDir(`${PAGES_ROOT}/${key}`) count-- } } if (count > 0) { // 替換commitid replaceCommitHolder(PAGES_ROOT, this.curCommitId) // 更新頁面的chunchHash值 setCurrTimeSnapHash(snapHashMap) } else { removeDir(`${outputOptions.path}`) } if (snapPages.length > 0) { // 調(diào)取接口存儲頁面信息 postSnapData(snapPages).then(() => { console.log('postSnapData --- success'); // 新增成功,刪除緩存文件 removeDir(resolve(PATH_CONFIG.SNAPS_PAGES)) }).catch(() => { console.log('postSnapData --- fail'); // 新增失敗,則將數(shù)據(jù)存儲只本地 setCurrTimeSnapPages(snapPages) }) } }) } }
以上就是vue多頁面項目實現(xiàn)版本快照功能示例詳解的詳細內(nèi)容,更多關(guān)于vue多頁面項目版本快照的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
VUE+Element UI實現(xiàn)簡單的表格行內(nèi)編輯效果的示例的代碼
這篇文章主要介紹了VUE+Element UI實現(xiàn)簡單的表格行內(nèi)編輯效果的示例的代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-10-10Vue 3自定義指令開發(fā)的相關(guān)總結(jié)
這篇文章主要介紹了Vue 3自定義指令開發(fā)的相關(guān)總結(jié),幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下2021-01-01Vue filter 過濾當(dāng)前時間 實現(xiàn)實時更新效果
這篇文章主要介紹了Vue filter 過濾當(dāng)前時間 實現(xiàn)實時更新效果,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-12-12