前端初学者必经之路-深入理解npm与cli
前言
Hello,大家好~,我是只会三步上篮。我们都知道在每个前端项目中,都有 package.json 文件,它是项目的配置文件,常见的配置有配置项目启动、打包命令,声明依赖包等。package.json 文件是一个 JSON 对象,该对象的每一个成员就是当前项目的一项设置。初学前端的时候,我们都知道安装npm包的命令npm install
, 比如全局安装vue-cli、webpack-cli等这些命令行工具,或者本地安装element-ui、vant这些组件库或者js库。安装组件库或者js库还好理解,但是安装cli之后,让我一头雾水。我就产生了一些疑问,
全局安装cli时,npm到底在背后帮我做了什么,让用户全局都能找到并且执行它?
局部安装cli时,为什么需要配置scripts,再通过npm run xxx运行?
这两个问题解释其实就是解释了npm install
和npm run
背后到底做了什么?
我通过全局安装和局部安装cli做探讨。
准备工作
我们s首先要知道全局安装的包在什么位置。
执行:npm root -g
可以看到我的全局npm包安装在C:\Program\node_modules里。
1.写一个简易cli的npm包
开发简易cli,需要你对Node.js有一定的基础,但是本文只是举个很简易的cli,针对初学者,不需要Node.js基础。如果你会可以直接跳过哦。
如果你会,可以直接跳过。
执行命令
mkidr my-cli
cd my-cli
npm init -y
再在该目录下创建bin文件夹,在bin文件夹下创建一个js文件。
该cli的功能就是控制台打印hello cli
在cmd里通过命令执行还需要在package.json里配置bin对象(开发cli配置bin必不可少,不清楚可以去npm官网了解下), 命令就叫say-hello
好了
"name": "my-cli223",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"bin": {
"say-hello": "./bin/index.js"
},
"keywords": [],
"author": "",
"license": "ISC"
}
2.发布npm包
- 首先去npm官网上去注册一个自己的账号
- 执行
npm login
登录 - 执行
npm publish
进行发布npm包(别忘记将npm源设置为registry.npmjs.org/ ,并且package.json里的name值要唯一)
开始
1.全局安装npm包
上面我们已经发布了自己的cli,我们通过npm全局安装到本地。安装完之后,我们进入到全局node_modules里已经有了自己的cli包,还会发现program的目录下多了三个文件.
这就说明执行命令npm i xxx -g
时,会在我们的包目录下生成这三个文件。我们任意位置打开cmd执行say-hello
,打印了'hello cli'
为什么会生成三个文件呢?
生成三个文件,其实是为了兼容不同的操作系统。
// unix 系默认的可执行文件,必须输入完整文件名
say-hello
// windows cmd 中默认的可执行文件,当我们不添加后缀名时,自动根据 pathext 查找文件
say-hello.cmd
// Windows PowerShell 中可执行文件,可以跨平台
say-hello.ps1
当在任意cmd里执行say-hello时,其实就是到了C:\Program下面执行say-hello.cmd这个脚本,然后这个脚本里面存放着需要执行的文件的路径信息。用记事本打开该文件看一下:
就会去标红这个路径执行index.js。这个路径就是之前在package.json里配置的。
为什么可以在全局执行命令?
执行命令能够找到具体位置,得益于在windows系统里配置了环境变量,执行命令的时候,就会去这些路径下找可执行的程序。
2.局部安装npm包
先卸载上面安装的全局cli,npm uninstall xxx -g
。
我用一个vue3的项目去举例。
npm install xxx -s
安装完之后执行say-hello
可以看到本地安装了之后,无法直接在项目里执行命令.
看这个错误提示,意思就是在c盘下面没有找到可执行的脚本文件或者其它可执行的程序。当执行这个命令时,会在当前目录下看看能不能找到该命令的脚本,没有找到,则会去全局里找,但是全局里面并没有这个脚本,所以找不到。
npm局部安装时帮我们做了什么?
其实跟全局安装包时操作的一样,当我们使用 npm命令安装包时,如果该包的 package.json
文件有 bin 字段,就会在 node_modules
文件夹下面的 .bin
目录中复制了 bin 字段链接的执行文件。
进入到该项目的node_modules里一探究竟
我们会发现有个bin文件夹,再进入到bin文件夹里,会看到有很多的脚本,也有say-hello脚本。
接下来,我们在package.json里配置scripts,新增一条
这个时候在当前项目下的cmd通过npm run
执行say-hello,发现执行成功。
那么npm run做了什么
npm run
运行 npm run xxx的时候,npm 会先在当前目录的 node_modules/.bin 查找要执行的程序,如果找到则运行;
没有找到则从全局的中查找,如果全局目录还是没找到,那么就从 path 环境变量中查找有没有其他同名的可执行程序
scripts: { 'say-hello': 'say-hello' }
//等同于
scripts: { 'say-hello': './node_modules/bin/say-hello.cmd' }
总结
1.当我们使用 npm 命令安装包时,如果该包的 package.json
文件有 bin 字段,全局安装的话会在全局的node_modules的同级目录下生成可执行的脚本文件,局部安装的话会在局部的node_modules里的bin下生成可执行的脚本文件。
2.执行npm run xxx
,就会去当前目录的node_modules/bin下执行对应的程序。
转载自:https://juejin.cn/post/7216209996525961277