深入学习npm
npm详解
我们在前面安装Nodejs的时候提到过npm
是Nodejs
的一个包管理工具,后来还介绍了一些npm
的替代品,如cnpm
、yarn
和pnpm
,本节我们来深入了解一下,npm
到底是个什么东西?
npm的组成-registry
作为一个程序员,无论你的发展方向是什么,你肯定知道世界上最伟大的网站github
。之所以说它伟大,唯一的原因就是,它提供了无数开源
的代码。
开源,一直以来都是推动软件开发和IT行业的重要力量。
如果没有开源,那么现在也不会有这么多程序员,你所使用的java
、javascript
等编程语言都是开源的。开源,也就是开放源码,你可以任意阅读它的源码。
github
本身不提供代码,它的代码由无数开发者上传,供大家学习,我们从github
下载代码之后,需要自行修改,使其融入我们的项目。
这样一来就会产生一个问题,比如作为一个前端开发者,我只需要前端相关的项目、插件或者工具;并且我们希望能够很方便地将这些代码进行下载并应用到我们的项目中,这显然是github
做不到的。
我们需要一个以语言为界限,将针对不同语言的开源代码上传到不同的"github",这里的"github"就可以理解为我们的npm
。
不仅仅是Nodejs
,像Python
、Java
都有类似的包管理工具。
开发者根据不同的开发语言的模块化以及不同的包管理工具,将代码以特定的格式进行约束,然后上传到名为"hub"的地方,在npm
中,这个"hub"被称为registry
。
registry
是npm
的核心,所有与nodejs
相关的代码都被上传到registry
中,我们称这些代码为package 包
,npm
就是node package manager
,Nodejs
的包管理者。
npm
默认的registry
为https://registry.npmjs.org。
npm的组成-website
有了这些包,我们就可以去使用它们,但是这里就产生了一个问题,我怎么知道有哪些包可以使用?
遇事不决问百度,但是百度也有不会的时候。比如你需要一个工具来发送http请求,百度只会告诉你,工具的名字是什么,但是它不会告诉你该如何去获取它。
npm为我们提供了一个网站用于查找包,这个网站其实就是npm的官网。
我们可以在这上面搜索各种各样的包,如axios
。
由于这些包是由全世界的开发者上传,因此出现同名或者相似名字是很常见的事情,我们要学会区分是不是我们真正想要的。
- 首先可以看名字是否和我们查找的一样;
- 第二可以看作者或者组织是否是官方;
- 最后可以查看下载量,当你在两个类似功能的包直接犹豫不决的时候,选下载量大的准没问题。
我们点击第一个搜索结果,进入详情页。
在这里你会看到很多有用的东西:
- 包的名字;
- 包的介绍,使用Markdown编写,一般是包的快速入门教程;
- 包的源码;
- 包的依赖,这个包可能还使用了其他的包;
- 包的历史版本;
- 如何安装包;
- 包的github地址;.
- 官网地址;
- 周下载量;
- 当前版本;
- 最近一次更新时间。
npm的组成-cli
cli
是命令行接口的意思,命令行是计算机中用来直接与计算机进行交互的窗口。
就是类似于这玩意的:
你的电脑可以会有其他版本的命令行,它们功能基本都是一样的。
对于初学者来说,我们只需要学会一些常用的命令即可。
npm-config
用于配置npm。
npm-init
用于初始化项目,其实就是创建一个package.json
文件,该文件可以用来配置项目相关信息。
npm-install
用安装包,该命令应用场景较多:
npm install <package-name>
用于在当前目录安装某个包;npm install <package-name> -g
用于在全局安装包;npm install
用于将当前目录下package.json
中配置的所有包进行安装。
install
可以简写为i
,-g
表示全局安装,会安装在npm
的目录下的node_modules
中,如果不加-g
会默认安装在当前目录的node_modules
。
你也可以通过在包名后面加上@version
的方式指定需要安装的版本号。
npm-start
用于启动命令,也可以写成npm run start
,命令在package.json
中配置:
json
{
"scripts": {
"start": "node foo.js"
}
}
当你拿到一个项目的时候,你应该先去package.json
文件中去查找scripts
配置项,看看应该用哪个命令进行启动。
npm-uninstall
卸载某个包。
npm-version
查看npm的版本。
其他命令
npm还有很多命令,如用于上传自己包的命令,用于登录npm账号的命令等,如果需要可以在官网进行阅读。
再谈registry
除了npm
,我们还介绍了yarn
和pnpm
。
那岂不是说开发者需要同步开发这两个工具对应的包呢?
实际上并不是,这两个工具仅仅是提供了安装包的方法,它们本身同步了npm
的仓库,在一方面缓解npm
服务器的压力,提升安装速度;另一方面它们在本地管理包的方式有所不同,在磁盘空间使用和读取效率上会有所提升。
目前国内用的比较多的是阿里开发的cnpm
,它为国内开发者提供了非常迅速的下载源,并且每间隔十分钟就同步一次官方仓库,保证了代码的同步性。
package.json配置
package.json
是Node.js
项目的核心配置文件,用于定义项目的元数据和依赖关系。它是npm
工作的基础,几乎所有npm
命令都依赖此文件。
基本结构
json
{
"name": "my-project",
"version": "1.0.0",
"description": "A brief description of the project",
"main": "index.js",
"scripts": {
"start": "node index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": ["example", "nodejs"],
"author": "Your Name",
"license": "ISC",
"dependencies": {
"express": "^4.18.2"
},
"devDependencies": {
"nodemon": "^2.0.22"
}
}
必填字段
- name
- 项目名称,必须是唯一的(在 npm 仓库中)。
- 只能包含小写字母、数字、连字符(-),不能有空格。
- 示例:"name": "my-project"
- version
- 项目版本号,遵循 语义化版本规范(SemVer)。
- 格式:MAJOR.MINOR.PATCH(如 1.0.0)。
- 示例:"version": "1.0.0"
可选字段
- description
- 项目的简短描述,用于 npm 仓库展示。
- 示例:"description": "A simple Node.js project"
- main
- 项目的入口文件(如 index.js),当其他模块引用此包时会加载该文件。
- 示例:"main": "index.js"
- scripts
- 定义自定义脚本命令,可通过 npm run
依赖管理
- dependencies
- 生产环境依赖,项目运行时必需的包。
- devDependencies
- 开发环境依赖,仅用于开发阶段(如测试、构建工具)。
这里提一点,你在通过npm
安装的时候,如npm i axios
会默认将最新版本的axios安装,并加入到dependencies
,但是你通过npm i axios -g
安装的包不会加到这里,-g
表示全局安装,一般只用于安装工具包,如rimraf
、cnpm
等。
还有就是这两个配置只是给开发者看的,并不是说你把axios
放在devDependencies
里面它在生产环境就无法使用,仅仅是从规范上来区分包的类型。
可以通过命令参数决定将包放入哪个选项:
shell
# dependencies
npm i --save axios;
npm i -S axios;
# devDependencies
npm i --save-dev axios;
npm i -D axios;
其他配置
- repository
- 项目代码仓库信息。
- homepage
- 项目主页 URL。
- bugs
- 问题反馈地址(如 GitHub Issues)。
- engines
- 指定项目运行的 Node.js 或 npm 版本范围。
json
"engines": {
"node": ">=14.0.0",
"npm": ">=7.0.0"
}
- files
- 指定发布到 npm 仓库时包含的文件(白名单)。
完整配置
json
{
"name": "my-cli-tool",
"version": "2.0.0",
"description": "A command-line tool for Node.js",
"main": "index.js",
"bin": {
"my-cli": "./bin/cli.js"
},
"scripts": {
"start": "node index.js",
"test": "jest"
},
"keywords": ["cli", "nodejs", "tool"],
"author": "Jane Doe <jane@example.com>",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/jane/my-cli-tool.git"
},
"dependencies": {
"commander": "^10.0.0"
},
"devDependencies": {
"jest": "^29.5.0"
},
"engines": {
"node": ">=14.0.0"
}
}
node_modules
node_modules
是Node.js
项目中用于存放依赖包的目录,是npm
安装依赖时的默认输出目录。了解 node_modules
的结构、作用和管理方式,对于开发高效的Node.js
应用至关重要。
node_modules
是一个树形结构,顶级目录是package.json
中定义的直接依赖,子依赖会嵌套在各自的目录中。
我们在有package.json
的目录下运行npm i
时,会自动下载并安装相关包,这些包都被安装在node_modules
中,开发者不应该去修改node_modules
中的内容。
这张图告诉你,node_modules
占很大内存。因此,我们在将项目提交到git时,应该忽略这个目录,当其他开发者同步代码之后,由对方自行安装,这也能避免由于操作系统差异导致的启动问题。
其他
npm
是开发nodejs
项目至关重要的工具,任何一位前端开发者都无法避免与其打交道。因此,熟悉其使用方式和常见的命令至关重要。