现在前端把戏越来越多了,今天我要谈的并不是什么别致的东西了,主动化构建布置嘛,假如你是一个 Javaer 或许 运维同学,关于 Jenkins 之类的主动化布置必定不陌生。不过也说到过了,作为一个前端,特别是业务驱动的开发来说,平时必定是很少接触这些东西的。笔者也是最近才打算前端主动化布置上容器,然后学习看了看,接下来就把学习进程和小总结给咱们共享共享,a f / D l ~ r很浅显,大牛直接右上角(左上角)封闭就能够了。

我写文章的主旨便是,把自己走过的弯路总结给咱们,f G ! 0 h防止你们踩坑I d y x 1 {,不 u f h图你们点赞,少喷就好。由于确实经历过很屡次“文章千百万,实践就完蛋”的场景太多了,咱们也不对读者负责,所以我的文章一般都会有代码和 Demo 示例,做不^ 5 c ~ 5 c y到最好可是至少假如你遇到过相同的问题t G ; a,必K ` M 7定能解决~

前置

  • Gitlab
  • Gitlab Runner
  • Docker

上面归于前置内容,Gitlab 就不用说了吧,一般公司内部运用的都是 Gitlab 库房;Gitlab Runner,一般需求额定装置,预先编写的主动化构建布置的脚本(后面会介绍到)便是由它来运转的: m k T K % _ d;最后,项目要打包成镜像布置到容器上,所以也需求 Docker。r = M g v e 3 f C

由于是公司内部流程不是自己单独玩耍,所以让运维c C _ [ c V ;大大替你搞定就能够了,现在这个时代在公司运用应该都是默认会有的了。个人= 1 / x / [P & c + z n .目或许大概率应该是放在 Github 上的,小伙伴们能够挑选 Github Actions,网上有许多教程。

新建一个项目

crea3 4 5 hte-react-app 为比方简略介绍一下,主动化构建布置然后生成 Gitlab Pages。首要,咱们新建一个项目推送到长途库房:

Gitlab CI — 前端自动化构建部署

.gitlab-ci.yml — 初始化

在运用 Gitlab CI 进行主动化构建布置的时分,需求新建一个 .gitlab-ci.yml 装备文件,里边是咱们主动化构建的详A : 8 o _ 8细步骤的脚本,这儿先简略的进行初始化一下,下面会详细; X X a f介绍:

# 界说阶段 stages
stages:
  - build
  - deploy
# 界说 job - build 项目
job1 - build 阶段! 9 M ( = 3:
# 开端之前需求装置依靠
  stage: build
  script:
    - echo "finisu 6 Gh build stage"
# 界说 job
job2 - 发布到线上环境:
  stage: deploy
  script:
    - echo "finish deploy stage"

U i K a 1面装备文件大体意思便是,此项目的主动构建大致分为两个阶段,分别是 build 和 deploy 阶段,而且每个阶段都会履行一些相应的使命,这儿由于是初始化演示,仅仅简略的进行了两行文本输出,而且字段意义咱们也不需求知道,下面会详细介绍。

将文件推送上去,检查作用:

Gitlab CI — 前端自动化构建部署

从图中能( 0 2 `够看出,成功推送到长途,接下来点击: CI/CD -> pipelines

Gitlab CI — 前端自动化构建部署
Gitlab CI — 前端自动化构建部署
Gitlab CI — 前端自动化构建部署

从上图能够看到,项目的主动化构建就完成了,你或许会问了,这么简略?其实便是这么简略,尽管我9 @ ) C r ^ L将构建内容简化成了两行输出,可是整体流程其实是不变的,无非便是构建进程复杂化,增加脚本内容罢了。接下来,就用此比方,一步一步加深了解 Gitlab CI。

Gitlab 中 YAML 相关概念解析

