npm run 是什么?为什么使用npm run 这一命令,就能够将 webpack 跑起来并进行下一步的操作?

1,319 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情

npm run 实际上是衔接 node 和 webpack 的连接点。先看看终端运行的npm是什么,如下图:

image-20220805142328846.png

图中的关键点是最后一行 C:\Users***\AppData\Roaming\npm\node_modules\npm。从它可以推断出系统环境变量下配置的npm的路径为C:\Users***\AppData\Roaming\npm,可以去环境变量中确认,如下:

image-20220805142146428.png

然后查看npm.cmd的批处理命令,如下:

@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
​
IF EXIST "%dp0%\node.exe" (
  SET "_prog=%dp0%\node.exe"
) ELSE (
  SET "_prog=node"
  SET PATHEXT=%PATHEXT:;.JS;=;%
)
​
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%"  "%dp0%\node_modules\npm\bin\npm-cli.js" %*

它的批处理的语法过程,可以参考上一篇:npm run dev 后 webpack-dev-server 做了哪些事情 中对于 webpack-dev-server.cmd的描述。这里通过 npm.cmd 的执行达到的目的就是执行 node 项目根路径\node_modules\npm\bin\npm-cli.js run dev

小TIPS:如果需要明确认识到批处理中的每一个变量的含义,可以创建一个临时文件,假设命名 temp.cmd ,然后在文本方式打开,输入如下内容:

set dp0=%~dp0
echo %dp0%

这样就能够调试确认对应的变量,加深对于windows上批处理命令的学习和理解。

因为这儿要说明的问题是 npm run ,而不是 npm run dev 后的内容。所以 npm run 它实际上是基于node 的可执行程序,接收三个参数并分析的过程。

这三个参数分别就是:

  • 项目根路径\node_modules\npm\bin\npm-cli.js
  • run
  • dev

下面我们简单说一下这个过程,因为它涉及到 node ,又涉及到 npm 。在vscode中调试(调试的配置方式在上一篇:npm run dev 后 webpack-dev-server 做了哪些事情 中有详细的配置过程)的时候可以通过调用堆栈找到入口的节点如下:

image-20220805144310140.png

对于这里的 internal/modules/cjs/loader 可能会在调试过程中会添堵,会纠结这个 internal 究竟是什么,它在哪儿。其实是node执行环境中的内部逻辑。这个node的开源源代码中可以找到踪迹。如下:

image-20220805145027786.png

在后续的步骤中它会调用的关键业务是在 run-script.js 中的 async exec 方法对于run方法的调用,来读取并解析项目根路径下的 package.json,如下:

image-20220805150931824.png

到这一步基本上就算是把 node 和 npm 连接,并且通过 npm 对于 package.json 的拆分 和 dev 下的 webpack-dev-server 连接起来。从宏观上理解这一流程,就更加顺滑,更加有方向感。

关键的解决问题思路,侧重于两个方面:①调试环境的配置;②源码的溯源和分析。

至于你是深入 node.js 或者是 npm ,亦或是 webpack 可以根据实际情况进一步深入。这一篇文章笔者是为了介绍webpack之前,为运行webpack的前提可能涉及到的问题扫清障碍。