1 简介

npm(Node Package Manager)是Node.js生态系统中的默认包管理器,它提供了一系列的命令行工具,使得开发者能够方便地进行包的管理操作。这些操作包括但不限于下载、安装、升级、删除包,以及发布和维护自己的包。

以下是npm的一些主要功能:

  • 包管理:通过npm install命令安装项目所需的包,并将其添加到项目的依赖中,减少重复劳动。
  • 版本管理:指定项目依赖项的版本,确保项目不受不兼容版本的影响。
  • 脚本执行:在package.json文件中定义脚本,使用npm run命令执行。
  • 包发布和分享:开发者可以将自己编写的包发布到NPM的公共仓库中,供其他开发者使用。
  • 依赖解析:递归地解析和安装其依赖项,确保项目中的所有依赖都得到满足。
  • 包搜索和浏览:在NPM网站上搜索、浏览和发现其他人创建的包。

2 安装NPM

npm不需要单独的安装,在安装Node.js的时候会相应的安装npm。

  1. 前往Node.js官网下载并安装最新版本Node.js

image-20240425225114401

  1. 验证npm是否安装成功
1
2
npm -v    # 查看npm版本,若输出版本号,即为安装成功
# 10.5.1

3 基本使用

初次运行npm时,可以使用npm init命令进行初始化操作,它会引导填写一些基本信息(如版本号、描述等)

image-20240425230442939

初始化项目后创建package.json文件

package.json文件

package.json文件通常用来描述项目和软件包信息。

  • name:项目或库的名称
  • version:项目的版本
  • author:项目作者
  • description:项目的描述
  • license:项目的许可证

scripts

scripts字段用于定义项目中的各种脚本命令。可以在其中指定一些常用的操作,比如启动项目、执行测试、构建等,并且可以通过命令行工具来执行这些脚本。

例如,假设想在每次提交代码前运行测试,可以创建一个名为precommit的脚本:

1
2
3
4
5
6
{
"scripts": {
"prestart": "npm install",
"start": "node index.js"
}
}

在命令行使用npm run prestart等同于执行npm install

每个script都是一个命令行指令,后面跟着要执行的具体命令。当开发者克隆一个仓库并在自己的机器上运行npm installyarn安装依赖后,可以通过npm run <scriptName>yarn <scriptName>来执行这些预设的任务。这样的自动化大大提高了开发效率,减少了重复劳动,并且确保所有开发者和CI/CD流水线都能以相同的方式执行相同的步骤。

dependencies和devDependencies

dependencies和devDependencies是项目配置文件中的两个重要部分,它们用于分别列出项目运行时和开发时所需的外部模块或库。

  • dependencies:项目在实际运行时所依赖的模块或库。这些依赖项是在生产环境中必须安装和包含的包,因为它们包含了项目功能实现的核心代码或是该应用程序直接使用的库。当用户全局安装该应用程序或在系统上运行它时,npm会自动将这些依赖项下载并安装到node_modules目录中。
  • devDependencies:项目在开发过程中所需要的工具、测试框架、构建工具等,它们通常不参与项目的实际运行。这包括测试库、构建脚本、代码格式化工具等。当发布应用程序时这些依赖项不会被包含在内,但是其他开发者如果要在本地开发或测试代码,则需要安装这些依赖项。

在package.json中明确指定这些依赖项,可以确保任何人在新的环境中克隆和设置项目时都能够获得正确的版本,并且能够重现构建过程。这对于团队协作和持续集成/持续部署(CI/CD)流程至关重要。

4 常用命令

npm提供了许多有用的命令来帮助管理项目的依赖项和其他相关任务。下面是一些最常用的npm命令:

  1. npm init:初始化一个新的Node.js项目,创建一个package.json文件。
  2. npm install:安装所有依赖项以及未列出的新依赖项。
    • npm install:安装一个新依赖项到你的项目。
    • npm install --save:安装一个依赖项,并将其添加到dependencies中。
    • npm install --save-dev:安装一个开发依赖项,并将其添加到devDependencies中。
  3. npm uninstall:卸载一个依赖项。
  4. npm update:更新所有过期的依赖项到最新版本。
  5. npm outdated:列出所有过期的依赖项。
  6. npm ls:显示已安装的包及其版本信息。
  7. npm publish:发布你的包到npm仓库。

更多npm命令可参阅CLI 命令 | npm 中文网 (nodejs.cn)

5 全局安装与本地安装

