一条命令引发的惨案

75 阅读2分钟

案件陈述

  • 事件起因:前端工程合并npm-scripts导致打包配置文件无法获取process.env中的属性值

  • 相关对象:

  • npmnode

  • cross-env

初始命令:执行npm start后两个js文件都可以获得process.env.test。下文引用执行命令为start1

"scripts": {
    "start": "cross-env test=true npm run dev",
    "dev": "node a.js && node b.js"
}

合并后命令:执行npm start后只有a.js中可以获得。下文引用执行命令为start2

"scripts": {
    "start": "cross-env test=true node a.js && node b.js"
},

已知:

  1. 直接执行node a.js会创建一个进程;
  2. cross-env内部调用spawn创建子进程且将环境变量键值对env作为新建进程环境变量【参考源码】;
  3. 上述&&符号的作用,第一条命令执行完且进程关闭再去执行后面的命令。

初步解析

执行start1cross-env创建子进程,子进程执行npm run dev且拥有env环境变量,然后依次创建两个子进程分别执行a脚本和b脚本,两个子进程可访问 父进程 部分包括env的环境变量。

执行start2&&符之前命令同上,cross-env创建的子进程执行node a.jsnode会创建一个子进程执行脚本文件,自己成可访问 父进程 环境变量;这两个进程执行结束后退出,运行node b.js,创建一个子进程,此时父进程中不存在env对象自己本身也没有,所以为undefined

以上两部解析可通过简单的process.pid【当前运行的进程ID】和process.ppid【当前运行进程的父进程ID】证明,进程ID一致说明是同一进程。

深入理解系列~后续文章

  1. npm run xxx执行过程、运行原理;
  2. 执行node a.js创建子进程实现过程;
  3. 父进程对子进程暴露范围;
  4. 父进程与子进程并不是严格意义上的父子进程,可以当作兄弟进程看待;
  5. 进程之间的通信;
  6. nodeJs中的线程;
  7. nodeJs中多进程如何进行有效管理。