You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

96 lines
10 KiB
Markdown

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 19 | 实战痛点5如何打包发布你的Vue 3应用
你好,我是大圣。
在实战痛点4这一讲中我们一起学习了Vue 3项目的性能优化策略。今天我们来聊一下项目上线前的最后一步就是如何把开发好的代码部署到线上。
对于这个问题,你可能脱口而出:“使用`npm run build`就好了呀”。这样做只是在本地把代码打包,如果想要在线上也可以访问这些代码,那么还需要加上部署的过程。所以在下面,我先给你介绍一下当前这个时代的前端代码在部署的时候,有哪些难点和问题需要处理。
## 代码部署难点
在jQuery时代之前前端项目中所有的内容都是一些简单的静态资源。那个时候网站还没有部署的概念网站上线前我们直接把开发完的项目打包发给运维再由运维把代码直接上传到服务器的网站根目录下解压缩这样就完成了项目的部署。
后来的jQuery时代项目的入口页面被后端管理模板部署到了后端CSS、JavaScript和图片等静态资源依然是打包到后端之后再解压处理。但现在我们对前端的性能和稳定性的要求也越来越高jQuery时代的那种简单的部署模式就不足以应对性能优化、持续部署等一系列的情境。
现在前端所处的时代我们主要会面临后面这些代码部署难点首先是如何高效地利用项目中的文件缓存然后是如何能够让整个项目的上线部署过程自动化尽可能避免人力的介入从而提高上线的稳定性最后项目上线之后如果发现有重大Bug我们就要考虑如何尽快回滚代码。
当我们面对这些代码部署上的难点,特别是在团队协作的项目中遇到时,我们就可以考虑对项目进行自动化部署了,这样代码部署的速度和稳定性会给项目研发效率带来很好的提升。
## 项目上线前的自动化部署
下图所示的,是大部分团队部署项目时的逻辑 。实际上大部分前端开发者都会认为完成图示中的打包压缩这一步也就是开发完项目之后代码推送到GitHub后就算完成任务了。但是打包代码之后把代码上传服务器也是这一步对于前端开发者来说是很少能接触到但却是很重要的一步。
![图片](https://static001.geekbang.org/resource/image/45/a9/4565abf4f599cc187d65d421d3cb8ba9.jpg?wh=1800x758)
所以,对于如何把打包好的代码上传到服务器这个问题,就值得我们去好好探究,琢磨出一个好的解决方案。
首先我们需要一台独立的机器去进行打包和构建的操作这台机器需要独立于所有开发环境这样做是为了保证打包环境的稳定之后在部署任务启动的时候我们需要拉取远程的代码并且切换到需要部署的分支然后锁定Node版本进行依赖安装、单元测试、ESLint等代码检查工作最后在这台机器上执行经过编译产出的打包后的代码并打包上传代码到CDN和静态服务器。当然了完成这些操作之后还要能通过脚本自动通过内部沟通软件通知团队项目构建的结果。
但是在项目部署的过程中迎面而来的可能是下面这些问题在什么操作系统环境中执行项目的构建由谁触发构建如何管理前面所述的把代码上传CDN时CDN账户的权限如何自动化执行部署的全过程如果每次都由人工执行就得消耗一个人力守着编译打包了而且较为容易引发问题比如测试的步骤遗漏或部署顺序出错。那么如何提升构建速率就成了部署功能中需要解决的重要问题。
为了解决上面这些问题业界提出了一些解决方案比如采用能保证环境一致性的Docker自动化构建触发可以通过GitHub ActionsGitHub的actions功能相当于给我们提供了一个免费的服务器可以很方便地监控代码的推送、安装依赖、代码编译自动上传到服务器。
![](https://static001.geekbang.org/resource/image/a7/dc/a7b8b0005f6003e91d17eb18149b9ddc.jpg?wh=2251x1206)
上图所展示的就是我们使用了GitHub Actions部署项目之后的项目开发流程。现在静态资源管理已经完成也实现了自动化部署。提交代码之后我们的项目就可以自动推送到服务器这样网站的第一次上线也就算成功了。
## 项目上线后的自动化部署
前端项目的自动化部署完成后,我们可以保证上线的稳定性,但是后续的持续上线怎么办?直接发到生产环境,会面临极大的风险。但如果不直接发布到生产环境,我们就不能在本地和测试的前端环境去连接生产环境的数据库。
所以我们需要一个**预发布的Pre环境**,这个环境只能让测试和开发人员访问,除了访问地址的环节不同,其他所有环节都和生产环境保持一致,从而提供最真实的回归测试环境。
这个时候我们会遇见下面这些问题首先如果我们确定项目下个版本在下周一零点发布那我们就只能晚上12点准时守在电脑前等待结果吗如果npm安装依赖失败或者上线后发现了重大Bug那就只能迎接用户的吐槽吗
其次,**随着node\_modules的体积越来越大构建时间会越来越长**。如果每次构建都需要30分钟甚至更长时间的话那么即使Bug是在项目刚上线时就发现的并且你也秒级响应并修复了Bug但在重新部署项目时我们也需要等服务器慢慢编译。这个时候时间就是金钱如果你在修复Bug和重新部署项目上耗费了过多的时间那么就会导致项目故障时间过长的问题。
为了解决上面说到的这些问题,我们需要一种机制,能够让我们在发现问题之后,尽快地将版本进行回滚,并且在回滚的操作过程中,尽可能不需要人力的介入。所以,我们需要静态资源的版本管理,具体来说,就是让每个历史版本的资源都能保留下来,并且有一个唯一的版本号,如果发生了故障,能够瞬间切换版本。这个过程由具体的代码实现之后,我们只需要点击回滚的版本号,系统就会自动恢复到上线前的版本。
在这种机制下如果你的业务流量特别大每秒都有大量用户访问和使用那么直接全量上线的操作就会被禁止。为了减少上线时部署操作对用户造成的影响我们需要先选择一部分用户去做灰度测试也就是说上线后的项目的访问权限暂时只对这些用户开放。或者你也可以做一些AB测试比如给北京的同学推送Vue课给上海的同学推荐React课等等。我们需要做的就是把不同版本的代码分开打包互不干涉。之后我们再设计部署的机器和机房去适配不同的用户。
在Gtihub中我们可以使用actions去配置打包的功能下面的代码是actions的配置文件。在这个配置文件中我们使用Ubuntu作为服务器的打包环境然后拉取GitHub中最新的master分支代码并且把Node版本固定为14.7.6执行npm install安装代码所需依赖后再执行npm run build进行代码打包压缩。在下面的代码中我们就通过GitHub Actions自动化打包了一份准备上线的代码。
```json
name: 打包应用的actions
on:
  push: # 监听代码时间
    branches:
      - master # master分支代码推送的时候激活当前action
jobs:
  build:
    # runs-on 操作系统
    runs-on: ubuntu-latest
    steps:
      - name: 迁出代码
        uses: actions/checkout@master
      # 安装Node
      - name: 安装Node
        uses: actions/setup-node@v1
        with:
          node-version: 14.7.6
      # 安装依赖
      - name: 安装依赖
        run: npm install
      # 打包
      - name: 打包
        run: npm run build
```
然后我们需要配置上线服务器和GitHub Actions服务器的信任关系通过SSH密钥可以实现免登录直接部署。我们直接把build之后的代码打包压缩通过SSH直接上传到服务器上并且要进行代码文件版本的管理就完成了代码的部署。
最后一步,就是部署成功后的结果通知了。现在办公软件钉钉和飞书都提供了相关的推送结果,我们可以随时通过群机器人接口把消息推送到群内,关于钉钉机器人的适用文档,你直接看官方的[开发文档](https://developers.dingtalk.com/document/robots/custom-robot-access?spm=ding_open_doc.document.0.0.7f875e59yR79vi#topic-2026027)就可以了,我们需要做的是把版本号、部署日期、发起人等信息推送到对应接口,这样就完成了自动化部署的操作。
这一过程涉及服务器、钉钉开发文档、GitHub Actions浏览器和本地代码环境多个场景的转换这一讲我们先重点学习整体部署需要的思路和注意事项实际的部署操作过程你可以看这个视频的实操演示
## 总结
今天的主要内容就讲完了,我们来总结一下今天学到的内容吧。首先,我们讲解了前端部署这一过程的难点,包括怎么处理缓存、怎么自动化部署等等。在部署上,我们需要尽可能减少人力的参与,做到整个过程都用代码可控。
之后在前端自动化部署这一部分我们着重讲到了代码的打包上传和项目的部署其中需要你重点注意的是项目的部署。为了解决如何部署代码到线上这一问题我们需要一个独立的部署系统有了独立的部署系统之后我们可以把整个部署上线的过程自动化。借助GitHub的Actions我们可以很方便地使用actions自带的服务去进行发布环节的版本确认、依赖安装、代码打包和上传的工作。
## 思考题
最后留一个思考题吧,你现在负责的项目中,发布和部署这个流程里有哪些环节可以优化呢?欢迎在评论区留言讨论,我们下一讲再见!