jiefancis / blogs

个人博客,学习笔记(issues)
1 stars 0 forks source link

深入npm run xxx的原理 #21

Open jiefancis opened 2 years ago

jiefancis commented 2 years ago

从一个问题来探讨

'vue-cli-service' 不是内部或外部命令,也不是可运行的程序或批处理文件

遇到这种问题,大部分人的做法是:要么重新删除node_modules包然后重新install,要么install vue-cli-service,接着重新运行项目就会正常启动。大多数人到这里就结束了,反正项目正常运行了不是么?当然不是,如果到这里结束了我也没必要写这篇文章。

vue-cli-service

当我们在项目安装了vue-cli-service依赖包后,在目录下vscode终端(也可以是cmd命令行或者powershell,本篇文章默认均在vscode终端运行)输入vue-cli-service指令时,得到的是一个报错信息:'vue-cli-service' 不是内部或外部命令,也不是可运行的程序或批处理文件。但当我们执行npm run dev(serve)的方式运行时,却可以正常运行,这是什么原因呢?仔细查看vue-cli-service/package.json文件,它有一个bin字段,在npm包中,bin字段表示这个包是一个可执行文件,格式为

bin字段对应的值是一个字符串,命令则是package.json的name
{
    name: "app-name",
    "bin": "./bin/xxx(-cli).js
}
或者
{
    "bin: {
        "命令": "./bin/xxx(-cli).js"
    }
}

同样,在包的根目录下存在一个bin目录(当然可以写别的名称,但是bin是一个规范),这是当前依赖包的执行文件,我们执行npm run dev时实际执行的命令是vue-cli-service serve,为什么我们直接执行vue-cli-service serve时却会报错呢?

.bin软连接

我们执行npm run dev时,实际执行vue-cli-service serve命令,这时npm会去项目的node_modules/.bin目录下查找vue-cli-service.cmd(或者.ps1)可执行文件,这个文件指定了vue-cli-service指令实际要执行的文件路径而去执行这个文件。所以npm install 局部安装做了两件事:1、下载依赖包到项目node_modules目录下,2、如果这个依赖包是一个可执行文件(package.json中存在bin参数),会在node_modules/.bin目录下创建这个可执行文件的软链接。
如果你想自己实现一个可执行程序包,请确保你的bin文件里面最开头写上 #!/usr/bin/env node,否则文件里的脚本不会在Node环境下执行。

npm install全局安装

上面讲的是在项目中安装(局部安装)可执行程序的过程,当我们想要全局安装某个可执行程序时,会执行npm install -g xxx命令,这个命令会在C:\Users\用户名\AppData\Roaming\npm目录下创建该程序的软链接并且在电脑的环境变量中注册,当我们在全局环境下执行程序的命令时,也是会到Roming/npm下找到该程序的可执行文件,这个可执行文件指明了要执行的文件的路径(指向Roming/npm/node_modules/下的某个路径),从而找到实际要执行的文件后在执行的环境下执行。当然可以通过win+r 输入cmd回车进入cmd命令行输入where npm的指令,找到npm全局安装实际安装的路径

vue-cli-service做了什么?

在早期版本的vue项目中,项目的webpack配置在build和config两个文件中,通过config配置webpack运行和打包两种环境的参数配置,在build目录中执行webpack+webpack-serve实现本地运行,后面vue-cli将webpack默认配置生成在自己项目中,并且给用户提供一个vue.config.js文件支持参数自定义,vue-cli-service通过require的方式加载用户自定义参数与默认参数进行合并启动用以启动项目。