使用js脚本将项目打包,然后直接部署到web服务器上

854 阅读1分钟

serverList.js 服务器列表

// serverList.js

/**
 * 定义多个服务器信息 及 导出服务器列表
 * 服务器列表对象的key自己随便定义,和package.json文件中的scripts中的DEPLOY_ENV对应上
 */
const SERVER_LIST = {
  '255': {
    id: 0,
    name: '未知环境',
    domain: '', // 域名
    host: '', // ip
    port: 22, // 端口
    username: '', // 登录服务器的账号
    password: '', // 登录服务器的账号
    path: '', // 发布至静态服务器的项目路径
    relativePath: './dist' // 本地build出来的包所在路径
  },
  '100': {
    id: 1,
    name: '测试环境',
    domain: '172.16.100.100', // 域名
    host: '172.16.100.100', // ip
    port: 22, // 端口
    username: 'root', // 登录服务器的账号
    password: '123456', // 登录服务器的账号
    path: '/home/admin/', // 发布至静态服务器的项目路径
    relativePath: './dist'
  }
}

module.exports = SERVER_LIST

deploy.js 脚本文件

// deploy.js

const scpClient = require('scp2')
const ora = require('ora')
const chalk = require('chalk')
const serverList = require('./serverList.js')

const server = serverList[process.env.DEPLOY_ENV]

const spinner = ora(`正在发布到${server.name}服务器... \n`)

// 如果传入DEPLOY_METHOD等于delete则先执行删除服务器旧文件,然后开始上传部署新代码
if (process.env.DEPLOY_METHOD === 'delete') {
  const { Client } = require('ssh2')
  const conn = new Client()
  conn.on('ready', () => {
    // rm 删除服务器上的文件
    conn.exec(`rm -rf ${server.path}`, (err, stream) => {
      if (err) throw err
      stream.on('close', (code, signal) => {
        // 在执行shell命令后,把开始上传部署项目代码放到这里面
        spinner.start()
        scpClient.scp(
          server.relativePath,
          {
            host: server.host,
            port: server.port,
            username: server.username,
            password: server.password,
            path: server.path
          },
          (err) => {
            spinner.stop()
            if (err) {
              console.log(chalk.red(`发布${server.name}服务器失败! \n`))
              throw err
            } else {
              console.log(chalk.green(`Success! 成功发布到${server.name}服务器! \n`))
            }
          }
        )
        conn.end()
      }).on('data', (data) => {
        console.log(`STDOUT: ${data}`)
      }).stderr.on('data', (data) => {
        console.log(`STDERR: ${data}`)
      })
    })
  }).connect({
    host: server.host,
    port: server.port,
    username: server.username,
    password: server.password
    // privateKey: require('fs').readFileSync('/home/admin/.ssh/id_dsa')
  })
} else { // 默认不删除服务器上的旧文件,就在执行命令的时候不传DEPLOY_METHOD
  spinner.start()
  scpClient.scp(
    server.relativePath,
    {
      host: server.host,
      port: server.port,
      username: server.username,
      password: server.password,
      path: server.path
    },
    (err) => {
      spinner.stop()
      if (err) {
        console.log(chalk.red(`发布到${server.name}服务器失败! \n`))
        throw err
      } else {
        console.log(chalk.green(`Success! 成功发布到${server.name}服务器! \n`))
      }
    }
  )
}

package.json 文件

cross-env 可以装全局的看自己习惯

{
	...
    ...
    
	"scripts": {
    	"build": "node build/build.js",
        "deploy": "npm run build && cross-env DEPLOY_ENV=100 node ./deploy.js",
        "deploy:del": "npm run build && cross-env DEPLOY_ENV=100 DEPLOY_METHOD=delete node ./deploy.js"
    },
    "devDependencies": {
    	"chalk": "^2.0.1",
     	"ora": "^1.2.0",
    	"scp2": "^0.5.0"
    }
    
    ...
    ...
}