
前言:
面试官:当你在使用`npm run xxx`时,它背后到底发生了什么?能否详细解释一下?
我:当你执行`npm run xxx`时,首先会创建一个shell,然后在该shell中执行指定的脚本。这个过程中涉及DNS解析和TCP连接,但主要是关于执行脚本的流程。
执行原理:
使用npm run script执行脚本的时候,首要步骤是创建一个shell环境。这个shell会将当前项目的可执行依赖目录(即node_modules/.bin)添加到环境变量path中,这样脚本命令中的依赖名可以直接找到对应的脚本,而无需加上路径。
执行顺序:
一个npm脚本可以执行多个任务,这些任务之间可以指定不同的执行顺序。例如,“&”表示并行执行,而“&&”则表示只有前一个任务完成后才会执行下一个任务。
关于`npm run dev`的具体流程:
以Vue CLI 3配置为例,当你在项目中执行`npm run dev`时,npm会去package.json里的scripts字段查找名为“dev”的命令,如果配置了,就会执行对应的命令,如“vue-cli-serviceserve”。vue-cli-service是一个命令组合,包含了构建、开发服务器等多个功能。
关于.bin目录:
在回答面试官关于.bin目录的问题时,我了解到,在npm install时,会将某些bin文件软链接到./node_modules/.bin目录下。这些软链接文件是包的点,例如vue-cli-service的可能就是其中的一个js文件。npm会自动把node_modules/.bin加入$PATH变量,这样就可以直接作为命令运行依赖程序和开发依赖程序,而无需全局安装。这样,即使我们没有全局安装vue-cli-service,也可以通过npm run serve来执行vue-cli-service serve。这是因为npm会在node_modules/.bin目录下找到对应的脚本并执行。至于那些软链接文件是如何生成的,它们实际上是npm在安装时根据包的配置创建的。至于为何能执行而没有报错,是因为node已经全局安装并可以直接被调用。如果我们没有运行npm run命令,那么默认会尝试执行node server.js命令(如果存在)。如果scripts字段中没有start命令也不会报错,会直接默认执行node server.js。最后提及的是关于软链接的工作原理和它们在.bin目录下的映射关系。当我们安装包并使用npm install -g xxx进行全局安装时,相应的bin文件会被加入到全局目录,如创建react应用时的create-react-app命令。关于webpack-dev-server的部分也做了简要介绍。它启动了一个express的Http服务器来伺服资源文件并与client使用websocket通讯协议进行实时编译更新。最后部分提到了在运行npm脚本时可能出现的一些常见错误及其解决方法。总结起来就是运行npm run xxx时,npm首先在当前目录的node_modules/.bin中查找要执行的程序,如果找到则运行;否则从全局的node_modules/.bin中查找;如果还是找不到就从path环境变量中查找是否有其他同名的可执行程序。
