vue多页面项目实现版本快照功能示例详解

 更新时间:2023年01月17日 09:19:29   作者:渐行渐远  
这篇文章主要为大家介绍了vue多页面项目实现版本快照功能示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

背景

App落地页迭代频繁,且需兼容App与各小App,目前是单向前进迭代,会存在以下问题:

  • 跳转原生交互;如:某个落地页增加了只有主App的才有的原生功能,小App就无法投放;
  • 历史版本归因与复用,历史测试版本的落地页都在主链上进行版本迭代,不利于落地页成功、失败版本的区分统计以及沉淀;

所以需实现一个快照版本的功能,将构建产物以特定的命名规则给保留下来,并且支持链接访问。可以解决已上问题;

  • 若主App落地页迭代了新的原生功能,小App可以更换投放历史的链接,等小App支持了该原生功能,再恢复成主链接;
  • 将每次迭代的链接利用管理后台维护,生成完资源后将changelog等信息上传至后台,方便产品管理。

需要解决的问题:

  • 如何保存页面资源
  • 只是项目中的几个页面需要支持这个功能,如何设计这个配置的开启与关闭
  • 每次只生成改动的页面,实现增量生成。

实现思路:

在需要配置快照版本的页面新增配置文件,构建过程中获取到这些需要快照版本功能的入口,由于迭代可能只更新到其中的某个页面,还需要做到增量生成,利用hashchunk对比构建上一次与这一次是否一致,若一致,则删除,若不一致,则保留,最后以当前提交的commitid作为目录将产物保存至dist/目录中,一同上传服务器中。

实现过程:

资源命名;因为每次迭代都会生成新的commitid,符合唯一性与可追溯性,适合用于当资源目录。再以特定的目录名标识此文件夹属于快照版本;最终命名snaps/{commitid}/pages/{页面}.html

文件保存:

在以往项目配置项目打包会清除dist目录内容,打包完成再传到服务器;为了实现历史资源保存,需要改一下clean-webpack-plugin的配置,每次只清除上一次的主构建产物,而不是整个dist目录。

版本快照的webpack配置;主要思路为:每个页面的配置文件新增快照版本标识{snapshot: true}, 获取到这些页面的入口文件,传入webpack的entry配置。

配置产物路径; 产物文件名filename、产物路径path、静态资源路径assetModuleFilename、静态资源基础路径publicPath

filename: [name]/assets/js/main.[chunkhash:8].js, 利用chunkhash做浏览器缓存

path:path.join(path.resolve(), dist/snaps/${commit}),以snaps作为父目录,commit标识每次生成快照版本的版本号。

assetModuleFilename: 将资源放入对应页面的目录,如dist/snaps/${commit}/assets/images/a.png,再后续实现增量构建时才能直接删除。

    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静态资源基础路径默认配置是/,需要将其指向快照版本目录对应的版本,确保资源能正常访问。COMMIT_ID_PACEHOLDER是commitid占位符,因为后续需要通过hashchunk对比产物是否更新,如果这里指定commitid,每次构建产物hashchunk都不一样,就无法做到增量更新;所以这里需要一个唯一的字符串,在构建完后用脚本去替换真实的commitid

实现增量生成与页面信息上传至管理后台:SnapshotPlugin

在plugin的done钩子,获取到此次入口的chunkHash(compilation.entrypoints[i].chunks)与上次的hashchunk记录进行对比,若不相同,则保留文件,若相同,说明此次该页面无改动,则将改页面的资源删除,则将该页面生成的删除删除,最后将此次生成的hashchunk值保存下来,以供下次对比;对比文件数据结构如下:

{
   "test-page-1": "6e364aeafe957d7929223750b326a4f3",
   "test-page-2": "f586eeef3a1f37672d54b0e5a1d5c0c7",
}

若是需要生成的页面,还需要替换掉COMMIT_ID_PACEHOLDER,遍历此次生成的目录中的js、css文件,将COMMIT_ID_PACEHOLDER替换成此次的commitid,确保资源能够访问。

最后通过调取接口存储页面链接、changelog、标题等信息。

关键代码:

  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
                         // 获取上次构建的chunkhash值
  			const snapHashMap = getLastTimeSnapHash()
                         // 获取上次没有上传至管理后台的页面信息数据,此次一同发送
  			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
                                   // 获取页面的配置文件,得到页面配置信息,如标题等
  					const config = getPageConfig([key]) || {}
                                   // 生成管理后台数据
  					snapPages.push(genSnapConfig(getSnapLink(this.curCommitId, key), config[key].title || key))
  				} else {
  					// 如果相同,则删除对应的文件目录,因为此个版本没有更新,不需要生成快照
  					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) {
                                // 调取接口存储页面信息
  				postSnapData(snapPages).then(() => {
  					console.log('postSnapData --- success');
  					// 新增成功,删除缓存文件
  					removeDir(resolve(PATH_CONFIG.SNAPS_PAGES))
  				}).catch(() => {
  					console.log('postSnapData --- fail');
  					// 新增失败,则将数据存储只本地
  					setCurrTimeSnapPages(snapPages)
  				})
  			}
  		})
  	}
  }

以上就是vue多页面项目实现版本快照功能示例详解的详细内容,更多关于vue多页面项目版本快照的资料请关注脚本之家其它相关文章!

相关文章

  • Hooks对于Vue作用意义详解

    Hooks对于Vue作用意义详解

    这篇文章主要为大家介绍了Hooks对于Vue作用意义详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • Vue实现简易计算器

    Vue实现简易计算器

    这篇文章主要为大家详细介绍了用Vue制作的简易计算器,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-02-02
  • 基于Vue中的父子传值问题解决

    基于Vue中的父子传值问题解决

    这篇文章主要介绍了基于Vue中的父子传值问题解决,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07
  • VUE+Element UI实现简单的表格行内编辑效果的示例的代码

    VUE+Element UI实现简单的表格行内编辑效果的示例的代码

    这篇文章主要介绍了VUE+Element UI实现简单的表格行内编辑效果的示例的代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-10-10
  • vue实现页面缓存功能

    vue实现页面缓存功能

    这篇文章主要为大家详细介绍了vue实现页面缓存功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • Vue 3自定义指令开发的相关总结

    Vue 3自定义指令开发的相关总结

    这篇文章主要介绍了Vue 3自定义指令开发的相关总结,帮助大家更好的理解和使用vue框架,感兴趣的朋友可以了解下
    2021-01-01
  • vue实现web前端登录页数字验证码

    vue实现web前端登录页数字验证码

    这篇文章主要为大家详细介绍了vue实现web前端登录页数字验证码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • vue实现一个移动端屏蔽滑动的遮罩层实例

    vue实现一个移动端屏蔽滑动的遮罩层实例

    本篇文章主要介绍了vue实现一个移动端屏蔽滑动的遮罩层实例,具有一定的参考价值,有兴趣的可以了解一下
    2017-06-06
  • Vue filter 过滤当前时间 实现实时更新效果

    Vue filter 过滤当前时间 实现实时更新效果

    这篇文章主要介绍了Vue filter 过滤当前时间 实现实时更新效果,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-12-12
  • vue: WebStorm设置快速编译运行的方法

    vue: WebStorm设置快速编译运行的方法

    今天小编就为大家分享一篇vue: WebStorm设置快速编译运行的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-10-10

最新评论