深入理解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包中的类和接口实现,它主要用于以下目的: 在运行时分析类的能力:通过反射,可以在运行时检查类的结构,比如它的方法、构造…...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
