内容简介:在上篇PS:只作为本人工作的分享,不作为任何形式的指南、教程、最佳实践等,也并非手把手系列以下内容请结合
在上篇 《【vue-cli3升级】老项目提速50%(二)》 文中,评论区好几个人对文中task任务以及 shell 打包推送远程仓库表示感兴趣,希望我多描述些内容... 基于此原因、在此基础上,谈一谈我在SPA项目打包 => 部署的工程化内容
PS:只作为本人工作的分享,不作为任何形式的指南、教程、最佳实践等,也并非手把手系列
项目环境描述
- SPA项目(Vue-cli3)
- Gitlab代码仓库
- node 10.8.0
- npm 6.5.0
- Nginx服务器
- Linux系统
- Jenkins持续集成部署工具
说下上篇文中Task.js、run.sh
以下内容请结合 《【vue-cli3升级】老项目提速50%(一)》 、 《【vue-cli3升级】老项目提速50%(二)》 阅读
为什么这么做?
结合实际场景罗列两个吧...
- 为了随时发布前端项目,不用等到晚上加班发布...
- 曾经,在发布过程中,老板正在浏览…然后白屏了…所以为了发布时线上用户无感知
整体流程(画图真墨迹啊)
-
执行
run.sh
,以beta
环境为例,项目根目录执行./run.sh beta
-
在
run.sh
中,初始化beta环境的远程仓库,拉取代码到本地.deploy/beta
目录,将.deploy/beta
目录中的文件复制到本地dist
目录 -
在
run.sh
中,执行构建:npm run build_beta
-
在
vue.config.js
中,创建版本号lastVersion
,将版本号lastVersion
加入到css
、js
资源文件名中(我是加在最前面的,位置随意,和task.js
中的正则对应) -
在
vue.config.js
中,注入task.js
,执行任务const task = require('./task') task.run(lastVersion) 复制代码
-
在
task.js
中,将版本号写入history.js
,判断是否超出最大值(最大5个历史版本),超出则执行rmFiles()
,删除本地dist
目录中最老的版本资源 -
复制本地
dist
目录文件到.deploy/beta
中,提交.deploy/beta
文件到远程仓库
附图:了解下.deploy/beta目录文件,history.js文件,远程Gitlab仓库代码
【Task.js】
前提:打包时不清除dist文件目录,以增量的形式打包。
vue-cli3下可参考 《【vue-cli3升级】老项目提速50%(二)》
vue-cli2下在 /build/build.js
中找到以下代码注释掉
// rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { // if (err) throw err // }) 复制代码
何时执行?build构建时
作用:利用nodeJs的fs模块操作history.js,存储最多5个版本,超过5个在本地dist目录中删除匹配最老版本的相关资源
代码(基本上都加上注释描述了)
const fs = require('fs') // node fs模块,操作文件 const path = require('path') // node path模块,操作路径 const endOfLine = require('os').EOL // node os模块,不同操作系统的行尾符 module.exports = { maxHistoryNum: 5, // 控制存储版本最大值 historyFile: path.resolve(__dirname, './dist/history.js'), // 本地dist目录中的history.js staticDir: path.resolve(__dirname, './dist/'), // 本地dist目录 // history.js不存在,创建 creataHistoryIfNotExist () { if (!fs.existsSync(this.historyFile)) { this.storeHistory([], 'a+') } }, // @done 将数据写到 history.js storeHistory (list, mode) { let historyFile = this.historyFile let outJson = 'module.exports = [' + endOfLine let listLen = list.length if (list && listLen > 0) { list.forEach((item, index) => { if (index === listLen - 1) { outJson += ` ${item}${endOfLine}` } else { outJson += ` ${item},${endOfLine}` } }) } outJson += ']' + endOfLine // 以 a+ 的falg标志在history.js写入和追加内容 fs.writeFileSync(historyFile, outJson, { flag: mode }) }, // 递归删除目录中的文件 (构建完成时版本>最大值时执行) rmFiles (dirPath, regexp) { let files try { files = fs.readdirSync(dirPath) } catch (e) { return } if (regexp && files && files.length > 0) { for (let i = 0; i < files.length; i++) { let filename = files[i] let filePath = dirPath + '/' + files[i] if (fs.statSync(filePath).isFile() && regexp.test(filename)) { console.log('删除过期的历史版本->(' + regexp + '):' + filename) fs.unlinkSync(filePath) } else { this.rmFiles(filePath, regexp) } } } }, // @done 更新history.js内容 cleanOldVersionFilesIfNeed (version) { let staticDir = this.staticDir let maxHistoryNum = this.maxHistoryNum let history = [] try { history = require(this.historyFile) } catch (e) { console.log(e) } // 加入最新的版本,老的的版本删除 history.push(version) // 如果历史版本数超过限制,则删除老的历史版本 let len = history.length if (len > maxHistoryNum) { let oldVersions = history.slice(0, len - maxHistoryNum) for (let i = 0; i < oldVersions.length; i++) { let ver = oldVersions[i] let reg = new RegExp(ver) this.rmFiles(staticDir, reg) } // 更新history文件 let newVersions = history.slice(len - maxHistoryNum) this.storeHistory(newVersions) } else { // 写入history文件 this.storeHistory(history) } }, // 入口 run (version) { this.creataHistoryIfNotExist() this.cleanOldVersionFilesIfNeed(version) } } 复制代码
【 run.sh 】
我们简单的分为beta(测试环境)和pro(线上环境)
作用:一键打包本地代码,提交上传至远程代码仓库
先看代码:
#!/bin/bash # 初始化上下文。有参数的 initContext(){ # dist目录 source_dir=dist # 获取参数,beta环境和pro环境 if [ $# -gt 0 ] && [ $1 = 'beta' ];then # beta环境远程仓库地址, git_url=git@beta/example.git # 本地根目录存放打包代码 dest=".deploy/beta" # npm 的脚本名,对应package.json定义的script node_script=build_beta else # pro环境远程仓库地址 git_url=git@pro/example.git # 本地根目录 dest=".deploy/pro" # npm 的脚本名,对应package.json定义的script node_script=build_pro fi } # 初始化git目录,pull最新代码 init(){ echo +++init start; if [ ! -d $dest ]; then git clone $git_url $dest fi # 记录现在的目录位置,pwd获取本地路径 cur=`pwd` # 进入git目录 cd $dest # git checkout . git add . git stash # reset为线上最新版本,要先pull一下再reset。 git pull origin master git reset --hard origin/master # 然后再pull一下 git pull origin master # 回到原来的目录 cd $cur echo ---init end; } # 重置dist目录 resetDist(){ echo +++resetDist start rsync -a --delete --exclude='.git' $dest/. ./dist echo ---resetDist end } # 构建 build(){ echo +++build start npm run $node_script echo ---build end } # 检查是否成功 checkBuild(){ if [[ ! -f $source_dir/index.html || ! -d $source_dir/static ]]; then echo error else echo ok fi } # 复制代码到$dest目录 cpCode(){ echo +++cpCode start # 复制代码,所有文件包含隐藏文件 rsync -r --delete --exclude='.git' $source_dir/. $dest echo ---cpCode end } # 提交到远程git仓库 commit(){ echo +++commit start # 记录现在的目录位置,最后要回来的 cur=`pwd` # 进入git目录 cd $dest # 提交的字符串 commit_str="commited in `date '+%Y-%m-%d_%H:%M:%S'`" git add . git commit -am "${commit_str}" git push origin master # 回到原来的目录 cd $cur echo ---commit end } # 显示帮助信息 help(){ # 微信h5版本 echo ----微信h5版本-------- echo ./run.sh build "#"构建代码 echo ./run.sh init "#"初始化git仓库 echo ./run.sh commit "#"提交到git echo ./run.sh "#"执行全部任务 echo ./run.sh hello "#"hello echo ./run.sh test "#"test echo ./run.sh beta "#"一键构建和提交beta版本 # app内嵌版本 echo ----app内嵌版本-------- echo ./run.sh app "#"一键构建和提交app版本 echo ----帮助信息-------- echo ./run.sh help "#"帮助 } # 测试用的 test(){ echo "a test empty task" } # 入口 if [[ $# -lt 1 || $1 = 'app' || $1 = 'beta' ]]; then # 无参数则打pro包,否则打相应类型的包 if [ $# -lt 1 ];then type=pro else type=$1 fi echo ===\>准备构建${type}版 initContext $type && init && resetDist # 构建代码 buildRes=$(build) # 检查构建结果 echo -e "$buildRes" if [[ $buildRes =~ "ERROR" ]]; then echo "$(tput setaf 1)xxx\>build error,task abort$(tput sgr0)" else # 代码构建成功才继续。 checkRes=$(checkBuild) if [ $checkRes == "ok" ];then cpCode && commit echo "$(tput setaf 2)===\>task complete$(tput sgr0)" else echo "$(tput setaf 1)xxx\>build error,task abort$(tput sgr0)" fi fi elif [ $1 ]; then # 参数不是包类型的,当中函数处理 echo ===\>准备执行${1}函数 initContext beta func=$1 $func echo ===\>task complete fi 复制代码
上篇文章评论区有人问到 rsync
,文中用来同步本地硬盘中的不同目录。可以看下这篇教程
Linux
系统已经集成了 rsync
命令, windows
的用户需要自行安装(教程),不然会和这位小伙伴一样遇到 command not found
,本人windows已经3年没碰了...
以上,是对上篇文章中对打包这块内容的讲解,接下来说下部署
部署 工具 我接触过walle、Jenkins
walle的话就是提交对应版本进行发布,持续集成部署方案的话就是Jenkins了。Jenkins文档
为什么要做自动化部署?结合自身实际场景描述下:
- 后端有微服务,前端自然不能落下。各个大模块(业务线)都是独立的工程,比如商城、教育、社区等等。当开发迭代一个版本时,可能就会涉及到A、B、C、D等几个项目,部署的痛苦就来了…我特么的一个个打包,然后再一个个的部署...这个过程可能半小时就过去了…效率低下又low,实力不允许这么做
- 公司有局域网限制,如果在家手动部署,还需要连接VPN,内心是拒绝的
- 我只想安心敲代码…别特么的动不动让我部署下,打断老子的思路...
当然,使用Jenkins持续集成方案,该装的环境还是一个都不能少的…这个也结合自身实际情况自行研究吧
本文也是描述下这个概念,各自实际情况各异,扔需自行研究
安装什么的自行文档吧(安装,插件,配置等),从新建任务开始
-
进入Jenkins系统,左侧新建任务
-
输入名称,选择构建一个自由风格的软件项目,确定
-
填写任务描述、源码仓库地址,分支默认master
-
配置触发器,Gitlab提交代码触发自动构建任务
-
如果需要构建时执行脚本,比如
npm i npm run build 复制代码
-
保存
很简单的几个配置步骤就能完成自动化部署任务,简单高效。自行研究尝试玩玩吧
结尾
通过这样的方式打包部署个人认为是适合绝大多数中小公司的,哈哈。我本来考虑的是将css、js部署在cdn服务器上,index.html单独部署的,考虑到暂时还没到需要这么干的程度,就不折腾服务器了,思路大同小异。
在写这篇文章的时候,正好看到 大公司里怎样开发和部署前端代码? ,大家可以了解下他们是怎么设计的。我这中小公司,感觉文中的思路方案也差不多OK的啦
提前写了,本来说是周末写的,正好今天不忙,花2小时简单写下
以上所述就是小编给大家介绍的《【前端打包部署】谈一谈我在SPA项目打包=>部署的处理》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Beego打包部署到Linux
- Spring Boot打包部署和环境配置
- iOS自动化打包部署踩坑记
- 利用rpm打包上线部署golang代码的方法教程
- JFinal Undertow 2.0 发布,开发、打包、部署一体化
- 后台管理系统 icec v1.1 发布,完善打包部署脚本
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Build Your Own Web Site the Right Way Using HTML & CSS
Ian Lloyd / SitePoint / 2006-05-02 / USD 29.95
Build Your Own Website The Right Way Using HTML & CSS teaches web development from scratch, without assuming any previous knowledge of HTML, CSS or web development techniques. This book introduces you......一起来看看 《Build Your Own Web Site the Right Way Using HTML & CSS》 这本书的介绍吧!