深入理解npm:从入门到精通

1. npm 简介
npm(Node Package Manager)是 Node.js 生态系统中的核心组件,它不仅是一个包管理器,还是一个强大的开发工具和庞大的开源社区。自2010年首次发布以来,npm 已经成为世界上最大的软件注册表,拥有超过100万个包,每周下载量超过数十亿次。
1.1 npm 的历史和发展
npm 由 Isaac Z. Schlueter 创建,最初是为了简化 Node.js 模块的安装过程。随着时间的推移,它逐渐发展成为一个全面的包管理解决方案,不仅支持 Node.js 项目,还支持前端 JavaScript 项目。
2020年,GitHub 收购了 npm,这标志着 npm 进入了新的发展阶段,有望获得更多资源支持和功能改进。
1.2 npm 的核心功能
- 包管理:安装、更新、卸载包
- 依赖解析:自动处理包之间的依赖关系
- 版本控制:遵循语义化版本规范
- 脚本运行:通过 package.json 定义和运行脚本
- 发布管理:允许开发者发布自己的包到 npm 仓库
2. npm 的安装与基本配置

2.1 安装 Node.js 和 npm
虽然 npm 通常随 Node.js 一起安装,但有时您可能需要单独更新 npm。以下是在不同操作系统上安装和更新 npm 的方法:
Windows
- 从 Node.js 官网 下载并安装 Node.js
- 打开命令提示符,运行
npm -v检查版本
macOS
- 使用 Homebrew 安装:
brew install node - 或者从 Node.js 官网下载安装包
Linux
使用包管理器安装,例如 Ubuntu:
sudo apt update
sudo apt install nodejs npm
2.2 更新 npm
无论您的操作系统是什么,都可以使用以下命令更新 npm:
npm install -g npm@latest
2.3 npm 配置
npm 的配置可以通过命令行、环境变量或 .npmrc 文件来设置。以下是一些常用的配置项:
-
设置默认的包安装位置:
npm config set prefix /path/to/directory -
设置代理(如果你在公司网络环境中):
npm config set proxy http://proxy.company.com:8080 npm config set https-proxy http://proxy.company.com:8080 -
设置私有仓库地址:
npm config set registry https://registry.your-company.com -
查看所有配置:
npm config list
3. npm 的基础用法
3.1 初始化项目
使用 npm init 命令可以交互式地创建 package.json 文件:
npm init
如果你想使用默认值快速创建,可以使用:
npm init -y
package.json 文件是项目的核心,它包含了项目的元数据和依赖信息。以下是一个典型的 package.json 文件示例:
{"name": "my-awesome-project","version": "1.0.0","description": "A project to demonstrate npm usage","main": "index.js","scripts": {"start": "node index.js","test": "jest"},"keywords": ["npm", "tutorial"],"author": "Your Name <your.email@example.com>","license": "MIT","dependencies": {"express": "^4.17.1"},"devDependencies": {"jest": "^26.6.3"}
}
3.2 安装依赖
在这里插入图片描述
npm 提供了多种安装依赖的方式,以满足不同的需求:
-
安装项目依赖:
npm install express这会将 express 添加到
dependencies中。 -
安装开发依赖:
npm install jest --save-dev这会将 jest 添加到
devDependencies中。 -
全局安装:
npm install -g nodemon这会将 nodemon 安装到全局,使其在命令行中可用。
-
安装特定版本:
npm install lodash@4.17.20 -
安装 git 仓库中的包:
npm install git+https://github.com/user/project.git
3.3 卸载依赖
卸载依赖的命令与安装类似:
npm uninstall express
npm uninstall jest --save-dev
npm uninstall -g nodemon
3.4 更新依赖
-
检查可更新的包:
npm outdated -
更新所有包到最新版本:
npm update -
更新特定包:
npm update lodash -
更新到最新主版本(可能包含破坏性更改):
npm install lodash@latest
4. npm 的高级用法
4.1 npm 脚本
npm 脚本是 package.json 文件中 scripts 字段定义的命令。它们可以用来自动化各种任务,如构建、测试、部署等。
"scripts": {"start": "node server.js","dev": "nodemon server.js","test": "jest","build": "webpack","lint": "eslint .","prepublish": "npm test && npm run build"
}
运行这些脚本的方式是:
npm run <script-name>
例如:npm run dev
一些特殊的脚本名称(如 start, test)可以直接运行,无需 run:
npm start
npm test
4.2 版本控制
npm 使用语义化版本控制(SemVer)来管理包版本。版本号格式为:MAJOR.MINOR.PATCH
- MAJOR:做了不兼容的 API 修改
- MINOR:新增了向下兼容的功能
- PATCH:向下兼容的 bug 修复
在 package.json 中,你可以使用以下符号来指定版本范围:
^: 允许次版本和修订版本更新(^1.2.3 将匹配所有 1.x.x 版本,但不包括 2.0.0)~: 只允许修订版本更新(~1.2.3 将匹配所有 1.2.x 版本,但不包括 1.3.0)*: 允许所有更新>,>=,<,<=: 版本比较1.2.3 - 2.3.4: 版本范围||: 组合多个版本范围
例如:
"dependencies": {"express": "^4.17.1","lodash": "~4.17.20","react": ">=16.8.0 <17.0.0"
}
4.3 npm 的作用域和私有包
npm 的作用域(scope)允许你将相关的包组织在一起,并且可以用来创建私有包。
-
使用作用域包:
npm install @myorg/mypackage -
创建作用域包:
在package.json中设置 name 字段:{"name": "@myorg/mypackage" } -
发布私有包:
首先需要注册一个组织或付费账户,然后:npm publish --access restricted -
设置私有仓库:
在.npmrc文件中添加:@myorg:registry=https://npm.your-company.com
5. npm 最佳实践
5.1 使用 package-lock.json
package-lock.json 文件是在 npm 5 中引入的,它的目的是锁定依赖的具体版本和依赖树结构,确保在不同环境中安装相同的依赖版本。
- 始终将
package-lock.json提交到版本控制系统 - 使用
npm ci而不是npm install在 CI/CD 环境中安装依赖
5.2 使用 .npmrc 文件
.npmrc 文件可以用来配置 npm 的行为。你可以在项目根目录创建这个文件,或者在用户主目录创建全局配置。
示例 .npmrc 文件:
save-exact=true
package-lock=false
registry=https://registry.npm.taobao.org
5.3 依赖管理策略
-
经常更新依赖:
npm update -
使用
npm outdated检查过时的包 -
使用
npm audit检查安全漏洞 -
考虑使用
npm-check-updates工具来管理大版本更新
5.4 发布包的最佳实践
- 使用语义化版本控制
- 编写清晰的文档和 README
- 包含测试和示例
- 使用
.npmignore文件排除不必要的文件 - 在发布前使用
npm pack检查包内容
6. npm 安全性考虑
6.1 使用 npm audit
npm audit 是一个内置的安全工具,可以扫描你的项目依赖中的已知漏洞:
npm audit
如果发现漏洞,可以使用以下命令修复:
npm audit fix
6.2 使用 Snyk
Snyk 是一个第三方工具,提供更全面的安全检查:
-
安装 Snyk:
npm install -g snyk -
认证:
snyk auth -
测试项目:
snyk test
6.3 包完整性
npm 使用 SHA512 哈希来验证下载的包的完整性。从 npm 5 开始,这个过程是自动的。
6.4 避免使用 npm install -g
全局安装包可能会导致版本冲突和安全问题。尽可能将依赖安装为本地依赖,并使用 npm scripts 或 npx 来运行它们。
7. npm 与其他工具的集成
7.1 Webpack

