记录--前端项目中运行 npm run xxx 的时候发生了什么?
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
npm 是 node 捆绑的依赖管理器,常用程度可想而知。那么你每天都在 npm/yarn run 的命令到底是如何运行项目的呢?
前端项目中运行 npm run xxx 的时候发生了什么?
大家都知道目前的 node 是捆绑 npm 的。npm 是 node 的依赖管理器,虽然它不是唯一的选择,我们还有 pnpm/yarn/cnpm/ni 。
但是,的依赖管理器都是在解决 npm 的某个痛点。对于 npm 依赖声明文件
package.json
本身是基本没有变化的。
例如我们可以使用
npm run serve
运行某个命令, 也可以使用
yarn serve
运行某个命令。
可以看到在这个地方 yarn 可以省略 run 这个参数。
但是,他们都只是对
package.json
进行解析而已,例如下面的文件,当运行
npm run serve
时,其实就是运行该 json 文件中的
scripts
下的
serve
键对应的命令。
{
"name": "h5",
"version": "1.0.7",
"private": true,
"scripts": {
"serve": "vue-cli-service serve"
},
"dependencies": {
"axios": "^0.19.2",
"vuex": "^3.4.0"
},
"devDependencies": {
"node-sass": "^4.12.0"
}
}
上面说是 命令
只是用于方便理解,例如:
npm run server
# 类似于在命令行运行以下命令
vue-cli-service serve
通过 npm run 与直接运行命令的区别
还是用上面的配置来描述:
{
"scripts": {
"serve": "vue-cli-service serve"
}
}
npm 在运行
vue-cli-service serve
这条命令的时候,会先在当前
node_modules/.bin
下面看有没有同名的可执行文件,如果有,则使用其运行。
这里我们可以打开这个目录看看:

如果直接在命令行中运行
vue-cli-service serve
这条命令,是不会从 node_modules 中查找可执行程序的。
运行可执行文件
那么什么叫可执行文件呢?上面的图中有很多个同名的 vue-cli-service ,到底是运行哪个?
我们先来分析这几个文件怎么来的?
例如
@vue/cli-service
有以下
package.json
文件,注意 bin 字段,当我们运行
npm i @vue/cli-service
这条命令时,npm 就会在
node_modules/.bin/
目录中创建好以
vue-cli-service
为名的几个可执行文件了。
{
"name": "@vue/cli-service",
"version": "4.4.6",
"description": "local service for vue-cli projects",
"main": "lib/Service.js",
"typings": "types/index.d.ts",
"bin": {
"vue-cli-service": "bin/vue-cli-service.js"
}
}
对于可执行这个定义,每个系统不一样。在 windows 系统上,可执行文件是通过组策略和环境变量决定的。
使用
set pathext
可以查看
pathext
这个环境变量,他定义了可以作为可执行文件的后缀。
# 查看可执行文件后缀
set pathext

由上面的配置可以发现,我们常见的 exe 也在其中,这个可执行文件在 windows 上,在命令行中输入文件名或双击时即可以运行。
在 unix 系统上面,是通过设置文件的属性为可执行,再在文件中的第一行声明解释器来运行的。

如果我们在 cmd 里运行的时候,windows 一般是调用了
vue-cli-service.cmd
这个文件,这是 windows 下的批处理脚本:
@ECHO off
SETLOCAL
CALL :find_dp0 SET _maybeQuote="
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET _maybeQuote=
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
) %_maybeQuote%%_prog%%_maybeQuote% "%dp0%\..\_@vue_cli-service@4.4.6@@vue\cli-service\bin\vue-cli-service.js" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b
所以当我们运行
vue-cli-service serve
这条命令的时候,就相当于运行
node_modules/.bin/vue-cli-service.cmd serve
然后这个脚本会使用 node 去运行
vue-cli-service.js
这个 js 文件,由于 node 中可以使用一系列系统相关的 api ,所以在这个 js 中可以做很多事情,例如读取并分析运行这条命令的目录下的文件,根据模板生成文件等。
# unix 系默认的可执行文件,必须输入完整文件名
vue-cli-service # windows cmd 中默认的可执行文件,当我们不添加后缀名时,自动根据 pathext 查找文件
vue-cli-service.cmd # Windows PowerShell 中可执行文件,可以跨平台
vue-cli-service.ps1
这里多提了下,在 windows 中 cmd 脚本使用得比较多,兼容性也较好。 powerShell 虽然比较强大,但他运行命令的方式由于和 cmd 命令有较大不同,这会导致你常常搞不清什么命令应该在什么解释器里运行。
示例:运行命令的方式不兼容

