前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【前端部署十一篇】通过 CICD 实践 Lint、Test、Performance 等前端质量保障工程

【前端部署十一篇】通过 CICD 实践 Lint、Test、Performance 等前端质量保障工程

作者头像
山月
发布2022-05-23 17:21:16
1.1K0
发布2022-05-23 17:21:16
举报

大家好,我是山月,这是我最近新开的专栏:「前端部署系列」。包括 Docker、CICD 等内容,大纲图示如下:

大纲

示例代码开源,置于 Github 中,演示如何对真实项目进行部署上线。

「前端部署」系列正在更新: 11/20


「目录」

  • 1. 任务的并行与串行
  • 2. 使用 Github Actions 进行 CI
  • 3. 将 Install 过程前置
  • 4. 更高级的 CI 检查
  • 5. 与 Git Hooks 的不同
  • 6. 小结

在上一篇章,我们了解到什么是 CICD。

本篇文章通过 github actions 介绍如何通过 CI 进行前端的质量检查。

话不多说,先以一个流程简单的 CI 配置开始,在 CI 中介入以下流程。

  1. Install。依赖安装。
  2. Lint。保障统一的代码风格。
  3. Test。单元测试。
  4. Preview。生成一个供测试人员进行检查的网址。

由于,Preview 是一个较为复杂的流程,留在以后篇章详解,今天先来说一下 Lint/Preview。

我们假设一个极其简单的 Git Workflow 场景。

  1. 每个人在功能分支进行新功能开发,分支名 feature-*。每一个功能分支将会有一个功能分支的测试环境地址,如 <branch>.dev.shanyue.tech
  2. 当功能分支测试完毕没有问题后,合并至主分支 master。在主分支将会部署到生产环境。
  3. 当生产环境出现问题时,切除一条分支 hotfix-*,解决紧急 Bug。

为了保障代码质量,线上的代码必须通过 CI 检测,但是应选择什么时机 (什么分支,什么事件)?

  1. 功能分支提交后(CI 阶段),进行 Build、Lint、Test、Preview 等,「如未通过 CICD,则无法 Preview,更无法合并到生产环境分支进行上线」
  2. 功能分支通过后(CI 阶段),合并到主分支,进行自动化部署。

在 CI 操作保障代码质量的环节中,可确定以下时机:

代码语言:javascript
复制
# 当功能分支代码 push 到远程仓库后,进行 CI
on:
  push:
    branches:    
      - 'feature/**'

或者将 CI 阶段提后至 PR 阶段,毕竟能够保障合并到主分支的代码没有质量问题即可。(但同时建议通过 git hooks 在客户端进行代码质量检查)

代码语言:javascript
复制
# 当功能分支代码 push 到远程仓库以及是 Pull Request 后,进行 CI
on:
  pull_request:
    types:
      # 当新建了一个 PR 时
      - opened
      # 当提交 PR 的分支,未合并前并拥有新的 Commit 时
      - synchronize
    branches:    
      - 'feature/**'

通过 CI,我们可以快速反馈,并促进敏捷迭代。这要求我们使用 Git 时尽早提交以发现问题,以功能小点为单位频繁提交发现问题,也避免合并分支时发现重大冲突。

1. 任务的并行与串行

在 CI 中,互不干扰的任务并行执行,可以节省很大时间。如 Lint 和 Test 无任何交集,就可以并行执行。

但是 Lint 和 Test 都需要依赖安装 (Install),在依赖安装结束后再执行,此时就是串行的。

「而进行串行时,如果前一个任务失败,则下一个任务也无法继续。即如果测试无法通过,则无法进行 Preview,更无法上线。」

PS: 此处可控制某些任务允许失败。如 Github Actions 中的 jobs.<job_id>.continue-on-error1 长按识别二维码查看原文 标题:jobs..continue-on-error

2. 使用 Github Actions 进行 CI

我们写一段 github actions 脚本,用以对我们的试验项目 cra-deploy2 进行 Lint/Test。

