前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >前端自动化部署的深度实践

前端自动化部署的深度实践

作者头像
Tusi
发布2020-07-10 16:26:12
1.1K0
发布2020-07-10 16:26:12
举报
文章被收录于专栏:前端司南前端司南

更新日志自动生成

之前我都是手动修改CHANGELOG.md,用来记录更新日志,感觉操作起来有点心累,也不是很规范。好在已有前人种树,于是我就考虑利用conventional-changelog-cli自动生成和更新CHANGELOG.md,真的好用!

什么是conventional-changelog

Generate a changelog from git metadata

根据git元数据生成更新日志,而conventional-changelog-cli则是相关的命令行工具。

安装conventional-changelog-cli

代码语言:javascript
复制
npm install -g conventional-changelog-cli

初始化生成CHANGELOG.md

代码语言:javascript
复制
cd my-project
conventional-changelog -p angular -i CHANGELOG.md -s

以上命令是基于最后一次的Feature, Fix, Performance Improvement or Breaking Changes等类型的commit记录生成或更新CHANGELOG.md。如果你希望根据之前所有的commit记录生成完整的CHANGELOG.md,那么可以试试下面这条命令:

代码语言:javascript
复制
conventional-changelog -p angular -i CHANGELOG.md -s -r 0

工作流

代码添加到暂存区

这一步没有什么特殊,日常撸代码,然后将工作区的内容添加到暂存区。

代码语言:javascript
复制
git add .

规范commit message