前面说到了,一切的构建布置内容g d z 8 K a都是写在 .gitlab-ci.yml 脚本@ F n ` X B N ,里履行k I n s $ i的,因此,此文件的内容写法以及各个关键字对应的意义,6 w X & x w是首要要了解的。

官方文档在此,我仅仅官方文档的筛选搬运工,咱们也能够自己去《有道词典》翻译。

关键字 Reqired 描绘
image 运用 Docker 镜像
service 运用 Docker 服务
stages 界说构建阶段
t2 f ) 1 x 5 N X 2ypes stages 别名(建议+ + 8 x E 4 .只运用st| 2 +ages,现已被废弃)
before_script 每个脚本使命履行之前履行的脚本
after_scriptw R i 每个脚本使命履行之; q y e o ? k后履行的脚本
variables 界说变量,能够在0 9 0 v a B +构建阶段运用
cache 界说缓存文件[ I 5 ) q l c r #,能够在后面阶段运用到

job

job.gitlax } Q g D : Cb-ci.yml 里的尖端元素了,任何主动# ! W L 7 $ D 6化布置都必须有的,个人认为能够将它分红使命,每个使命里至少包括一条脚本表J w v `明在此使命里要做的事情。能够界说多个 job 而且每一个 jJ + dob 之间都是相互独立的,job 会被 Gitlab Runner 在自己的环境下履行。

# 界说 job1
job1:
  script:
    - echo "i'm job1"
# 界说 job2
job2:
  script:
    - echo "p # E J c u 6 _ wi'mT e x 8 # 7 [ job2"

上面是最简略的示例,界说了两个 job,每个里边有一个脚本执输出一段字符M 2 6 b串。

【留意】: 前面说到过r e I qjob 是尖端元素,i 4 : r m l = ^它的命名也很宽泛,${string}:字符串 + 分号(不限中英文3 R B)即可,可是上面表格说到的各个关键字是不能被界说成 job名 的。

image && services

由于 Gitlab Runner 也是运用 Docker 进行构建的,因此能够在# h D y x _构建咱们代码的时分也运用相应的镜像进行根底构建。对应字段便是 imageservices,先来看看官方给的简略示例:

# 根底镜像
image: ruby:2.1
# 运用镜像 service - postgres
services:
  - postgres

接下来咱们看看咱们自己的项目,咱们是一个基于 create-react-ap) h P G } y vp 构建的项目,所以依靠的必定是 node 镜像,服务不需求能够不写,由于是可选项。

# 依靠镜像 node
image: nod! O G 3e:10.16.0
# 界说阶段 stM 1 ~ages
stages:
  - build
  - depl8 v u U yoy
# 界说 job - build 项目
job1 - build 阶段:
# 开端之前需求装置依靠T G I
  stage: build
  script:
    - echo "finish build stage"
# 界说 job
job2 - 发布到线上环境:
  stage: deploy
  script:
    - echo "finish deploy st} s K h ,agL u (e"

上面,咱们增加了镜像依靠,而且拟定版本号是v10.16.0

stages

这个字段也挺重要的,我觉得O ? & 4 2 3能够翻译为为构建阶段,比方咱们的项目分为两阶段,第一个阶| z A R W d u段是 build — 编译打包,第二个阶段是 deploy — 发布上线。其实也便是对应两个p x e b job,然后鄙2 O L j人面对每一个阶段更详细化的描绘。

s| P ~ / T x Gtages 字段界说O N 7 j B B O ) A的几个阶段在 pipelines 构O R O O D C 9建进程中顺序是一致的,而且有如下规律:

  • 前一阶段完成,后一阶段履行

也便是说,build 成功了,deploy 才会履行。

  • 一切阶段悉数成功,整个 pipelines 进程悉数标记为 pQ } ) v 9 Y ~ H ^ass,整个构建才是成功
  • 其中一个6 n * a阶段失利,pipelines 后续流程不会被履行,整个构建标记为失利。

详细履行进程咱们能够在 pipelines 里检查到,如下图所示

Gitlab CI — 前端自动化构建部署

sB ) 7 1 ~cript

