NodeJs执行Linux脚本

(我们活着不能与草木同腐,不能醉生梦死,枉度人生,要有所作为。——方志敏)

在这里插入图片描述

为什么需要使用NodeJs执行Linux脚本

  1. linux的sh脚本命令编写复杂,在不熟悉linux交互式命令的情况下,使用高级编程语言来执行是最明智的选择
  2. 高级语言的生态较为完善,可以使用各种现成的工具包来完成脚本执行,比如NodeJs的npm,Java的maven等
  3. linux命令较为复杂,通常需要专业的运维来执行各种复杂的命令操作,但使用高级语言则屏蔽了linux底层命令,直接使用高级语言封装好的工具包即可

NodeJs执行脚本命令

应用场景举例

比如以下场景,在传统k8s容器化服务的架构下,每次服务的发布都需要重新安装依赖,快则两三分钟,慢则十分钟甚至更久,在没有专业运维的情况下,我们可以使用NodeJs来执行命令脚本,在每次发布前,对比两个版本的package.json文件,如果不一致,则再安装依赖,否则直接跳过安装阶段,使用当前目录下的node_moodules进行发布,这样在最优的情况下,就能省去依赖安装的时间,极大的提升了服务发布速度

场景细则
上一个版本的node_modules/package.json哪里来的
  • 在不使用容器化的情况下,我们在构建的目标目录下把上一个版本的node_modules/package.json复制来即可
  • 使用容器化的情况下,我们可以直接使用docker镜像生成一个node_modules/package.json缓存,然后加入新版本的Dockerfile下,使用相同的工作目录就可以复用

代码示例

// 在本地环境有nodejs的情况下 直接使用node xx.js执行即可
// 使用nodejs内置破快的exec执行linux命令
const {
    
     exec } = require('child_process');
// 本地的新json
const newJson = require('./package.json');
// 从上一个版本中复制来的旧json
const oldJson = require('./old.package.json');

// 安装依赖方法
const installDependencies = async (isInstall) => {
    
    
    return new Promise((resolve) =>{
    
    
		// 如果不需要安装则打印信息并跳出
        if(!isInstall){
    
    
            process.stdout.write('no need to install dependencies \n');
			// 结束promise
            return resolve();
        }
		// 执行yarn安装依赖命令
        const yarn = exec('yarn');
		// 实时监听该命令输入的信息并打印
        yarn.stdout.on('data', (data) => {
    
    
            process.stdout.write(data);
        });
		// 实时监听该命令的结束指令并打印
        yarn.stdout.on('end', () => {
    
    
            process.stdout.write('dependencies install complete \n');
            return resolve();
        })
		// 实时监听该命令的关闭指定并打印
        yarn.stdout.on('close', () => {
    
    
            process.stdout.write('dependencies install close \n');
            return resolve();
        });
    });
};

// 编译打包命令
const buildDist = async ()=>{
    
    
    return new Promise((resolve) =>{
    
    
		// 执行打包命令
        const yarn = exec('yarn run build');
        yarn.stdout.on('data', (data) => {
    
    
            process.stdout.write(data);
        });
        yarn.stdout.on('end', () => {
    
    
            process.stdout.write('build complete \n');
            return resolve();
        })
        yarn.stdout.on('close', () => {
    
    
            process.stdout.write('build close \n');
            return resolve();
        });
    });
};

// 立即执行函数,对比新旧两个依赖是否相同,然后执行依赖安装和打包编译操作
(async () => {
    
    

    const oldPro = oldJson.dependencies;
    const oldDev = oldJson.devDependencies;
    const oldProKeys = Object.keys(oldPro);
    const oldDevKeys = Object.keys(oldDev);

    const newPro = newJson.dependencies;
    const newdDev = newJson.devDependencies;
    const newProKeys = Object.keys(newPro);
    const newDevKeys = Object.keys(newdDev);

    let isInstall = false;

	// 对比新旧package.json的dependencies
    const loopProDependencies = () => {
    
    
        if (isInstall) {
    
    
            return;
        }
        /**
     * 对比新旧两个版本的安装包,出现以下情况的,需要重新安装依赖包
     * 1. 新的依赖在旧依赖中不存在的
     * 2. 新的依赖和旧依赖中版本号不同的
     */
        for (let i = 0; i < newProKeys.length; i++) {
    
    
            const prokey = newProKeys[i];
            const proKeyVersion = newPro[prokey];

            const oldKey = oldProKeys.find((v) => v === prokey);
            if (!oldKey) {
    
    
                process.stdout.write(`${
      
      prokey} no found, need install dependencies \n`);
                isInstall = true;
                break;
            }
            const oldKeyVersion = oldPro[oldKey];
            const isSameVersion = oldKeyVersion === proKeyVersion;
            if (!isSameVersion) {
    
    
                process.stdout.write(`${
      
      prokey} version difference, old_version:${
      
      oldKeyVersion} new_version:${
      
      proKeyVersion} \n`);
                isInstall = true;
                break;
            }
        }
    }

	// 对比新旧package.json的devDependencies
    const loopDevProDependencies = () => {
    
    
        if (isInstall) {
    
    
            return;
        }
        /**
     * 对比新旧两个版本的开发环境安装包,出现以下情况的,需要重新安装依赖包
     * 1. 新的依赖在旧依赖中不存在的
     * 2. 新的依赖和旧依赖中版本号不同的
     */
        for (let i = 0; i < newDevKeys.length; i++) {
    
    
            const devKey = newDevKeys[i];
            const devKeyVersion = newdDev[devKey];
            const oldKey = oldDevKeys.find((v) => v === devKey);
            if (!oldKey) {
    
    
                process.stdout.write(`${
      
      devKey} no found, need install dependencies \n`);
                isInstall = true;
                break;
            }
            const oldKeyVersion = oldDev[oldKey];
            const isSameVersion = oldKeyVersion === devKeyVersion;
            if (!isSameVersion) {
    
    
                process.stdout.write(`${
      
      devKey} version difference, old_version:${
      
      oldKeyVersion} new_version:${
      
      devKeyVersion} \n`);
                isInstall = true;
                break;
            }
        }
    }

    loopProDependencies();
    loopDevProDependencies();

    await installDependencies(isInstall);
    await buildDist();
})();






猜你喜欢

转载自blog.csdn.net/qq_42427109/article/details/132133767