Webpack 是一个流行的模块打包工具,可以与 npm 无缝集成:
-
安装 Webpack:
npm install webpack webpack-cli --save-dev -
在
package.json中添加构建脚本:"scripts": {"build": "webpack" }
7.2 Babel

Babel 是一个 JavaScript 编译器,允许你使用最新的 JavaScript 特性:
-
安装 Babel:
npm install @babel/core @babel/cli @babel/preset-env --save-dev -
创建
.babelrc文件:{"presets": ["@babel/preset-env"] } -
在
package.json中添加编译脚本:"scripts": {"build": "babel src -d lib" }
7.3 ESLint

ESLint 是一个流行的 JavaScript 代码质量工具:
-
安装 ESLint:
npm install eslint --save-dev -
初始化 ESLint 配置:
npx eslint --init -
在
package.json中添加 lint 脚本:"scripts": {"lint": "eslint ." }
7.4 Jest

Jest 是一个流行的 JavaScript 测试框架:
-
安装 Jest:
npm install jest --save-dev -
在
package.json中添加测试脚本:"scripts": {"test": "jest" } -
创建测试文件(如
myFunction.test.js)并开始编写测试
8. npm 的替代品和补充工具
8.1 Yarn

Yarn 是由 Facebook 开发的另一个包管理器,提供了一些 npm 没有的特性:
-
安装 Yarn:
npm install -g yarn -
使用 Yarn 安装依赖:
yarn add express
想要学习更多请看我的这篇文章:一篇文章搞懂Yarn
8.2 pnpm