这个也算是最重要的一1 N M k c个字段了,它表明由 Gitlab Runner 履行的一段 shn O n yell 脚本,在构建项目进程中必定是要履行许多指令的,比方装置依靠、打包、布置等指令。仍是以咱们的项目为例,7 8 o新增了 node 镜像,这就意味着能N m H &够履行 npm installnpm run build等指令了。

# 依靠镜像
image: node:10.16.0
# 界说阶段 stages
sta. Z V jgesM H T _ e:
  - build
  - deploy
# 界说 job - build 项目
job1 - build 阶段:
# 开端之前需求- : * G # Z g ; J装置依靠
  stage: build
  script:
    - yarn install
    - yarn build
    - echo "finish build stage"
# 界说 job
job2 - 发布到线上环境:
  stage: deploy
  script:
    - echo "finish deploy stage"

在上面,咱们在 job1 里新增了两个指令 yarn installyarn build两条指令,熟悉前端开发的应该都知! U * 4 o q E ) N道,项目生产之前要装置依靠和打包编译。接下来推送到长途库房来看看作用:

  • 构建成功
Gitlab CI — 前端自动化构建部署
  • 第一步的构建内容x P e 6 W 3
Gitlab CI — 前端自动化构建部署

从上方截图能够看的出来,推送上去的代码再次触发主动构建,构建成功而且第一步 build 阶段里边顺次履行了咱们编写的三个脚本内容,十分完l _ V ^ J美~

before_script 和 after_script

这两个字段意义就跟字面意义一致,before_script — 脚本履行之前履行的脚本,after_script — 脚本履行; j c | J之后履行的脚本。

这儿或许有人会说B x a了,那么把 yarn install 安依靠的脚本指令放到 before_script里岂不是愈加适宜,这样 build 阶段只做 build 指令,愈加恰当。答案是不可的,由于这两个指令是在外层,意思是每一个阶段之前都履行一次,也便是说,每j U 0 I x q I m $一个 job 里都会先履行 b[ Y t n wefore_script 然后再履行自己界说的 script 脚本,而事实上咱2 2 K c byarn install 只需求履行一次。

我思来想去想} d – g l w找一个D o C } ,最佳场景去演示,可是感觉用到的场景确实很少而且也都不是很恰当,当然q M * – $ d,假如仅 h n j仅为了了解功用,那么输出一个字符串就行了,这儿我觉得国内能够在 before_scriptW l = N ) : w –设置下淘宝镜像。

