在nodejs
日渐普及的大背景下,前端工程化的发展可谓日新月异。构建打包这种日常任务脚本化已经是常态了,webpack
和gulp
已经家喻户晓自然不必多说,而持续集成/持续交付/持续部署也越来越得到各个前端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[1]来改造优化下,也是实现自动部署的好方法。有兴趣的同学可以试试git hook
。
自动部署
写脚本
先写个自动构建部署的脚本,主要是包含了切git
分支,拉取最新代码,构建打包,传输文件到服务器这些步骤。
代码语言:javascript复制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密钥
接着要把公钥传输到服务器上
代码语言:javascript复制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"
}
配合vscode
的npm 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 ./test/static username@162.81.49.85:/usr/share/nginx/html/projectname/
scp -i ~/.ssh/id_rsa ./test/favicon.ico username@162.81.49.85:/usr/share/nginx/html/projectname/favicon.ico
scp -i ~/.ssh/id_rsa ./test/element-icons.ttf username@162.81.49.85:/usr/share/nginx/html/projectname/element-icons.ttf
scp -i ~/.ssh/id_rsa ./test/element-icons.woff username@162.81.49.85:/usr/share/nginx/html/projectname/element-icons.woff
scp -i ~/.ssh/id_rsa ./test/index.html username@162.81.49.85:/usr/share/nginx/html/projectname/index.html
如果觉得这样很傻X,那么可以考虑下rsync
了,rsync
是可以通过--exclude
忽略文件的,这样的话理论上只需要写两条传输命令即可,也不用考虑后续构建可能会新增的内容。不过在windows
和linux
之间用rsync
还是蛮复杂的,留给各位大佬自己探索啦。
参考资料
[1]
git hook: https://www.git-scm.com/book/zh/v2/自定义-Git-Git-钩子