pnpm 是一个快速、节省磁盘空间的包管理器:
-
安装 pnpm:
npm install -g pnpm -
使用 pnpm 安装依赖:
pnpm install express
pnpm 的主要优势在于它使用硬链接和符号链接来共享包,大大减少了磁盘空间的使用,并提高了安装速度。
8.3 npx
npx 是 npm 5.2+ 版本中自带的包运行工具,它允许你运行包而不需要全局安装:
npx create-react-app my-app
这个命令会临时安装 create-react-app,用它创建一个新的 React 应用,然后删除它,不会在全局环境中留下任何痕迹。
8.4 nvm (Node Version Manager)
nvm 是一个 Node.js 版本管理工具,允许你在同一台机器上安装和切换不同版本的 Node.js:
-
安装 nvm(在 Unix 系统上):
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash -
安装特定版本的 Node.js:
nvm install 14.17.0 -
切换 Node.js 版本:
nvm use 14.17.0
9. npm 高级主题
9.1 创建和发布自己的 npm 包
-
创建包目录和初始化:
mkdir my-awesome-package cd my-awesome-package npm init -
编写包的主要代码(例如
index.js) -
编写测试(使用 Jest 或其他测试框架)
-
更新
package.json,确保包含正确的入口点、版本等信息 -
创建 README.md 文件,描述包的用途和使用方法
-
发布包:
npm publish
注意:首次发布需要在 npm 网站上注册账号,并在命令行中登录:
npm adduser
9.2 npm 钩子
npm 提供了许多生命周期钩子,允许你在包安装、测试、发布等过程中执行自定义脚本:
preinstall: 安装前运行postinstall: 安装后运行preuninstall: 卸载前运行postuninstall: 卸载后运行preversion: 改变包版本前运行version: 改变包版本后运行postversion:npm version完成后运行pretest,test,posttest: 运行测试时prepublish,prepare,prepublishOnly,publish,postpublish: 发布包时
例如,在 package.json 中:
"scripts": {"prepublish": "npm test","postinstall": "node scripts/postinstall.js"
}
9.3 npm 和 monorepos
Monorepo 是一种将多个相关项目存储在单个存储库中的开发策略。npm 提供了一些工具来管理 monorepos:
-
Lerna:一个优化 monorepos 工作流的工具
npx lerna init -
Workspaces:npm 7+ 原生支持的 monorepo 解决方案
在根package.json中:{"workspaces": ["packages/*"] }
9.4 npm 缓存
npm 会缓存下载的包,以提高后续安装的速度:
-
查看缓存:
npm cache ls -
清理缓存:
npm cache clean --force -
验证缓存:
npm cache verify
9.5 npm 和 CI/CD
在持续集成/持续部署(CI/CD)环境中使用 npm:
-
使用
npm ci而不是npm install,它会严格按照package-lock.json安装依赖 -
缓存
node_modules目录以加速构建 -
在 CI 配置中设置
NPM_TOKEN环境变量,用于访问私有包 -
使用
npm version和npm publish自动化版本管理和发布
10. npm 性能优化
10.1 并行安装
从 npm 5+ 开始,npm 默认并行安装依赖。你可以通过设置 --maxsockets 来控制并发数:
npm install --maxsockets 5
10.2 使用 fast-npm
fast-npm 是一个 npm 的替代 CLI,它可以显著提高安装速度:
npm install -g fast-npm
fast-npm install
10.3 使用本地缓存
如果你经常在相同的项目上工作,可以考虑使用本地缓存来加速安装:
npm config set cache-min 9999999
这会让 npm 缓存包 9999999 分钟(约 6.9 天)。
10.4 使用 npm ci 在 CI 环境中
npm ci 命令专为 CI 环境设计,它比 npm install 更快,因为它跳过了某些用户体验相关的功能。
11. npm 故障排除
11.1 常见错误
EACCES错误:权限问题,可以通过修改 npm 默认目录的权限或使用 nvm 来解决ENOENT错误:通常是因为文件或目录不存在,检查路径是否正确ETIMEDOUT错误:网络超时,可能需要检查网络连接或使用镜像
11.2 调试技巧
- 使用
npm install --verbose查看详细的安装日志 - 检查
npm-debug.log文件以获取错误详情 - 使用
npm config list查看当前的 npm 配置
11.3 常见问题解决方案
- 依赖冲突:使用
npm dedupe命令来解决 - 全局安装问题:检查
PATH环境变量是否正确设置 - 版本不兼容:检查
package.json中的版本范围,必要时手动更新
12. npm 的未来发展
随着 JavaScript 生态系统的不断发展,npm 也在持续进化。以下是一些可能的未来发展方向:
- 更好的单体仓库(monorepo)支持
- 改进的依赖解析算法,以更好地处理复杂的依赖关系
- 更强大的安全特性,如更精细的权限控制
- 与云服务的进一步集成,简化部署流程
- 更好的性能,特别是在大型项目中
结语
npm 已经成为 JavaScript 开发不可或缺的工具。通过本文,我们深入探讨了 npm 的方方面面,从基础用法到高级特性,从最佳实践到性能优化。掌握 npm,不仅能够提高你的开发效率,还能帮助你更好地理解和参与 JavaScript 生态系统。
记住,npm 生态系统是不断发展的,保持学习和实践的习惯,关注官方博客和文档,参与社区讨论,这样你就能始终保持在 npm 使用的最前沿。希望这篇文章能够帮助同学们更好地理解和使用 npm,祝你们在 JavaScript 开发的道路上取得更大的成功!
相关文章:
深入理解npm:从入门到精通
1. npm 简介 npm(Node Package Manager)是 Node.js 生态系统中的核心组件,它不仅是一个包管理器,还是一个强大的开发工具和庞大的开源社区。自2010年首次发布以来,npm 已经成为世界上最大的软件注册表,拥有…...
Docker入门教程:10分钟掌握基础
Docker入门教程:10分钟掌握基础 1. Docker是什么? Docker是一种容器化技术,它允许开发者打包他们的应用以及应用的依赖环境到一个可移植的容器中,这个容器可以在任何支持Docker的操作系统上运行。 2. Docker的基本组成 镜像&a…...
NLP实验-基于预训练模型的文本分类
使用BERT及其变体实现AclImdb情感分类 前言数据集介绍【Hugging Face】使用方法和如何挑选一个自己需要的模型 基于BERT预训练模型的本文分类数据预处理载入文本标记器将数据转化为模型可以接受的格式训练模型加载模型 基于RoBerta预训练模型的文本分类基于DeBerta预训练模型的…...
Table API SQL的概念和通用API
目录 表API和SQL程序的结构 创建表环境(Create a TableEnvironment) 在目录中创建表(Create Tables in the Catalog) 临时表与永久表(Temporary vs Permanent tables) 遮蔽(Shadowing) 创建表(Create a Table) 连接器表(Connector Tables) 虚拟表(Virtual…...
【网络】UDP和TCP之间的差别和回显服务器
文章目录 UDP 和 TCP 之间的差别有连接/无连接可靠传输/不可靠传输面向字节流/面向数据报全双工/半双工 UDP/TCP API 的使用UDP APIDatagramSocket构造方法方法 DatagramPacket构造方法方法 回显服务器(Echo Server)1. 接收请求2. 根据请求计算响应3. 将…...
Electron:摄像头录制和屏幕录制
摄像头录制 main.js const { app, BrowserWindow} require(electron)let mainWin null const createWindow () > {mainWin new BrowserWindow({width: 800,height: 600,title: 自定义菜单,webPreferences: {// 允许渲染进程使用nodejsnodeIntegration: true,// 允许渲…...
【uniapp】vue3+vite配置tailwindcss
安装 npm install autoprefixer tailwindcss uni-helper/vite-plugin-uni-tailwind -Dautoprefixer :自动管理浏览器前缀的插件,可以解析css文件并且添加前缀到css内容里。uni-helper/vite-plugin-uni-tailwind: 将 Tailwind CSS 框架集成到使用 Vite 作…...
从源码到应用:医疗陪诊系统与在线问诊小程序开发详解
在数字化医疗时代,医疗陪诊系统与在线问诊小程序的开发成为了医疗机构和技术公司关注的焦点。接下来,小编将与您一同深入了解。 一、医疗陪诊系统的核心功能 医疗陪诊系统旨在为患者提供更贴心的医疗服务,通过专业人员陪同患者完成就医过程。…...
mysql数据库中decimal数据类型比较大小
在MySQL中,DECIMAL数据类型用于存储精确的数值,它非常适合用于需要高精度计算的场景,如金融应用。当我们需要在MySQL数据库中比较DECIMAL类型数据的大小时,可以使用标准的比较运算符,如>, <, >, <, 和 &l…...
掌控库存,简化管理 — InvenTree 开源库存管理系统
InvenTree :简化您的库存管理,让效率和控制力触手可及。- 精选真开源,释放新价值。 概览 InvenTree,一款专为精细化库存管理而设计的开源系统,以其高效和灵活性在众多库存管理工具中脱颖而出。它以Python和Django框架…...
Linux---项目自动化构建工具-make/Makefile
一、背景 会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的 规则来指定,哪些文件需要先编译,哪些文件…...
嘉立创EDA个人学习笔记1(PCB板介绍)
前言 本篇文章属于嘉立创EDA的学习笔记,来源于B站教学视频。下面是这位up主的视频链接。本文为个人学习笔记,只能做参考,细节方面建议观看视频,肯定受益匪浅。 嘉立创EDA-PCB设计零基础入门课程(54集全)_…...
(转)Restful接口设计(1)
.representational:代表性的 URI(Universal Resouce Identifier):Universal :普遍的;共同的。Identifier:标识符。统一资源标识符。 31-RESTful接口介绍-02_哔哩哔哩_bilibili 31-RESTful接口介绍-03_哔哩…...
Python进阶之3D图形
Python进阶之3D图形 在数据可视化中,2D图形通常可以满足大多数需求。然而,对于一些复杂的数据或分析,3D图形可以提供更多的视角和洞察。在Python中,使用 Matplotlib 和 Plotly 等库可以轻松创建各种3D图形。本文将介绍如何使用这…...
机器学习深度学习中的搜索算法浅谈
机器学习&深度学习中的搜索算法浅谈 搜索算法是计算机科学中的核心算法,用于在各种数据结构(如数组、列表、树、图等)中查找特定元素或信息。这些算法不仅在理论上具有重要意义,还在实际应用中扮演着关键角色。本文将详细探讨…...
基于IMX8M_plus+FPGA+AI监护仪解决方案
监护仪是一种以测量和控制病人生理参数,并可与已知设定值进行比较,如果出现超标可发出警报的装置或系统。 (1)监护仪主要采集测量人体生理参数,心电、血压、血氧、体温等需要采集处理大量的数据,系统需要多…...
仿RabbitMq实现简易消息队列正式篇(路由匹配篇)
TOC 目录 路由匹配模块 代码展示 路由匹配模块 决定了一条消息是否能够发布到指定的队列 在每个队列根交换机的绑定信息中,都有一个binding_key(在虚拟机篇有说到)这是队列发布的匹配规则 在每条要发布的消息中,都有一个rout…...
一套完整的NVR网络硬盘录像机解决方案和NVR程序源码介绍
随着网络技术的发展,视频数据存储的需求激增,促使硬盘录像机(DVR)逐渐演变为具备网络功能的网络视频录像机(NVR)。NVR,即网络视频录像机,负责网络视音频信号的接入、存储、转发、解码…...
2024年人工智能固态硬盘采购容量预计超过45 EB
根据TrendForce发布的最新市场报告,人工智能(AI)服务器客户在过去两个季度显著增加了对企业级固态硬盘(SSD)的订单。为了满足AI应用中不断增长的SSD需求,上游供应商正在加速工艺升级,并计划在20…...
Java的反射原理
反射允许程序在运行时检查或修改其类、接口、字段和方法的行为。反射主要通过java.lang.reflect包中的类和接口实现,它主要用于以下目的: 在运行时分析类的能力:通过反射,可以在运行时检查类的结构,比如它的方法、构造…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...
AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机
这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...
【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...
Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...
LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》
🧠 LangChain 中 TextSplitter 的使用详解:从基础到进阶(附代码) 一、前言 在处理大规模文本数据时,特别是在构建知识库或进行大模型训练与推理时,文本切分(Text Splitting) 是一个…...
一些实用的chrome扩展0x01
简介 浏览器扩展程序有助于自动化任务、查找隐藏的漏洞、隐藏自身痕迹。以下列出了一些必备扩展程序,无论是测试应用程序、搜寻漏洞还是收集情报,它们都能提升工作流程。 FoxyProxy 代理管理工具,此扩展简化了使用代理(如 Burp…...
