社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
在安装 npm 包模块的时候,不管是 Webpack 、React 还是 Vue,都需要全局安装,即执行 npm install webpack -g 或者 npm install @vue/cli -g,否则在使用命令(比如查看版本,webpack -v)的时候就会报错 ‘webpack’ 或者 ‘vue’ 不是内部或外部命令,也不是可运行的程序或批处理文件,很多人都是靠全局安装去解决这个问题,那么你知道为什么全局安装可以解决这个问题,或者有没有其他更优的方案吗。今天就给大家分享一下出现这个问题的原因及更好的解决办法。
在解释这个原因之前先普及一下基本知识。
注意:
a 目录下面有 b 和 index.js ,即 b 和 index.js 是同级目录
b 目录下面也有 index.js 及 test.cmd
a 目标下的 index.js 内容如下:
console.log('hello world a');
b 目录下的 index.js 内容如下:
console.log('hello world b');
test.cmd 内容如下:
node "%~dp0..index.js" %*
在当前根目录,也就是 a 目录下执行 test 命令,出现如下报错
因为 a 目录下并没有 test.cmd 文件,而 test.cmd 文件是在 b 目录下。所以切换到 b 目录下执行 test 命令,打印出 ‘hello world a’
那么如果我们想打印出 ‘hello world b’ 怎么办昵,就需要分析一下该 index.js 文件的路径了,可以看到该文件直接在 a 目录下。所以需要修改 test.cmd 文件的执行文件(需要执行的那个 js)路径为
node "%~dp0index.js" %*
修改后再次执行 test 得到结果
看到这里就不难猜出报以上错误的原因:
有了以上知识的普及,现在我们定位到具体的项目中。如果没有全局安装模块,只是将模块安装在了当前目录下,而我们执行命令的时候,却总是在项目目录下执行。我们的项目目录下并没有 cmd 执行文件。所以就报了以上错误。现在就基于以上分析的没有 cmd 文件和要执行的文件路径有误这两点说说几种解决方案。
1. 全局安装模块
这个是众所周知的解决方案,基于以上的知识点我们再来分析能解决这个问题的原因。
@IF EXIST "%~dp0node.exe" (
"%~dp0node.exe" "%~dp0node_moduleswebpackbinwebpack.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0node_moduleswebpackbinwebpack.js" %*
)
2. 在 cmd 执行文件下运行命令
@IF EXIST "%~dp0node.exe" (
"%~dp0node.exe" "%~dp0..webpackbinwebpack.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0..webpackbinwebpack.js" %*
)
再啰嗦一下,“%~dp0” 表示当前路径,也就是 .bin 目录,"… "表示上级项目,也就是 node_modules 目录,所以该文件路径也是正确的。问题就是每次只能在 项目路径/node_modules/.bin 目录下去使用 webpack 命令了。而我们一般情况下习惯直接在项目目录下去使用命令,那应该怎么做昵?
3.添加 cmd 文件,修改对应路径
@IF EXIST "%~dp0node.exe" (
"%~dp0node.exe" "%~dp0..webpackbinwebpack.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0..webpackbinwebpack.js" %*
)
那么这里的 “%~dp0"指的就是项目目录了,”…" 就到项目目录的上一级目录了,自然不是我们想要的,很显然项目目录下的 webpack.js 文件路径应该是 项目目录/node_modules/webpack/bin/webpack.js。(可能有些人的目录不一定是我这样的,你只需要找到你自己项目下的 webpack.js 文件路径即可)。那么这里就只需要把 “…” 改成 “node_modules” 就是 webpack.js 的正确路径了。即
@IF EXIST "%~dp0node.exe" (
"%~dp0node.exe" "%~dp0node_moduleswebpackbinwebpack.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0node_moduleswebpackbinwebpack.js" %*
)
其实这跟全局下的 cmd 文件路径是一样的,所以如果从全局下复制过来的 webpack.cmd 文件就不用做任何修改了。
以上3种方案中各有利弊,如果是全局安装,一般情况下肯定也会在项目目录下安装一份,这将造成每个模块都会安装两遍的内存消耗;而只在项目目录下安装并使用以上说的第二种方案每次都在 .bin 目录下执行命令无疑比较麻烦;所以第三种方案,直接复制一份 cmd 文件到项目目录下并修改相应的文件执行路径是最优方案。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!