前端静态资源布署,可以通过xShell或者SecureCRT这种软件来上传资源,用软件的ftp上传,或者手动输入一些命令来操作,比如:
如果用node自动布署,就简便很多。
使用node脚本,可将npm run build
之后构建出来的dist文件夹压缩,然后自动上传到远端服务器,然后在远端服务器自动解压到固定的目录。
cli
在package.json中增加bin命令cli-deploy
,指向./bin/deploy.js
,在script中增加deploy
命令。后面完成deploy.js
后就可以直接npm run deploy
来发布了。
不了解node cli的话,可以看这篇文章A guide to create a NodeJS command-line package – Netscape – Medium
1 2 3 4 5 6 7 8 9 10
| // package.json "scripts": { "dev": "vue-cli-service serve", "build": "vue-cli-service build", "lint": "vue-cli-service lint", "deploy": "vue-cli-service build && cli-deploy" }, "bin": { "cli-deploy": "./bin/deploy.js" },
|
也可以不使用bin,将scripts中的deploy命令改成vue-cli-service build && node ./bin/deploy.js
压缩
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| const glob = require('glob') const fs = require('fs') const path = require('path') const yazl = require("yazl") const chalk = require('chalk')
const zip = ({ sourcePath, destPath, filename }) => { return new Promise((resolve) => {
const zipfile = new yazl.ZipFile()
if (!fs.existsSync(destPath)) { fs.mkdirSync(destPath, 0777) }
const files = glob.sync('**/*.*', { cwd: sourcePath })
files.forEach(function(file) { const filePath = path.join(sourcePath, file) zipfile.addFile(filePath, file) })
zipfile.outputStream.pipe(fs.createWriteStream(path.resolve(destPath, filename))).on('close', () => { console.log(chalk.cyan( ` ${filename} has build!` )) resolve() }) zipfile.end() }) }
module.exports = { zip }
|
1 2 3 4 5 6 7 8 9
| #!/usr/bin/env node const { zip } = require('./zip') const zipOptions = { sourcePath: path.join(__dirname, '../dist'), destPath: path.join(__dirname, '../'), filename: 'dist.zip', } zip(zipOptions)
|
上传
上传这块做了比较多的调研,看了比较多的库,最后决定用scp2,不需要配置ssh免密登录,直接使用的时候指定信息就行。
1 2 3 4 5 6
| const path = require('path') const client = require('scp2') client.scp(path.join(__dirname, '../dist.zip'), `${user}:${pass}@${host}:${reomteFloder}`, () => { })
|
也可以不压缩,直接上传文件夹
1 2 3 4 5 6
| const path = require('path') const client = require('scp2') client.scp(path.join(__dirname, '../dist/'), `${user}:${pass}@${host}:${reomteFloder}/`, () => { })
|
解压
选用simple-ssh连接远端,然后用ssh.exec在远端执行命令。simple-ssh只是把ssh2进一步封装了一下,让调用更简单。
1 2 3 4 5 6 7 8 9 10 11 12
| const SSH = require('simple-ssh') const host = 'xx.xx.xx.xx' const user = 'xxx' const pass = 'xxx' const reomteFloder = '/xxx/xxx/xx' const ssh = new SSH({host, user, pass}) ssh.exec(`rm -rf ${reomteFloder}/dist`) .exec(`unzip -o ${reomteFloder}/dist.zip -d ${reomteFloder}/dist`, { out: console.log.bind(console), }) .start()
|
unzip参数说明:
- -o 不必先询问用户,unzip执行后覆盖原有文件
- -d <目录> 指定文件解压缩后所要存储的目录
pm2
有的项目需要用pm2重启,如果直接远程执行pm2命令,比如pm2 status
, 会报错pm2: command not found
。
解决办法:把pm2 status
改成'bash -l -c "pm2 status"'
。
参考了bash-doesnt-load-node-on-remote-ssh-command和env-problem-when-ssh-executing-command-on-remote
总结
至此,完成了自动压缩、上传、解压。
cli-deploy
可以部署;
npm run deploy
可以构建+部署。
完整版本deploy.js
如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| #!/usr/bin/env node const { zip } = require('./zip') const path = require('path') const SSH = require('simple-ssh') const client = require('scp2')
const zipOptions = { sourcePath: path.join(__dirname, '../dist'), destPath: path.join(__dirname, '../'), filename: 'dist.zip', } const host = 'xx.xx.xx.xx' const user = 'xxx' const pass = 'xxx' const reomteFloder = '/xxx/xxx/xx'
const ssh = new SSH({host, user, pass})
const upload = () => { client.scp(path.join(__dirname, '../dist.zip'), `${user}:${pass}@${host}:${reomteFloder}`, () => { ssh.exec(`unzip -o ${reomteFloder}/dist.zip -d ${reomteFloder}/dist`, { out: console.log.bind(console), }) .start() }) }
async function deploy () { await zip(zipOptions) console.log('Build complete') upload() }
deploy()
|