当前位置:   article > 正文

node实现自动化部署_yarn build:prod

yarn build:prod

 首先看一下需要什么依赖?

  1. {
  2. "name": "zdpl",
  3. "version": "1.0.1",
  4. "description": "自动部署",
  5. "main": "./src/index.js",
  6. "bin": {
  7. "zc-deploy": "./src/index.js"
  8. },
  9. "scripts": {
  10. "test": "echo \"Error: no test specified\" && exit 1"
  11. },
  12. "keywords": [
  13. "deploy"
  14. ],
  15. "publicConfig": {
  16. "registry": "https://registry.npmjs.org/"
  17. },
  18. "author": "",
  19. "license": "ISC",
  20. "dependencies": {
  21. "chalk": "^4.1.0",
  22. "inquirer": "^8.0.0",
  23. "node-ssh": "^11.1.1",
  24. "ora": "^5.3.0",
  25. "shelljs": "^0.8.5",
  26. "zip-local": "^0.3.5"
  27. }
  28. }

脚本的目录结构如下:

 

 

1. chalk插件主要用于改变终端输出文字的样式

2. inquirer 用户交互命令行

3. node-ssh        connect 用于用户连接服务器,exec 用于执行命令, putFIle用于推送文件到服务器指定位置。

4. ora 用于等待某个指令执行,类似loading效果

5. shelljs 是基于node.js的Unix shell命令的可移植实现。类似shell脚本可以写一下指令,然后执行。shelljs就是可以在js通过其中方法执行指令,在运行代码时依次执行。

6. zip-local用于压缩文件,用法查看npm官网

7. download-git-repo用于从github,gitlab等上拉取摸板。

8. commander 这里主要用来生成不同的指令,zc-deploy init 和 zc-deploy push

主要代码如下

需要在代码中配置deploy.config.ts 文件,使用zc-deploy init 初始化摸板。也可以自己配置,配置格式如下,需要知道公司项目发布的服务器ip,在此文件中声明即可。在执行yarn deploy时,会出现如下图选择部署的服务器。

  

  1. module.exports = Object.freeze({
  2. PRIVATE_KEY: 'C:/Us/.ssh/id_rsa', // 密钥地址
  3. SERVER: [
  4. {
  5. NAME: 'server-501',
  6. SERVER_PATH: '39.98.82.82',
  7. SSH_USER: 'root', // 服务器用户名
  8. SSH_KEY: ``, // 服务器密码
  9. PORT: 22, // 端口 默认为22
  10. DIST: './dist', // 需要部署的打包过后的文件夹 根据项目不同值不同 一般为 build static 或者dist
  11. SCRIPT: 'yarn build:prod', // 打包命令 可能项目由不同的构建命令 如打包指定环境的代码
  12. PATH: '/root/501', // 服务器存放静态文件目录
  13. },
  14. {
  15. NAME: 'server-506',
  16. SERVER_PATH: '192.168.117.133',
  17. SSH_USER: 'root', // 服务器用户名
  18. SSH_KEY: 'root', // 服务器密码
  19. PORT: 22, // 端口 默认为22
  20. DIST: './dist', // 需要部署的打包过后的文件夹 根据项目不同值不同 一般为 build static 或者dist
  21. SCRIPT: 'yarn build:prod', // 打包命令 可能项目由不同的构建命令 如打包指定环境的代码
  22. PATH: '/root/506', // 服务器存放静态文件目录
  23. },
  24. {
  25. NAME: 'server-603',
  26. SERVER_PATH: '192.168.117.133',
  27. SSH_USER: 'root', // 服务器用户名
  28. SSH_KEY: 'root', // 服务器密码
  29. PORT: 22, // 端口 默认为22
  30. DIST: './dist', // 需要部署的打包过后的文件夹 根据项目不同值不同 一般为 build static 或者dist
  31. SCRIPT: 'yarn build:prod', // 打包命令 可能项目由不同的构建命令 如打包指定环境的代码
  32. PATH: '/root/603', // 服务器存放静态文件目录
  33. },
  34. ],
  35. });