一个规范的commit message一般分为三个部分Header,Body 和 Footer。Header包含type, scope, subject等部分,分别用于描述commit类型,影响范围,commit简述。Body则是详细描述,可以分多行写。Footer主要用于描述不兼容改动(Breaking Change)或者关闭issue(Closes #issue)。

格式如下:

代码语言:javascript
复制
<type>(<scope>): <subject>

<body>

<footer>

举个栗子:

代码语言:javascript
复制
feat(支持自动部署): 结合conventional-changelog,配合部署脚本完成部署任务

conventional-changelog是一个很好的工具,用于自动生成changelog,再配上自定义的部署脚本,整个部署流程就显得更规范了

Breaking Change: 比较大的更新
Closes #315

其中,Header是必需的,BodyFooter可以省略。

大致了解规范后,就可以上工具了,这里我们用到的是commitizen

代码语言:javascript
复制
npm install -g commitizen

接着在项目根目录运行以下命令:

代码语言:javascript
复制
commitizen init cz-conventional-changelog --save --save-exact

运行成功后,package.json会新增如下内容:

代码语言:javascript
复制
"devDependencies": {
  "cz-conventional-changelog": "^3.1.0"
},
"config": {
  "commitizen": {
    "path": "./node_modules/cz-conventional-changelog"
  }
}

git commit这一步用git cz替代cz就是指commitizen,通过交互式命令行完成commit操作。

代码语言:javascript
复制
PS D:\robin\frontend\spa-blog-frontend> git cz
cz-cli@4.0.3, cz-conventional-changelog@3.1.0

? Select the type of change that you're committing: feat:     A new feature
? What is the scope of this change (e.g. component or file name): (press enter to skip) 支持自动部署
? Write a short, imperative tense description of the change (max 86 chars):
 (37) 结合conventional-changelog,配合部署脚本完成部署任务
? Provide a longer description of the change: (press enter to skip)

? Are there any breaking changes? No
? Does this change affect any open issues? No
[master ee41f35] feat(支持自动部署): 结合conventional-changelog,配合部署脚本完成部署任务
 3 files changed, 15 insertions(+), 3 deletions(-)

处理版本号,更新CHANGELOG

接着我们要更新npm包的版本号,结合npm versionconventional-changelog使用,可以同时更新CHANGELOG.md

好的,我们先准备好脚本:

代码语言:javascript
复制
"scripts": {
    "start": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "deploy": "node deploy",
    "version": "conventional-changelog -p angular -i CHANGELOG.md -s && git add CHANGELOG.md",
    "postversion": "npm run deploy"
}

根据实际版本情况选择更新patch/minor/major版本。假设我们更新的是minor版本号,那么操作命令如下:

代码语言:javascript
复制
npm version minor -m '特性版本更新'

执行这条命令会更新package.json中的version字段,

同时会执行conventional-changelog -p angular -i CHANGELOG.md -s && git add CHANGELOG.md,更新CHANGELOG.md

执行完这条命令后,可以看到CHANGELOG.md已经被修改了。

CHANGELOG自动更新

npm钩子触发部署脚本

通过postversion钩子触发部署脚本node deploy,开始进行部署工作。deploy.js文件内容如下:

代码语言:javascript
复制
const { execFile } = require('child_process');

const version = process.env.npm_package_version;

execFile('deploy.sh', [version], { shell: true }, (err, stdout, stderr) => {
    if (err) {
        throw err;
    }
    console.log(stdout);
});

这里利用了nodejschild_process模块执行子进程,调用了execFile执行了 deploy.sh,并将npm包版本号作为参数传递给了deploy.sh

deploy.sh文件内容如下:

代码语言:javascript
复制
#!/bin/bash
npm run build
htmldir="/usr/share/nginx/html"
uploadbasedir="${htmldir}/upgrade_blog_vue_ts"
appenddir=$1
uploaddir="${uploadbasedir}/${appenddir}"
projectdir="/usr/share/nginx/html/blog_vue_ts"
scp -r ./dist/. txcloud:${uploaddir}
ssh txcloud > /dev/null 2>&1 << eeooff
ln -snf ${uploaddir} ${projectdir}
exit
eeooff
echo done

以上命令主要做的事情是:

  • npm run build执行构建任务
  • 将构建得到的dist文件夹中的内容通过scp传输到服务器,通过版本号区分各个版本。
  • nginx配置的是监听80端口,指向/usr/share/nginx/html/blog_vue_ts,而我通过软连接将blog_vue_ts再次指向到upgrade_blog_vue_ts下的版本目录,如upgrade_blog_vue_ts/0.5.4。每次发布版本时,以上脚本会修改软连接,指向目标版本,如upgrade_blog_vue_ts/0.6.0,完成版本过渡。

我这里使用了软连接改进了之前的部署脚本,既可以在服务器保留各个历史版本文件夹,也不用考虑处理index.html与静态资源分离的问题。

代码语言:javascript
复制
lrwxrwxrwx 1 root root   47 Feb  3 21:35 blog_vue_ts -> /usr/share/nginx/html/upgrade_blog_vue_ts/0.6.0

linux服务器项目版本文件夹

如果要回退版本,也可以通过修改软连接的方式实现,还是比较方便的。

推送到remote

最后别忘了把代码push到远程仓库。

代码语言:javascript
复制
git push

更新日志changelog查看也变得很方便了,修改了什么内容一目了然,并且可以直接跳转到commit历史,issue等。

github上的changelog

番外

可以看到,我是通过deploy.js调用了deploy.sh。之前本想直接在npm scripts中调用deploy.sh并传入版本号参数的,但是试了几种写法都不行,这里也记录一下。

代码语言:javascript
复制
"deploy": "deploy.sh npm_package_version"
代码语言:javascript
复制
"deploy": "deploy.sh $npm_package_version"

看起来在npm scripts中调用sh脚本时,只能写字面量参数,传变量作为参数好像行不通。

下面这种字面量参数写法是可以的,但是就有点呆呆的感觉了,而且与自动化部署的主题不符。

代码语言:javascript
复制
"deploy": "deploy.sh 0.6.0"

所以我目前还是选择通过deploy.js作为中间者来调用deploy.sh的。

结语

需要承认的是,我以上所述的部署流程是以我的个人项目为例说明,可能不是很规范,但是也算是通过自己的理解和摸索,完整地搞了一套部署流程,并没有借用jenkins等工具。有了这段自动化部署的学习经历后,相信学习和使用jenkins会变得更轻松。接下来我会继续优化和规范自己的部署流程,jenkins理所当然会出现在我的计划表中。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-02-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 bin不懂二进制 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 更新日志自动生成
  • 什么是conventional-changelog
  • 安装conventional-changelog-cli
  • 初始化生成CHANGELOG.md
  • 工作流
    • 代码添加到暂存区
      • 规范commit message
        • 处理版本号,更新CHANGELOG
          • npm钩子触发部署脚本
            • 推送到remote
            • 番外
            • 结语
            相关产品与服务
            命令行工具
            腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档