Node.js 项目持续集成实践

Catalogue
  1. 1. 实现的效果
  2. 2. 实现细节
    1. 2.1. 测试
    2. 2.2. 构建
    3. 2.3. 部署
  3. 3. 解决工作中场景中哪些痛点
  4. 4. 思考

前端开发流程( 语法检查、编译、重载)的自动化我们在工作中已经用得比较溜了,这篇文章主要介绍 Node.js 应用部署到服务端过程(编译、测试)的自动化。

这里以开源的 API Mock 系统 AMP 的部署为例( https://iffe.leanapp.cn ),通过这套系统提供的 mock 服务,前端可以在接口定义完毕后就着手开发,与后端接口开发并行以提升项目整体效率。接口支持 CORS 跨域访问、支持 HTTPS 访问,为前端开发,尤其是移动端开发带来便利。

实现的效果

本地开发代码,提交到 gitlab 的 master 分支后自动测试和编译,并将编译结果提交到可部署生产的 built 分支,需要的时候一键发布生产。

实现细节

这里用到 gitlab.com 提供的私有代码托管和 git-ci 服务,以及 leancloud 的云引擎。gitlab.com 提供的服务可以使用自己搭建的 gitlab 替换。提供与 leancloud 类似云引擎功能的网站,市面上也不少,这里因为其免费策略合理所以采用,拿它们举例适用性较广。

首先我们要在项目根目录添加 gitlab-ci.yml 文件,用于描述持续集成的过程,分三个阶段:

测试

只需要执行 Node.js 应用的测试命令: npm test

1
2
3
test:
script:
- npm test

构建

执行 Node.js 应用的构建命令: npm run build

1
2
3
build:
script:
- npm run build

部署

1
2
3
4
deploy:
stage: deploy
script:
- . deploy.sh # 为了方便脚本执行上下文控制,我们将命令写到 deploy.sh 中

deploy.sh 脚本完成两件事:

  1. 执行编译命令
  2. push 编译代码到 built 分支

完整配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# .gitlab-ci.yml
image: node:6
# 缓存安装后的 node_modules ,以加速下次构建
cache:
paths:
- node_modules/
before_script:
- npm i -D # 所有任务执行前都会执行该脚本,用于安装所有依赖包
# 添加 ‘build' 任务,描述构建任务的执行
build:
stage: build # 定义所属阶段
script:
- npm run build # 需要运行的脚本
only:
- build # 'build' 任务仅影响 'build' 分支
# 添加 'test' 任务, 描述测试任务的执行
test:
stage: test # 定义所属阶段
script:
- npm run test # 需要运行的脚本
except:
- master # 'test' 任务影响除 'master' 分支之外的所有分支
# 添加 'deploy' 任务, 完成构建和部署
deploy:
stage: deploy
script:
- . deploy.sh # 需要运行的脚本
only:
- master # 'deploy' 任务仅影响 'master' 分支

由于测试任务由除 master 之外的分支的 push 触发,而部署任务完成后,将编译结果 push 到 built 分支。所以我们 push 到 master 后,会先执行部署任务,部署任务完成后,执行测试任务(如下图)

push 操作触发部署、测试任务

任务执行结果:

执行结果

有了构建好的代码,就可以部署到 leancloud 了,部署前我们需要告诉 leancloud 代码库地址,并将 deploy key 信息保存到 gitlab 的项目配置中。这样以后 leancloud 就可以凭 deploy key 向 gitlab 库拉取代码。

在 leancloud 上的“常规设置“中填写代码库地址,并获取 `deploy key`

在 gitlab 上项目的“Deploy Keys“中填写上一步获取的 `deploy key`

两边信息配置完毕,就可以开始部署,在“部署”面版填写“分支或版本号“为 built 即可。

在 leancloud 云引擎中选择 built 分支部署

如果一切顺利,部署成功后就可以访问应用了。

部署完成访问应用

(请注意:演示系统虽然功能 ok,但是运行环境为 leancloud 免费版云引擎,配额受限,请 不要 在实际项目中使用, 请使用大师在内网环境部署的。)

解决工作中场景中哪些痛点

  1. 无缝版本切换,实现“为跑道上飞驰的赛车更换零件”——在 leancloud 部署应用到生产环境的过程中发现一个有意思的细节,就是新版本构建出问题并不影响线上服务。大致过程类似于在一台新服务器上运行好版本代码,然后把流量从上运行上一版本代码的服务器切过来,在此之前会检测配置的端口是否正常相应请求,如果不是就终止切换,并提示发版失败,发版成功则把“旧版服务器”做存档,以供后续版本回退。有了这一机制,发版本就可以选择最适合业务的时机,而不是非要等到用户量最低的时候,“他好我也好” 😝

  2. 提前暴露编译配置的问题,实际项目中更改生产构建配置,往往改完当时验证没问题后就不太会留意,而等到真正发版前的一段时间项目文件变动可能产生预料外的问题,这时发现再解决就占用了本已紧张的发版时间,而且需要定位产生问题的代码,这问题在多人协作以及长周期的版本尤其突出。而引入持续集成后,每次 push 将会触发测试环节,在这里加上构建测试,通过测试结果即可及时发现问题并处理。

  3. 提升开发体验,将一部分消耗资源、重复的、机械性的任务如全量编译,交由持续集成服务器完成,以节约开发机资源,让开发者专注于开发而不受打断。能有空伸个懒腰,发发呆不再是奢求。

思考

探索“云计算”、”微服务”这些新热技术在前端开发领域的应用场景,对理解“小而美”产品(快速迭代、小步快跑的同时保持新集成特性的稳定输出)存在的基础(支撑点),有推导和借鉴意义。

短期内切换应用部署方案显然并不现实,但这并不构成拒绝拥抱变化的充分条件,毕竟技术的发展不因主观意愿而转移,而去中心化和原子化(把功能和服务内聚为模块)显然是日益突显的两个特征。实际上下半年组内在一些项目中切换 git 做版本管理,并将暴露的问题解决得七七八八已是一个不错的开端。


“ 我觉得套路和扯皮救不了中(cheng)国(xu)人(yuan),但技术储备可以 ”

我没说过这句话——鲁迅

Share Comments