阅读 4592

自动化部署的一小步,前端搬砖的一大步

nodejs日渐普及的大背景下,前端工程化的发展可谓日新月异。构建打包这种日常任务脚本化已经是常态了,webpackgulp已经家喻户晓自然不必多说,而持续集成/持续交付/持续部署也越来越得到各个前端Team的重视,业界也有了很多成熟的概念或者方案,如Hudson, Jenkins, Travis CI , Circle CI, DevOps, git hook。然而对于小白来讲,如果直接上手这些内容,很容易混淆概念,陷入迷茫。如果为了用Jenkins而用Jenkins,那不是我的做事风格,我必须搞清楚这项技术能给我带来什么。所以我干脆回归问题本质,从最简单的工作流入手,先解决手动部署的效率问题

前面说这么多废话纯属凑字数,对了,本文讲的内容比较简单,不适合工作流已经很完善的同学

自动构建

构建不是本文的重点,也不是一篇短文能够讲清楚的,这里就一笔带过了。

构建工具

使用主流的构建工具如webpack, gulp, rollup等。

构建目标

通过脚本化的形式组织代码检查编译压缩混淆资源处理devServer等工作流事务。

手动部署

踩过的坑

本人曾经也尝试过两种手动部署的方法。

  • 搬砖模式,将构建完毕的文件夹通过xftp传输到服务器/usr/share/nginx/html目录下。
  • 将构建完毕的文件夹用git分支管理起来,推送到远程仓库,然后在linux服务器上拉取这部分代码。

第一种方法显然已经属于刀耕火种模式了,不过我竟然用了很久。唉,没办法,业务缠身的我只能挤出时间来优化工作流。

第二种方法我自己私下也用过,后来一想,好像可以用git hook来改造优化下,也是实现自动部署的好方法。有兴趣的同学可以试试git hook

自动部署

写脚本

先写个自动构建部署的脚本,主要是包含了切git分支,拉取最新代码,构建打包,传输文件到服务器这些步骤。

scp 命令用于 Linux 之间复制文件和目录

#!/bin/bash
git checkout develop
git pull
npm run build:test
scp -r ./dist/. username@162.81.49.85:/usr/share/nginx/html/projectname/
复制代码

ps:ip已经被我胡乱改了一把,别试着攻击我了。

然而我发现在使用部署脚本的过程中,每次操作都要输入密码,很烦人。

ssh认证

虽然很讨厌输密码,但是密码是安全的保证,如果不输入密码,只能通过ssh安全访问了。

首先是在自己工作电脑的~/.ssh目录下创建密钥对

ssh-keygen -t rsa
复制代码

根据个人情况按需修改密钥对的文件名,输入密码时回车即可,代表不需要使用密码

生成ssh密钥

接着要把公钥传输到服务器

scp ~/.ssh/id_rsa.pub username@162.81.49.85:/home/username/.ssh/authorized_keys
复制代码

如果服务器已经存在authorized_keys文件,那么可以直接在服务器上修改authorized_keys文件,在文件末加入你自己的id_rsa.pub内容即可。

然后我们再修改部署脚本,改用ssh认证方式向linux服务器传输文件。

#!/bin/bash
git checkout develop
npm run build:test
scp -i ~/.ssh/id_rsa -r ./dist/. username@162.81.49.85:/usr/share/nginx/html/projectname/
复制代码

scp-i参数指定传输时使用的密钥文件,这样就可以通过ssh安全访问,而不用再每次输入密码了。-r参数则是recursive,代表递归复制整个目录。

最后我们可以修改下package.json,通过npm scripts来执行sh

"scripts": {
  "deploy:test": "deploy-test.sh"
}
复制代码

配合vscodenpm scripts快捷方式,用起来就很舒服了。

npm scripts

注意,如果linux文件权限不够也可能报错的,别忘了给authorized_keys文件赋予权限,拥有者可读可写即可。

chmod 600 authorized_keys
复制代码

好了,按下那个deploy:test,静静等待一会吧。此时别忘了扭扭脖子,按按腰啊,程序员还是要注意身体,对自己好一点。

scp传输中

随着bash窗口的自动关闭,部署工作也画上了句号。

完工

last but not least

这里还要考虑的一个问题是,部署过程中会不会造成用户访问问题?

答案是会影响用户访问。比如部署脚本执行过程中,已经替换了index.html,正在部署静态资源,此时用户正好进入网站,新的index.html却访问不到新的静态资源,网页白屏报错。

解决方法是先上静态资源,再上页面。因为静态资源经webpack构建后都带上了hash值,先上静态资源不会影响原有的版本,所以我们还需要再优化下部署脚本,分解下传输过程。

很头疼的是scp命令竟然不能忽略文件,这就有点麻烦了。

如果打包后的dist根目录文件不算很多,可以考虑手动列举的方式来排列传输顺序。举个例子:

#!/bin/bash
git checkout develop
git pull
npm run build:test
scp -i ~/.ssh/id_rsa -r ./dist/static username@162.81.49.85:/usr/share/nginx/html/projectname/
scp -i ~/.ssh/id_rsa ./dist/favicon.ico username@162.81.49.85:/usr/share/nginx/html/projectname/favicon.ico
scp -i ~/.ssh/id_rsa ./dist/element-icons.ttf username@162.81.49.85:/usr/share/nginx/html/projectname/element-icons.ttf
scp -i ~/.ssh/id_rsa ./dist/element-icons.woff username@162.81.49.85:/usr/share/nginx/html/projectname/element-icons.woff
scp -i ~/.ssh/id_rsa ./dist/index.html username@162.81.49.85:/usr/share/nginx/html/projectname/index.html
复制代码

如果觉得这样很傻,那么可以考虑下rsync了,rsync是可以通过--exclude忽略文件的,这样的话理论上只需要写两条传输命令即可,也不用考虑后续构建可能会新增的内容。不过在windowslinux之间用rsync还是蛮复杂的,留给各位大佬自己探索啦。

更新补充

2020-01-20 简化脚本

谢谢网友_shanks的提醒,可以用.ssh/config简化写法。首先是要修改.ssh/config

# 配置开发环境
Host dev
HostName 162.81.49.85
User username
IdentityFile ~/.ssh/id_rsa
复制代码

接着修改部署脚本deploy-test.sh

#!/bin/bash
git checkout develop
git pull
npm run build:test
scp -r ./dist/static dev:/usr/share/nginx/html/projectname/
scp ./dist/favicon.ico dev:/usr/share/nginx/html/projectname/
scp ./dist/element-icons.ttf dev:/usr/share/nginx/html/projectname/
scp ./dist/element-icons.woff dev:/usr/share/nginx/html/projectname/
scp ./dist/index.html dev:/usr/share/nginx/html/projectname/
复制代码

2020-02-04 深度实践

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

  • 收藏吃灰不如现在就开始学习,奥利给!
  • 如果您觉得本文有所帮助,请留下您的点赞关注支持一波,谢谢!
  • 快关注公众号前端司南,与笔者一起交流学习吧!