示例:windows 很多系统会默认禁止此脚本运行,导致 npm 命令运行错误

所以如果遇到 powerShell 相关错误时建议用 cmd 试试。
注入相关运行时信息
这一节我们通过调试 npm 的源码来进行说明。
首先我们在 mockm 这个前端接口联调工具的源码中先来个 debugger, 注意有从 process.env 中获取 NPM_CONFIG_REGISTRY 这个环境变量,这是 npm 安装时可配置的镜像地址。

然后我们再看一下这个环境变量,在当前系统中是没有定义的。

让我们开始调试 mockm package.json 中的 scripts
npm run s2
{
"scripts": {
"s2": "node run.js remote --config=D:/git2/mockm/server/example/full.mm.config.js",
}
}

为了节省篇幅,这里直接断点在关键地点:

这是 npm@v6.x 的源码,可以发现 npm 使用了 npm-lifecycle 这个依赖来运行的子进程调用我们的
run.js
文件。
在通过 spawn 运行 run.js 的时候,同时设置了进程相关的一些信息,这是由 node 原生支持的。

例如刚刚说到的 NPM_CONFIG_REGISTRY 环境变量。
下面把继续进入下一个断点, run.js 文件:

可以发现子进程成功获取了父进程给予的信息。
总结
运行 npm run xxx
的时候,npm 会先在当前目录的 node_modules/.bin 查找要执行的程序,如果找到则运行;
没有找到则从全局的 node_modules/.bin 中查找,npm i -g xxx
就是安装到到全局目录;
如果全局目录还是没找到,那么就从 path 环境变量中查找有没有其他同名的可执行程序。
本文转载于:
https://blog.51cto.com/u_15077533/4531157
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

