如何利用webpack进行项目的发布记录管理

需求分析

  我们在做一个项目过程中会遇到很多版本的迭代;这就会有很多的上线记录等着我们去做管理,在一些线上事故到来之际第一时间能够找到对应的版本回滚;

  我们之前的做法是在全局window下面挂载一个Gdata对象,把每次发版的版本号记录上去;然后利用confluence去记录每次发版信息,比如作者、发布时间、对应的发布包名称;我个人觉得不失为一种很好的方案,但是借助第三方工具跟项目本身有了脱离。比如:打包完了项目,又要在confluence上记录下;动作一旦切换过多,其实很是比较反感的;所以我在看到webpack内置BannerPlugin插件的时候自己产生了一些想法。

  BannerPlugin插件的作用就是在打包后的代码头部插入一些说明文字,那能不能动态的将本地的.md插入到代码中呢;这样我们根据本地的文件与线上说明做一个对应起来;

要解决的几个问题
  1. 如何能够很好的将本地的md文件与插入的说明进行对应
  2. 如何进行.md文件的获取
  3. 如何解析.md 文件的内容
  • 如何能够很好的将本地的md文件与插入的说明进行对应

  从我们要记录的内容出发,我们要记录的主要是时间、发布者、内容;从时间上看就是每天的时间;于是我们可以在项目生成一个notes文件夹;里面的结构如下:

└── notes
    ├── 202003
    │    ├── 0330.md
    │    └── 0331.md
    ├── 202004
    │    ├── 0401.md
    │    └── 0402.md
  • 如何进行.md文件的获取

  原本想着直接用require()去载入这个文件,但是node不支持直接这么引入;于是想用fs模块readFile去读取这个文件内容;但是读取是异步操作;还是不能解决这个问题;好在还有个同步读取文件的方法fs.readFileSync;于是读取的问题得到了解决;根据计算得出要读取的md文件fs.readFileSync(./notes/${format(new Date(),'yyyyMM')}/${format(new Date(),'MMdd')}.md,'utf8')

  • 如何解析.md文件

  解析.md文件,原本想找一个现成的插件;但发现大多数是解析成html或者vue的;于是我就自己把这个.md文件内容进行了字符串解析;不过我这里的md文件内容是有规范要求的;

#### 需求发布记录
- 完成banner的构建
    1. author:devin
    2. daytime:20200331
    3. content:具体的需求描述
- 改动了公共配置
    1. author:devin
    2. daytime:20200331
    3. content:具体的需求描述
    测试
    222

解析代码如下:

  const fs = require('fs');
const getMdText = () => {
    let returnValue = {};
    fs.access(`./notes/${format(new Date(),'yyyyMM')}/${format(new Date(),'MMdd')}.md`, (err) => {
        if(err) return;
        const mdText = fs.readFileSync(`./notes/${format(new Date(),'yyyyMM')}/${format(new Date(),'MMdd')}.md`, 'utf8')
        let result = mdText.split('\n'); // 解析出md文档返回每一行可字符串
         // 每次取最后一条记录,一般最后一条记录是最新的
        const last_index = findLastIndex(result, item => {
            return item.includes('-')
        });
        const splice_target = result.splice(last_index);
        for (let i = 0; i < splice_target.length; i++) {
            let curStr = splice_target[i].trim(),
                nextStr = i + 1 < splice_target.length ? splice_target[i + 1].trim() : '.';
            let cur_isDot = curStr.includes('.'),
                isTitle = curStr.includes('-'),
                next_isDot = nextStr.includes('.');
            // 找到 -
            if (curStr.includes('-')) {
                returnValue['title'] = curStr.replace('-', '').trim();
            }
            // 找到 .
            if (cur_isDot && next_isDot) {
                let keyValue = curStr.split('.')[1].split(':');
                returnValue[keyValue[0].trim()] = keyValue[1].trim();
            }
             // 空行情况, 处理如果一个. 下面有多个空行情况,进行拼接
            if (cur_isDot && !next_isDot) {
                let currentIndex = i + 1,
                    isnextDot = splice_target[currentIndex].includes('.');
                while (!isnextDot && currentIndex < splice_target.length) {
                    curStr += splice_target[currentIndex].trim();
                    currentIndex++;
                }
                let keyValue = curStr.split('.')[1].split(':');
                returnValue[keyValue[0].trim()] = keyValue[1].trim();
            }
        }
    });
      // 返回一个对象 {title: '改动了公共配置',author: 'devin',daytime: '20200331',content: '具体的需求描述测试222'}
    return returnValue;
}
最后就是打包生成banner
  • 我们可以忽略一些具体的修改记录打包到banner中;
     new webpack.BannerPlugin({
      banner: () => {
        let str = ' ';
        Object.keys(md).map(key => {
          if (key !== 'content') {
            return str += md[key]+' '
          }
        })
        return str;
      }
  • 效果代码
    /*!  改动了公共配置 devin 20200331  */ ! function (e) {...}(...)
  • 最终的目的就是根据线上的代码的banner信息,在项目里找到对应的文档;




    项目地址
posted @ 2020-05-16 16:17  Devin_n  阅读(268)  评论(0编辑  收藏  举报