长按识别二维码查看原文 标题:cra-deploy

由于 create-react-app 使用 ESLint Plugin 源码3 进行代码检查,而非命令行式命令。

长按识别二维码查看原文 标题:源码

当 ESLint 存在问题时,create-react-app 会「判断当前是否 CI 环境来决定报错还是警告」,而在 CI 中 npm run build 将会报错。

因此,我这里使用 npm run build 来模拟 Lint 检查。

脚本路径位于 workflows/ci.yaml4。 长按识别二维码查看原文 标题:workflows/ci.yaml

代码语言:javascript
复制
# 关于本次 workflow 的名字
name: CI

# 执行 CI 的时机: 当 git push 代码到 github 时
on: [push]

# 执行所有的 jobs
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      # 切出代码,使用该 Action 将可以拉取最新代码
      - uses: actions/checkout@v2

      # 配置 node.js 环境,此时使用的是 node14
      # 注意此处 node.js 版本,与 Docker 中版本一致,与 package.json 中 engines.node 版本一致
      # 如果需要测试不同 node.js 环境下的表现,可使用 matrix
      - name: Setup Node
        uses: actions/setup-node@v1
        with:
          node-version: 14.x

      # 安装依赖
      - name: Install Dependencies
        run: yarn

      # 在 cra 中,使用 npm run build 来模拟 ESLint
      - name: ESLint
        run: npm run build
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Setup Node
        uses: actions/setup-node@v1
        with:
          node-version: 14.x
      - name: Install Dependencies
        run: yarn
      - name: Test
        run: npm run test

关于截图的本次 Action5 执行情况 长按识别二维码查看原文 标题:本次 Action

  • lint 执行了 40s
  • test 执行了 33s
  • 两者并行执行,总共执行了 50s

尽管二者并行执行,但可以把 Install 的过程抽离来减少服务器的并行压力。

3. 将 Install 过程前置

「首先,将 Install 前置会节省服务器资源,但并不会加快 CI 时间。甚至因为多了一个 JOB,Job 间切换也需要花费时间,总时间还会略有增加。」

脚本路径位于 workflows/ci-parallel.yaml6。 长按识别二维码查看原文 标题:workflows/ci-parallel.yaml

在 Lint/Test 需要使用到 Install 阶段构建而成的 node_modules 目录,CI Cache 可在不同的 Job 间共享资源数据。此处先忽略,在下一篇文章进行讲解。

一个 Job 依赖另一个 Job,在 Github Actions 中可使用 needs7 字段。

长按识别二维码查看原文 标题:needs

代码语言:javascript
复制
install:
lint:
  needs: install
test:
  needs: install

完整配置文件如下,关于 Cache 将在下节篇章讲解。

代码语言:javascript
复制
name: CI Parallel
on: [push]
jobs:
  install:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Setup Node
        uses: actions/setup-node@v1
        with:
          node-version: 14.x
      - name: Cache Node Modules
        id: cache-node-modules
        uses: actions/cache@v2
        with:
          path: node_modules
          key: node-modules-${{ hashFiles('yarn.lock') }}
          restore-keys: node-modules-
      - name: Install Dependencies
        if: steps.cache-node-modules.outputs.cache-hit != 'true'
        run: yarn
  lint:
    runs-on: ubuntu-latest
    # 通过 needs 字段可设置前置依赖的 Job,比如 install
    needs: install
    steps:
      - uses: actions/checkout@v2
      - name: Setup Node
        uses: actions/setup-node@v1
        with:
          node-version: 14.x
      - name: Cache Node Modules
        id: cache-node-modules
        uses: actions/cache@v2
        with:
          path: node_modules
          key: node-modules-${{ hashFiles('yarn.lock') }}
          restore-keys: node-modules-
      - name: ESLint
        run: npm run build
  test:
    runs-on: ubuntu-latest
    needs: install
    steps:
      - uses: actions/checkout@v2
      - name: Setup Node
        uses: actions/setup-node@v1
        with:
          node-version: 14.x
      - name: Cache Node Modules
        id: cache-node-modules
        uses: actions/cache@v2
        with:
          path: node_modules
          key: node-modules-${{ hashFiles('yarn.lock') }}
          restore-keys: node-modules-
      - name: Test
        run: npm run test
  preview:
    runs-on: ubuntu-latest
    needs: [lint, test]
    steps:
      - run: echo 'Preview OK'