记录--前端项目中运行 npm run xxx 的时候发生了什么?的更多相关文章
- 三面面试官:运行 npm run xxx 的时候发生了什么?
事情是这样的,直接开讲 面试官:npm run xxx的时候,发生了什么?讲的越详细越好. 我(心想,简单啊): 首先,DNS 解析,将域名解析成 IP 地址,然后 TCP 连接,TCP 三次握手.. ...
- React中使用create-react-app创建项目,运行npm run eject建立灰度报错
我在运行npm run eject建立测试环境和正式环境时候报错 这里的问题是是脚手架添加.gitgnore文件,但是却没有本地仓库,按照以下顺序就可以正常使用 git add . git commi ...
- react创建项目后运行npm run eject命令将配置文件暴露出来时报错解决方法
最近在用create-react-app创建项目,因要配置各种组件,比如babel,antd等, 需要运行npm run eject命令把项目的配置文件暴露出来,但是还是一如既然碰到报错,因为是在本地 ...
- create-react-app创建项目后运行npm run eject命令报错解决办法
最近在用create-react-app创建项目,因要配置各种组件,比如babel,antd等, 需要运行npm run eject命令把项目的配置文件暴露出来,但是还是一如既然碰到报错,因为是在本地 ...
- 使用create-react-app命令创建一个项目, 运行npm run eject报错
解决方法: 先 git add . 然后 git commit -m ‘init’ 然后再npm run eject
- Vue项目中执行npm run dev 不报错也不显示点击的地址链接
问题描述: 输入npm run dev 没有报错也没有显示可以点击的地址链接,如下图: 解决方法: 具体配置: autoOpenBrowser默认为false,改为true.重新 npm run de ...
- react 记录:运行npm run eject命令暴露配置文件都报这个错误
问题: react 使用create-react-app命令创建一个项目,运行npm run eject命令暴露配置文件都报这个错误 原因:主要是脚手架添加 .gitgnore文件,但是却没有本地仓库 ...
- 在 ASP.NET Core 项目中使用 npm 管理你的前端组件包
一.前言 在项目的前端开发中,对于绝大多数的小伙伴来说,当然,也包括我,不可避免的需要在项目中使用到一些第三方的组件包.这时,团队中的小伙伴是选择直接去组件的官网上下载,还是图省事直接在网上搜索,然后 ...
- create-react-app创建项目后,运行npm run eject报错解决方法
运行npm run eject报错解决方法 主要问题是脚手架添加.gitgnore文件,但是却没有本地仓库,使用以下命令操作以下就可以了 git init git add . git commit - ...
- 结合docker发布前端项目(基于npm包管理)的shell脚本
结合docker发布前端项目(基于npm包管理)的shell脚本 本教程依据个人理解并经过实际验证为正确,特此记录下来,权当笔记. 注:基于linux操作系统 目前主流的前后端分离的项目中,常常在部署 ...
随机推荐
- 开源.NetCore通用工具库Xmtool使用连载 - 散列算法篇
[Github源码] <上一篇>详细介绍了Xmtool工具库中的加解密类库,今天我们继续为大家介绍其中的散列算法类库. 散列算法在某些特殊场景也可以当做加密方法使用:其特点是不可逆,同一内 ...
- ABC 311
前四题过水 E 枚举正方形的上边界所在行.对于第 \(i\) 行一个没洞的位置 \((i,j)\),我们尝试求出以它为右上角的无洞正方形个数. 结论:设以 \((i,j-1)\) 为右上角的无洞正方形 ...
- Mysql 8.0 Navicat连接Mysql报错Authentication plugin ‘caching_sha2_password‘ cannot be loaded
1.终端登陆MySQL$ mysql -u root -ppassword #登入mysql 2.修改账户密码加密规则并更新用户密码ALTER USER 'root'@'localhost' IDEN ...
- NC53370 Forsaken的三维数点
题目链接 题目 题目描述 Forsaken现在在一个三维空间中,空间中每个点都可以用 \((x,y,z)\) 表示.突然,三维空间的主人出现了,如果Forsaken想要继续在三维空间中呆下去,他就 ...
- 蔚来杯2022牛客暑期多校训练营3 AC
比赛链接 A 题解 知识点:LCA. 队友写的,俺不会qwq.预处理出关键点序列的在树A B上的前缀LCA和后缀LCA,枚举去掉的关键节点并使用前后缀LCA算出剩余节点的LCA比较权值即可. 时间复杂 ...
- Spring源码之容器的功能拓展-ApplicationContext
目录 一.解析预备 刷新上下文环境 例如对系统属性或者环境变量进行校验和准备 二.初始化 BeanFactory 并进行 Xml 配置文件的读取 三.对BeanFactory 各种功能填充 四.激活以 ...
- Advanced .Net Debugging 2:CLR基础
一.简介 这是2024新年后我的第一篇文章,也是我的<Advanced .Net Debugging>这个系列的第二篇文章.这篇文章告诉我们为了进行有效的程序调试,我们需要掌握哪些知识.言 ...
- 无所不谈,百无禁忌,Win11本地部署无内容审查中文大语言模型CausalLM-14B
目前流行的开源大语言模型大抵都会有内容审查机制,这并非是新鲜事,因为之前chat-gpt就曾经被"玩"坏过,如果没有内容审查,恶意用户可能通过精心设计的输入(prompt)来操纵L ...
- 【Azure Developer】使用 Azure PowerShell 执行 Azure 表存储操作时遇见的4个问题
要使用PowerShell操作Azure的表存储,需要经过以下步骤: 1:必须安装 Az 和 AzTable 模块.安装命令为: #安装 Az 模块 Install-Module -Name Az - ...
- Jmeter 之常数吞吐量作用
一 添加方法: 线程组右键->添加->定时器-> 常数吞吐量定时器 二 作用: 常数吞吐量定时器的作用: 设置最大的吞吐量不超过设置的值 注意:如果线程能发送的请求远远低于设置的 ...