# 依靠镜像
image: node:10.16.0
be4 i 2fore_scripU / V { = %t:
  - echo "======== before script ========"
  - npm config set regM b g p Q 0istry https://regq b u ?iste q 1 i W $ qry.npm.taobao.org
after_script:
  - echo "=======v $ p 7 o= after scrip% | y t Dt ========"
# 界说阶段 stages
stages:
  - build
  - deploy
# 界说 job - build 项目
job1z M X 1 V w - build 阶段:j F 6 * m E . z
# 开端之前需求装置依靠
  stage: build
  script:
    - yarn install
    - yarn build
    - echo "finish build stage"
# 界说 job
job2 - 发布到线上环境:
  stage: deploy
  script:
    - echo "finish deploy stage"

来看看作用:

  • bd _ 2 N E E 8 $ Nuild 阶段
Gitlab CI — 前端自动化构建部署
  • Deploy 阶段
Gitlab CI — 前端自动化构建部署

能够看到确实如描绘所A Z V C | J D言,这两个脚本每个构建阶段 — stage 都会履行。

only && except

接下来这两个关键字也很重要了,咱们先来看一下比方:

  • 第一步,新建/ e , ^ l H , G %一个分支:branch-a
  • 第二步,修正内容推送到长途
Gitlab CI — 前端自动化构建部署
Gitlab CI — 前端自动化构建部署

先别管是否构建成功了,现在就出问题了。为啥?咱们研讨的是主+ % q [ + o动化构建布置上线,那么必定是应该有上线标准的,你不能每个分支每次 push 到长; u ` B V :途都触发构建吧,必定不可啊。这时分,only 和k P 5 3 s ] k / f except 就派上用场了。

  • only:只允许契合条件的触发构建
  • except:除了某些内容,都会触发构建r P p

这儿为了演示,我约定的是,只要e d y b e J masterC F 9 的 push 会触发,只要 master 分支代码变化了,才会触发构建。

# 依靠镜像
image: node:10.16.0
before_script:
  - echo "======== bew * Ufore script ========"
  - npm coZ / # s b o y 3 %nfig set rel d / X U f / {gistry https://registry.npm.taobao.org
after_script8 , * n U ` P P:
  - echo "=====H ] K=== after script ========"
# 界说# m D ( { D p x l阶段 stages
stages:
  - build
  - deployz D J
# 界说 job - build 项目
job1 - build 阶段:
# 开端之前需求装置依靠
  stage: build
  script:
    - ya*  ; 8rn install
    - yarn build
    - echo "finish build stage"
  only:
    - master
# 界说 joq R 7 O j B 1 * )b
jh f v p Bob2 - 发布到线上环境:
  stage: deploy
  script:
    - echo "finish deploys $ ] stage"
  only:
    - master

【留意】:only 字段是需求每个 job 阶段都要单独界说的,由于不能保证你每个阶段对应的要求是什么。

将代V O k ] k 7 c _码推送上去,现已不会触发主动构建了,咱们再来验证一下,在 branch-a 分支提一个 MR 然后合并到 master,看看作用。

  • Merge Request
Gitlab CI — 前端自动化构建部署
  • Merge && CI
Gitlab CI — 前端自动化构建部署

能够看到,分支提交并不会触发 CI,而 Merge 到 master 之后会触发,达到预期。

关于 only 和 except 相关内容其实还有许多,比方特定分支,特定 tag 等等。这儿就不做过多赘述,总归便是能够满意你任何复杂场景和操作,你自己去组合就好了。

variables

望文生义,便是变量,咱们能够预先界说+ ; $ a b ?好一些常用的变量,然后在 job 的脚本里运用它们,一个简略的比方:

variables:
    DOCKW Y ! . $ , y :ER_HUB_URL: "https://custom.dockerhub.com/ { i & * Y"
# 界说 job - build 项目
job1-build:
# 开端之前需求装置依靠
  stage: build
  script:
    - yarn install
    - yarn build
    - ec( f + F [ b m t /ho $DOCKER_HUB_URL
    - echo "B ^ b f Vfinish build stage"
Gitlab CI — 前端自动化构建部署

除了自界说的变量之外,系统还内置了许多常量:详细检查这儿

artifacts

这个参数也是十分重要的一环,它的作用是能够在当时 job 构建成功之后,将构建列表里的文件或许文件夹传递给其他的 job(不一定便是下R 9 A 5 i一个 job),也便是说在两个 job 之间进行传递文件内容。

为什么说它重要呢,咱们先来看看比方,咱们在 job2 中新添加一个指令,检查当时构建目录:

# 界说 job7 } B C k
job2 -6 N r b E v J 发布到线上环境:
  stagej 6 r M k: deX a 3 . d * C r =ploy
  script:
    - ls
    - echo "finish deploy stage"
  only:
    - mas, ` z N - V %ter

输出成果如下:

Gitlab CI — 前端自动化构建部署

咱们会发现一个问题,在| P } job2 里获取v U V ^ B 4 V的仍是库房 master 里的内容,这意味着什么,假如你了解 React 应该知道,create-react-app打包之后会生成一个 /build 文件夹,此文件夹里边的内容$ q W k 9 R一般来说便是最终的上线| T e * t K ` s内容。可是咱们分明在 job1 里边 build 了,而且 job1 build 成功了,也便是说需求把 job1 build 成功过后的文件夹 /build 传递给 job2,所以此刻也就用上了 artifacts

# 依靠g J i x s A { p镜像
image: node:10.16.0
before_script:
  - echo "======== before script =======3 o 2 i="
  -? T 4 E [ H ! s npm config set registry https://registry.npm.taobao.org
after_script:
  - echo "======== after script ========"
# 界说阶段 stages
stages:
  - build
  - deploy
# 界说 job - build 项目
job1-build:
# 开端之前需求装置依靠
  stage: build
  script:
    - yarn install
    - yarn build
    - echo "finis| F & I f sh build stage"
  only:
    - master
  artifacts:
    paths:
        -B L 9 K # build/
# 界说 job
job2-deploy:
  stage: deploy
  scripV 4 ` v vt:
    - ls
    - echo "finish d] E 5 V {eploy stage"
  only:
    - master
  dependencies:
    - job1-build
  • job1-4 0 4build

Job1 新增的 artifactK ! d g 5 =s 里边设置 paths: build/ 文件夹。

  • job2-deploy

Job2 新增 dependenc* O A P z G u 9 Uies: job1-build,表明此 job 依靠 job1-build 传递过来的 artifacts 内容。

推送到长途检查作用:

Gitlab CI — 前端自动化构建部署

从上图能够看出,job2 现已能够获取到 job1 构建成功之后生成的 /build 文件夹了。

.gitlab-ci.yml

最后的装备文件如下所示:

# 依靠镜O A o
image: node:10.16.0
before_script:
  - echo "======== before script% ^ q E M q | M d ========"
  - npm config set registry https://registry.npm.tao# y L 6 T z ebao.org
after_script:
  - echo "======== after script ========"
# 界说阶段 stages
stages:
  - build
  - deploy
# 界说 jm Q _ bob - build 项目
job1-build:
# 开端之G N - V前需求装置依靠
  stage: build
  script:
    - yarn install
    - yarn! C P * G { O u 0 build
    - echo "finish bZ f q #uild stage"
  only:
    - master
  artifacts:
    paths:
        - build/
# 界说 joby * Z 3 0 5
job2-deploy:
  stage: deploy
  script:
    - ls
#######
# 这儿能够对项目. f i n S 2 7 s ,进行真实的发布
#######
    - echo "finish deploy stage"
  only:% ! h 9 ` ` .
    - master
  dependencies:
    - job1-build

其实真实的主动化构建布置上线也@ J 0 = p Z便是在 job2-deploy 里边再新增更复杂的脚本罢了,比方笔者做的便是打包 docker 镜像推送到 docker hub 然后经过 k8s 布置项目。J f C ) Q z O O当然,也能够增 D f z 5 G ! –加 stage 和 job,详细细节每个人每个公司都不一样,咱们能够自行修正。

项目构建流程系统准则

前面介绍完基本上前端使用 Gitlab UI 就能够进行简略的主动化布置上线了,只不过在公司多人开发的时分要标准一些,下面是我个人(个人看法,不喜勿喷)觉得比较标准化的合理流9 k ) t Y z ] 程。

  • 并行开发项目,每次上线 master 分支
  • 基于 master 分支新开分支开发(单人 && 多人)
  • 分支开发结束预备上线前提 Merge Request,code-review 没问题后由 Masters 进行 Mef ? + + L u ; * Vrge 到 master
  • master 分支改变触发 Gitly C ; 5 { n hab CI 主动构建布置上线(E } 9 ;上线失利回滚也是主动触发)

因此,Gitlab 项目装备应该是如下:

  • master 分支在新增完l f – .gitlab-ci.yml @ h t 5 / !后设置不允许 push
  • master 分支只能够由管理: 9 C x j员经过 Merge Request 进行代码的合? q u & g D h 8 [
Gitlab CI — 前端自动化构建部署

总结

很浅显的一篇文章,仅仅为了让咱们能简略了解前端主动化构建,以及个人的一些小小总结。更深层次的比方Gitlab Runner和实际项目的Docker布置由于因人而异,也并不是一切人都用 Docker 布置前端,所以没过多介绍,我觉得作为入门了解 Gitlab CI 还 OK~