src/index.js:这是全局的入口。主要配置了两个命令:zc-deploy init 和zc-deploy push 

  1. #!/usr/bin/env node
  2. program
  3. .version(packageJson.version, "-v, --version")
  4. .command("init")
  5. .description("初始化部署相关配置")
  6. .action(() => {
  7. require("../lib/init")();
  8. });
  9. program
  10. .version(packageJson.version)
  11. .command("push")
  12. .description("部署项目")
  13. .action(async () => {
  14. if (fs.existsSync(path.resolve(process.cwd(), "./deploy.config.ts"))) {
  15. const CONFIG = require(path.resolve(process.cwd(), "./deploy.config.ts"));
  16. const serverConfig = [...CONFIG.SERVER];
  17. const answers = await inquirer.prompt([
  18. {
  19. type: "confirm",
  20. name: "hasBuild",
  21. message: "是否需要打包",
  22. },
  23. ]);
  24. let hasBuild = answers.hasBuild ? true : !existsSync(distZipPath);
  25. const serverName = await inquirer.prompt([
  26. {
  27. type: "list",
  28. name: "server_name",
  29. message: "请选择部署的服务器",
  30. choices: serverConfig.map((item) => item.NAME),
  31. },
  32. ]);
  33. runTask(hasBuild, serverName, serverConfig, CONFIG);
  34. } else {
  35. defaultLog(`缺少部署相关的配置,请运行"zc-deploy init"下载部署配置`);
  36. }
  37. });

