为什么需要包管理工具
想象一下没有包管理工具的场景,你需要:
-
手动查找库: 你需要知道某个功能(比如处理日期、发送网络请求、操作数据库)可能已经有现成的库了,然后去网上搜索找到这个库的主页或代码仓库。
-
手动下载库: 找到库之后,你需要手动下载它的代码文件(可能是 .zip 包、.js 文件、.jar 文件等)。
-
手动放置库文件: 你需要决定把下载的代码放在项目的哪个目录下,并确保你的主代码能够正确地引用到它。
-
处理库的依赖: 这是最痛苦的部分! 你下载的库 A 可能又依赖于库 B 和库 C。于是你又得重复步骤 1-3 去找、下载、放置库 B 和库 C。而库 B 可能又依赖于库 D... 这形成了一个复杂的依赖树,手动追踪和管理极其困难,很容易遗漏或版本错误,这就是所谓的**"依赖地狱" (Dependency Hell)**。
-
版本管理困难:
- 你怎么知道你下载的是哪个版本?
- 如果库发布了新版本(修复了 Bug 或增加了新功能),你需要重复整个过程去更新。
- 如果你的项目依赖了库 A 和库 B,而库 A 需要库 C 的 1.0 版本,库 B 却需要库 C 的 2.0 版本,怎么办?手动解决版本冲突非常棘手。
-
项目共享困难: 当你把项目代码分享给同事或者部署到服务器时,如何确保他们也安装了所有正确版本的依赖库?你可能需要手动列一个清单,或者把所有依赖库连同你的代码一起打包(导致仓库体积巨大),而且这个过程非常容易出错。
-
难以发现和复用: 没有统一的地方查找和管理,社区的优秀代码很难被发现和方便地复用。
-
卸载麻烦: 如果不再需要某个库,手动移除它以及它引入的但不再被其他库需要的依赖,也很困难。
包管理工具就是为了解决以上所有这些问题而生的。它们的核心价值在于:
- 自动化依赖解析和下载: 你只需要在配置文件(如 package.json, requirements.txt, pom.xml)中声明你的直接依赖,包管理工具会自动分析整个依赖树,下载所有必需的包(包括间接依赖)。
- 规范化的版本管理: 使用语义化版本(SemVer)等规范,允许你指定依赖的版本范围(如 ">=1.0 <2.0" 或 "^1.2.3"),包管理工具会根据规则选择合适的版本,并帮助解决版本冲突(或至少报告冲突)。
- 确保环境一致性: 通过锁定文件(如 package-lock.json, yarn.lock, Pipfile.lock),可以精确记录下项目中每个依赖(包括子依赖)的确切版本 。这样,任何人在任何机器上使用相同的锁定文件执行安装命令,都能得到完全一致的依赖环境,极大地提高了可重复性 和可靠性,避免了"在我机器上能跑"的问题。
- 简化项目共享和部署: 你只需要共享你的源代码和那个小小的配置文件(以及锁定文件),其他人或部署系统只需运行一条安装命令(如 npm install, pip install -r requirements.txt),就能自动搭建起完全相同的依赖环境。
- 提供中央仓库/生态系统: 像 npmjs.com, PyPI, Maven Central 这样的中央仓库,方便开发者发布、搜索和发现可复用的包,极大地促进了代码共享和生态繁荣。
- 简化更新和卸载: 提供简单的命令(如 npm update, pip uninstall)来更新或移除依赖。
- 任务运行器(附加功能): 很多包管理器(如 npm, Yarn)还集成了运行自定义脚本的功能(如运行测试、启动服务、构建项目),进一步简化了开发流程。
代码共享方案
我们不是有GitHub吗
缺点:
-
使用的程序员必须知道你代码的GitHub的地址,并且从GitHub上手动下载
-
需要在自己的项目中手动的引入。自己还有下载和管理相关的依赖
-
不需要的时候,需要手动的删除相关的依赖
-
当遇到版本升级(大的或小的更新)。要重复上面的操作
所以有了一个更专业的工具管理我们的代码
-
通过工具将代码发布到特定的位置
-
其他的程序员直接通过工具来进行安装,升级,删除我们的工具代码
包管理工具NPM
Node Package Manager, 也叫Node包管理工具
npm(Node Package Manager)是 Node.js 默认的、也是世界上最大的软件包管理器。它主要由两部分组成:
- 命令行客户端 (CLI - Command Line Interface): 就是你在终端或命令行中输入的 npm 命令。这个工具负责安装、更新、卸载、发布包,以及管理项目的依赖和运行脚本等。
- 在线仓库 (Registry): 一个庞大的公共数据库(官方地址是 npmjs.com),托管着成千上万的开源 JavaScript 软件包(也称为模块或库)。开发者可以将自己的包发布到这里,也可以搜索并下载别人共享的包。
认识npm
npm 的核心功能:
-
依赖管理 (Dependency Management):
- 安装包: 使用 npm install <package_name> (或简写 npm i <package_name>) 从 npm仓库下载包并将其添加到你的项目中。
- 记录依赖: 项目的依赖关系(需要哪些包以及它们的版本范围)记录在项目根目录下的 package.json 文件中。
- 自动处理依赖的依赖: 当你安装一个包时,npm 会自动下载并安装该包所依赖的其他包(所谓的"传递性依赖")。
- 版本控制: npm 使用语义化版本(Semantic Versioning, SemVer)来管理包的版本,允许你指定依赖的版本范围(例如,^1.2.3 表示接受 1.2.3 及以上,但低于 2.0.0 的版本)。
- 确保一致性: package-lock.json 文件(或 yarn.lock / pnpm-lock.yaml)会锁定项目中所有依赖(包括传递性依赖)的确切版本,确保团队成员和不同环境(开发、测试、生产)安装的依赖版本完全一致,避免"在我机器上能跑"的问题。
- 更新包: npm update 可以根据 package.json 中指定的版本范围更新依赖到较新版本。
- 卸载包: npm uninstall <package_name> 用于移除项目中的某个包。
-
运行脚本 (Script Execution):
-
package.json 文件中的 scripts 字段允许你定义一些自定义的命令行脚本快捷方式。
-
你可以使用 npm run <script_name> 来执行这些脚本。
-
常见的预定义脚本包括 npm start, npm test, npm stop, npm restart(这些可以省略 run 直接执行)。
-
这常用于启动开发服务器、运行测试、构建项目、代码检查等任务。
js// package.json { "scripts": { "start": "node server.js", "dev": "nodemon server.js", "build": "webpack --config webpack.config.js", "test": "jest" } }
执行 npm run dev 就会运行 nodemon server.js 命令。
-
-
包发布 (Package Publishing):
- 如果你编写了自己的 JavaScript 库或工具,可以通过 npm publish 命令将其发布到 npm 仓库,供全世界的开发者使用。
- 需要先在 npmjs.com 注册账号,并使用 npm login 登录。
-
项目初始化 (Project Initialization):
- npm init 或 npm init -y (快速使用默认配置) 命令可以在项目根目录下创建一个 package.json 文件,用于记录项目信息和依赖。
关键文件和目录:
-
package.json: 项目的清单文件。包含了项目的元数据(名称、版本、描述、作者、许可证等)、依赖列表(dependencies 和 devDependencies)、可执行脚本(scripts)等。这是 npm 工作的基础。
- dependencies: 生产环境运行所必需的包。
- devDependencies: 只在开发环境需要的包(如测试框架、构建工具、代码检查器)。使用 npm install <package_name> --save-dev 或 -D 安装。
-
package-lock.json: 非常重要! 这个文件自动生成(或更新),精确记录了当前项目中安装的所有包(包括子依赖)的确切版本号 以及它们的依赖树结构。应该将此文件提交到版本控制系统(如 Git) ,以保证所有开发者和部署环境安装的依赖版本完全一致,实现可重复构建 (Reproducible Builds) 。
-
node_modules/: 这个目录存放着所有通过 npm 安装的包的实际代码 。它的内容是根据 package.json 和 package-lock.json 安装生成的。通常不应该将此目录提交到版本控制系统,因为它体积庞大且可以根据 package.json 和 package-lock.json 重新生成(通过 npm install 命令)。通常会把它添加到 .gitignore 文件中。
如何下载和使用npm工具
-
npm属于node的管理工具,当我们在安装node的时候。已经自动帮我们下载了
-
npm的包可以在官网查看,里面可以查找已经收录的包
npm中的基本使用命令
常用 npm 命令:
-
npm init
[-y]
: 初始化项目,创建 package.json。 -
npm install / npm i
: 安装 package.json 中定义的所有依赖。 -
npm install <package_name>
: 安装指定的包并添加到 dependencies。 -
npm install <package_name> --save-dev / npm i <package_name> -D
: 安装指定的包并添加到 devDependencies。 -
npm install <package_name> -g
: 全局安装包(通常用于命令行工具,如 create-react-app, nodemon, http-server)。(注意:全局安装和项目依赖是分开的)。 -
npm update
: 根据 package.json 中的版本范围更新包。 -
npm update <package_name>
: 更新指定的包。 -
npm uninstall <package_name> / npm un <package_name>
: 卸载包并从 package.json 和 package-lock.json 中移除。 -
npm run <script_name>
: 执行在 package.json 的 scripts 中定义的脚本。 -
npm list
: 列出当前项目安装的包。 -
npm list -g
: 列出全局安装的包。 -
npm outdated
: 检查哪些包有可用的更新。 -
npm view <package_name> versions
: 查看某个包的所有可用版本。 -
npm search
<keyword>
: 在 npm 仓库中搜索包含关键字的包。 -
npm login
: 登录 npm 账号(用于发布包)。 -
npm publish
: 发布你的包到 npm 仓库。 -
npx <command>
: (npm 自带的工具) 运行 npm 包中的可执行文件,而无需全局安装。例如 npx create-react-app my-app。
基本案例
npm init -y
和npm i dayjs

- 创建main的js文件
js
//项目中下载了dayjs的包, 可以直接引用
const dayjs = require('dayjs')
console.log(dayjs())