关于截图的本次 Action5 执行情况 长按识别二维码查看原文 标题:本次 Action

从图中也可以看出 Lint 和 Test 用了更好的时间,然而总时长还略有增加。

4. 更高级的 CI 检查

Lint 和 Test 仅是 CI 中最常见的阶段。为了保障我们的前端代码质量,还可以添加以下阶段。

  • Audit: 使用 npm audit 或者 snyk8 检查依赖的安全风险。可详查文章如何检测有风险依赖9 长按识别二维码查看原文 标题:snyk
  • Quality: 使用 SonarQube10 检查代码质量。 长按识别二维码查看原文 标题:SonarQube
  • Container Image: 使用 trivy11 扫描容器镜像安全风险。 长按识别二维码查看原文 标题:trivy
  • End to End: 使用 Playwright12 进行 UI 自动化测试。 长按识别二维码查看原文 标题:Playwright
  • Bundle Chunk Size Limit: 使用 size-limit13 限制打包体积,打包体积过大则无法通过合并。 长按识别二维码查看原文 标题:size-limit
  • Performance (Lighthouse CI): 使用 lighthouse CI14 为每次 PR 通过 Lighthouse 打分,如打分过低则无法通过合并。 长按识别二维码查看原文 标题:lighthouse CI

5. 与 Git Hooks 的不同

有些细心并知识面广泛的同学可能注意到了,某些 CI 工作也可在 Git Hooks 完成,确实如此。

它们的最大的区别在于一个是客户端检查,一个是服务端检查。而客户端检查是天生不可信任的。

而针对 git hooks 而言,很容易通过 git commit --no-verify 而跳过。

最重要的是,CI 还可对部署及其后的一系列操作进行检查,如端对端测试、性能测试以及容器扫描(见上)等。

6. 小结

本篇文章通过 Github Actions 配置了 Lint/Test,并给出了更多可在 CI 中所做的代码质量检查。

那在 Pipeline 的多个阶段,如何更好利用缓存呢?


参考资料

[1]

jobs..continue-on-error:https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idcontinue-on-error

[2]

cra-deploy:https://github.com/shfshanyue/cra-deploy

[3]

源码:https://github.com/facebook/create-react-app/blob/v5.0.0/packages/react-scripts/config/webpack.config.js#L765

[4]

workflows/ci.yaml:https://github.com/shfshanyue/cra-deploy/blob/master/.github/workflows/ci.yaml

[5]

本次 Action:https://github.com/shfshanyue/cra-deploy/actions/runs/1680667890

[6]

workflows/ci-parallel.yaml:https://github.com/shfshanyue/cra-deploy/blob/master/.github/workflows/ci-parallel.yaml

[7]

needs:https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idneeds

[8]

本次 Action:https://github.com/shfshanyue/cra-deploy/actions/runs/1680667891

[9]

snyk:https://snyk.io/

[10]

如何检测有风险依赖:https://q.shanyue.tech/engineering/742.html#audit

[11]

SonarQube:https://www.sonarqube.org/

[12]

trivy:https://github.com/aquasecurity/trivy

[13]

Playwright:https://github.com/microsoft/playwright

[14]

size-limit:https://github.com/ai/size-limit

[15]

lighthouse CI:https://github.com/GoogleChrome/lighthouse-ci

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

本文分享自 全栈成长之路 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 任务的并行与串行
  • 2. 使用 Github Actions 进行 CI
  • 3. 将 Install 过程前置
  • 4. 更高级的 CI 检查
  • 5. 与 Git Hooks 的不同
  • 6. 小结
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档