lib/deploy.js:这个文件是,项目的部署流程文件。

  1. #!/usr/bin/env node
  2. const distZipPath = resolve(process.cwd(), "./dist.zip");
  3. // 打包 npm run build 或yarn build
  4. const compileDist = async (CURCONFIG) => {
  5. // 进入本地文件夹
  6. cd(process.cwd(), "./");
  7. exec(CURCONFIG.SCRIPT || "yarn build:prod");
  8. success("打包完成");
  9. };
  10. // ******压缩dist文件******
  11. const zipDist = async (CURCONFIG) => {
  12. try {
  13. if (existsSync(distZipPath)) {
  14. defaultLog("dist.zip已经存在,即将删除压缩包");
  15. unlinkSync(distZipPath);
  16. } else {
  17. defaultLog("即将开始压缩zip文件");
  18. }
  19. let spinner = ora("文件开始压缩").start();
  20. sync
  21. .zip(path.resolve(process.cwd(), CURCONFIG.DIST || "./dist"))
  22. .compress()
  23. .save(distZipPath);
  24. spinner.succeed("文件压缩成功");
  25. } catch (error) {
  26. errorLog(error);
  27. errorLog("压缩dist文件失败");
  28. }
  29. };
  30. // ********执行清空线上文件夹指令**********
  31. const runCommond = async (commond, CONFIG) => {
  32. const result = await SSH.exec(commond, []);
  33. console.log(warning(result));
  34. };
  35. // ********* 执行清空线上文件夹指令 *********
  36. const runBeforeCommand = async (CONFIG) => {
  37. let spinner = ora("正在删除服务器文件").start();
  38. await runCommond(`rm -rf ${CONFIG.PATH}/dist.zip`);
  39. await runCommond(`rm -rf ${CONFIG.PATH}/dist`);
  40. spinner.succeed("删除服务器文件成功");
  41. };
  42. // 通过ssh上传文件服务器
  43. const uploadZipBySSH = async (CONFIG) => {
  44. // 上传文件
  45. let spinner = ora("准备上传文件").start();
  46. try {
  47. await SSH.putFile(distZipPath, CONFIG.PATH + "/dist.zip");
  48. // await SSH.putFile(distZipPath, '/root/dist.zip');
  49. spinner.succeed("文件上传服务器成功");
  50. let spinner1 = ora("完成上传,开始解压").start();
  51. await runCommond(`unzip ${CONFIG.PATH}"/dist.zip" -d ${CONFIG.PATH}/dist`);
  52. spinner1.succeed("文件解压成功");
  53. success(`${CONFIG.NAME}部署完成`);
  54. process.exit(0);
  55. } catch (err) {
  56. errorLog(err);
  57. errorLog("上传失败");
  58. }
  59. };
  60. const getServerConfig = (serverName, serverConfig) => {
  61. return serverConfig.find((item) => {
  62. return item.NAME == serverName;
  63. });
  64. };
  65. // 连接ssh
  66. const connectSSH = async (CURCONFIG, CONFIG) => {
  67. defaultLog(`尝试连接服务:${CURCONFIG.SERVER_PATH}`);
  68. defaultLog(`密钥路径${CONFIG.PRIVATE_KEY}`);
  69. let spinner = ora("正在连接").start();
  70. try {
  71. SSH.connect({
  72. host: CURCONFIG.SERVER_PATH,
  73. username: CURCONFIG.SSH_USER,
  74. password: CURCONFIG.SSH_KEY,
  75. privateKey: Buffer.from(CONFIG.PRIVATE_KEY).toString() ?? "",
  76. port: CURCONFIG.PORT || 22,
  77. }).then(async () => {
  78. // exec(`sh ${connect} ${CURCONFIG.SERVER_PATH} ${CURCONFIG.PATH}`);
  79. spinner.succeed("服务器连接成功");
  80. await runBeforeCommand(CURCONFIG);
  81. await uploadZipBySSH(CURCONFIG);
  82. });
  83. } catch (err) {
  84. errorLog(err);
  85. errorLog("ssh连接失败");
  86. }
  87. };
  88. async function runTask(hasBuild, serverName, serverConfig, CONFIG) {
  89. const CURCONFIG = getServerConfig(serverName.server_name, serverConfig);
  90. if (hasBuild) {
  91. await compileDist(CURCONFIG);
  92. }
  93. await zipDist(CURCONFIG);
  94. await connectSSH(CURCONFIG, CONFIG);
  95. }
  96. module.exports = runTask;

 lib/init.js  :这个文件是初始化配置文件,生成一系列配置信息(deploy.config.ts)

  1. const deployTem = "github:success-c/deploy-template";
  2. const checkDeployExists = () => {
  3. if (fs.existsSync(deployConfigPath)) {
  4. defaultLog("根目录下已经存在deploy.config.ts文件,请勿重新下载");
  5. process.exit(1);
  6. }
  7. downloadAndGenerate(deployTem);
  8. };
  9. const downloadAndGenerate = (templateURL) => {
  10. const spinner = ora("开始生成部署模板");
  11. spinner.start();
  12. download(templateURL, process.cwd(), { clone: false }, (err) => {
  13. if (err) {
  14. errorLog(err);
  15. process.exit(1);
  16. }
  17. spinner.stop();
  18. success("模板下载成功,模板位置:/deploy.config.js");
  19. defaultLog("请配置根目录下的deploy.config.js配置文件");
  20. console.log("注意:请删除不必要的环境配置");
  21. process.exit(0);
  22. });
  23. };
  24. module.exports = () => {
  25. checkDeployExists();
  26. };

lib/utils : 打印信息的方法

  1. const chalk = require("chalk");
  2. const { red, blue, green, yellow } = chalk;
  3. const errorLog = (error) => console.log(red(`=========>${error}`));
  4. const defaultLog = (log) => console.log(blue(`=========>${log}`));
  5. const success = (log) => console.log(green(`=========>${log}`));
  6. const warning = (log) => console.log(yellow(`${log}`));
  7. module.exports = {
  8. errorLog,
  9. defaultLog,
  10. success,
  11. warning,
  12. };

 

源码地址: 

deploy: node脚本实现自动化部署https://gitee.com/liu--zicheng/deploy.git

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/488052
推荐阅读
相关标签
  

闽ICP备14008679号