Menu Home

maps开发之代码版本控制

项目背景

maps 项目类似cms 项目,由很多的模块组成。采用前后端分离的模式,所以在约定数据存储后端只负责存储不做任何逻辑储存。所以需要前端自己组织整个页面的数据结构和逻辑。这就意味着如果在数据上的变更和修改都需要前端自己来处理。

遇到的问题

在项目开发二期发现问题是,二期在模块的修改、新增,导致模块字段结构变化非常大,导致兼容一期的数据会变的麻烦。这个时候考虑到两种方案,第一种是在代码上兼容所有版本的数据,第二种不同版本的数据执行不同版本的代码。

方案的选择

根据遇到的问题里面讲述的两种方案:

  • 如果采用第一种方案,带来的问题就是 代码需要兼容的字段和数据会随着版本的增加变的越来越复杂。后面让代码理解带来很大的麻烦。
  • 再看第二个方案,我可以保持我的代码永远是最新的状态,对于老的运行的版本数据不至于版本的更新,导致不至于运行不了。

但是第二个方案有个问题,随着版本的更新会出现 代码文件的碎片化严重,需要维护的版本增多了这样也不好。有个解决办法就是在编辑页面的地方(后面称为B端)保持代码的最新,对老数据进行置换为新的代码结构的数据。这样就可以对已编辑的页面就会换成新版本的数据的页面。尽量减少这种碎片化的情况。

方案实施

需要解决的问题

  1. 如何保证B端的代码永远最新兼容老版本数据的时候不出错
  2. 将B端保存数据版本化
  3. 首先如何打包文件代码将其版本化
  4. 用户端如何将版本对应代码顺利执行

问题一

为了减少代码的碎片化,不得不得在重新编辑旧版本数据的页面时候,置换成最新版本的数据结构。也就是在模块执行操作之前写了一个中间件,中间件的作用就是将新就数据diff ,如果新版的字段老版本没有就给默认,如果老版的字段新的版本没有就舍弃。如下面的代码

function parseModuleCfg(moduleObj) {
        var that = moduleObj,
            servModuleCfg = that.getModuleCfg(),
            moduleCfg = {
                'isUseTitle': servModuleCfg.isUseTitle || false,
                'showCount': servModuleCfg.productShowNum || 1,
                'type': servModuleCfg.type,
                'isSubTitleShow': servModuleCfg.isSubTitleShow || false
            };
        that.setModuleCfg(moduleCfg);
    }

WX20170714-153223@2x

问题二

将数据版本化,在B端的代码中点击保存页面的时候,会将当前代码的版本随着数据一起传输给服务端存储在数据库中。所以即使这份已有的页面的数据是来自老版本的依然可以稳定运行在新版本的代码中,这样就可以将老版本的数据的页面减少
WX20170714-153754@2x

问题三

如何将代码文件版本化?

当前项目中,涉及库函数和模块等相关文件,差不多50多个。如果每个文件都要打上版本号并且保证异步加载的方式,是非常麻烦。所以使用webpack3将js、css打包成一个文件,并对这一个文件进行版本化,图片,字体文件就合并一个文件夹就可以了。这里webpack 是默认支持将所有的文件都合并到一个文件中,并修改文件命为 main_version.js 例如 main_1.6.5.js
WX20170714-154104@2x

问题四

如何将数据中存储的版本和文件名对应上?

页面加载后 请求当前页面的数据的版本号回来,如何拼凑成main_1.6.2.js这样的字符串,然后动态创建script 标签插入到页面中。这里就有个问题,假如这个版本的文件不存在怎么办?那就请求到最新版本的文件。

那么如何知道这个版本文件会不存在呢?

每个版本的文件在执行前都会在window.version 种上当前版本,也就是说在请求文件之前设定一个定时器,发现window.version 为undefind 就请求最新版本的文件。

总结

这里虽然解决了多版本数据对应多版本的文件,但是在实践过程中发现,在请求回调版本号到开始渲染中间有个短暂的过渡时间,这个体验会不太好。

还有就是在合并代码的过程中 将所有的代码合在一起,那么导致很多库函数,不需要每次更新版本就更新缓存。这里可以通过webpack 将非业务逻辑代码提取出来单独做一个文件,用文件内容hash 给缓存住。具体做法会使用到 webpack 的CommonsChunkPlugin插件。

Categories: 最新新闻

Tagged as:

knowthis

发表评论

电子邮件地址不会被公开。 必填项已用*标注