在 npm 中,可以选择全局安装或本地安装包。这两种方式各有用途:

  • 全局安装 (npm install -g):全局安装的包对所有项目都可用。这意味着无论在哪里,都可以在命令行中访问这些包。这适用于那些不打算在单个项目中使用,而是希望在整个系统范围内使用的工具或命令行程序。例如,如果你经常需要使用某个代码格式化工具或构建脚本,全局安装可以让它在任何地方都可以使用。
  • 本地安装 (npm install):本地安装的包仅限于当前项目的node_modules目录。这意味着其他项目不能访问这些包,除非也为它们安装了同样的依赖项。这适用于那些项目直接依赖的库或工具。例如,如果你的项目需要一个特定版本的jQuery,你应该本地安装它,因为它只对你当前的项目有用。

image-20240428000553721

一般来说,建议尽可能使用本地安装,因为它允许精确控制每个项目的依赖关系,并且避免不同项目之间的冲突。全局安装主要用于那些你需要在多个项目间共享的工具或命令行实用程序。

6 版本管理和兼容性策略

npm版本管理和兼容性策略是确保项目顺利运行的关键部分。以下是一些建议:

  1. 使用语义化版本控制:遵循语义化版本控制规则,即主版本号.次版本号.修订号。当发布新功能时,增加次版本号;当修复 bug 时,增加修订号;当做出破坏性更改时,增加主版本号。这有助于开发者了解他们是否需要升级他们的代码以适应新版本。
  2. 锁定文件:使用package-lock.json或yarn.lock文件来锁定依赖项的具体版本。这可以防止因不同版本而导致的问题,并确保在不同环境中具有相同的一致性和可预测性。
  3. 定期更新:定期运行npm update来更新依赖项到最新版本,以利用最新的改进和安全修复。但请小心重大更新,因为它们可能会引入不兼容的变化。
  4. 依赖项兼容性:当添加新依赖项时,尽量选择广泛支持和积极维护的包。
  5. 测试:在更新依赖项之前,最好在一个隔离的环境中测试它们,比如使用Docker或虚拟机,以确保它们不会破坏现有的功能。
  6. 回退计划:如果更新导致问题,确保有一个回退计划。这可能意味着保留旧版本的代码或依赖项,直到问题解决。
  7. 监控:监控项目以识别潜在的安全漏洞和性能问题。有许多工具和服务可以帮助做到这一点,包括Snyk、Greenkeeper等。
  8. 文档:及时更新README.md或其他文档,说明项目依赖哪些版本的包,以及如何安装和配置它们。

通过遵循这些实践,可以最大限度地减少因依赖项更新而引起的问题,并确保项目稳定可靠。

package-lock.json文件:

package-lock.json文件是npm在执行npm install命令后自动生成的一个锁文件,其目的是确保在不同环境下能够一致地安装相同版本的依赖项。这个文件描述了项目所需的每个依赖的确切版本号以及解析后的实际下载地址。

7 案例分析:创建一个简单的npm模块并发布

  1. 确定模块名称

在GitHub或其他代码托管服务上检查模块名称是否可用,确保该名称没有被其他npm包占用。

  1. 初始化模块

在开发目录中创建一个新的文件夹作为模块项目,在该文件夹内运行npm init命令初始化package.json文件,它会引导填写一些基本信息(如版本号、描述等),或者使用npm init -y命令快速初始化。

image-20240427230309324

  1. 编写代码

在项目目录中创建一个JavaScript文件,通常命名为index.js,在其中编写模块代码,并且确保它能作为一个Node.js模块正确导出功能或类。

  1. 编辑package.json文件

添加必要的元数据,包括模块的名称、版本号、描述、作者、许可证等,如果需要,还可以添加 scripts 部分来自定义命令,例如启动脚本或测试脚本。

  1. 发布模块

第一次发布需要先注册一个npm账户

1
2
# 注册账户
npm adduser

image-20240428001100253

如果有npm账户则直接登录

1
2
# 登录账户
npm login

最后使用npm publish命令将模块发布到npm仓库

  1. 后期维护

对于每次更新,需要先递增版本号,然后再次运行npm publish来更新已发布的模块版本。

8 总结

总的来说,npm不仅是Node.js的核心组成部分,也是现代前端工程化的基石。掌握npm意味着掌握了JavaScript开发的未来趋势,它是每个前端工程师必备的基本功。随着Node.js及JavaScript技术的不断演进,相信npm将继续发挥其重要作用,引领着Web开发的新潮流。