npm 入门:包管理器、依赖与 npx

npm 入门:包管理器、依赖与 npx

一个项目不可能从零写起。今天聊 npm。

为什么需要 npm

代码写到一定阶段,会撞上一个现实:几乎没有哪个项目是从零写完的。

要发 HTTP 请求、要处理时间格式、要压缩图片------这些事早有人做过,而且做得比你好。合理的选择不是重写一遍,而是拿来用。

但"拿来"本身也有成本:去哪里找?用哪个版本?这个包又依赖了哪些别的包?换一台机器,怎么保证装出来是同一套?装到一半发现漏了一个包,怎么补?

npm(Node Package Manager,Node.js 包管理器) 就是解决这一串问题的工具,它是 Node.js 的官方包管理工具,负责三件事:

能力 说明
安装包 从远程仓库下载第三方代码库(如 express、lodash)到项目中
管理依赖 通过 package.json 记录项目需要的包及版本,确保环境一致
发布包 开发者可以把自己的代码打包发布到 npm 仓库,供他人使用

换个更快的理解方式:npm 就是 JavaScript 世界的应用商店。

需要一个"计算器"功能,不必自己写,去商店搜一个、一键安装;商店会记下你装过哪些 App(package.json 干的就是这件事);你写了一个好用的 App,也能传上去给别人下载。

这个思路并不新鲜------Java 世界有 Maven,Python 世界有 PyPI,说的都是同一件事。

核心机制

一、npm 站在 Node 的肩膀上

npm 的名字里带 Node 不是巧合:先有 Node,npm 才有用武之地。

前端页面靠三样东西撑着:

角色 语言 职责
骨骼 HTML 提供整体框架与内容承载
装修 CSS 控制颜色、大小、位置
逻辑 JavaScript 处理交互、从远端拉取数据

JavaScript 负责第三件事,但它有个先天限制:只能活在浏览器里。 它不能读写磁盘、不能连数据库、不能监听端口。这不是能力不足,而是刻意为之------浏览器里的脚本若能随意读你的硬盘,你存的其他东西也会被一并读走。

打个比方:JavaScript 像餐厅的前厅服务员,帮客人点菜、把菜名写进菜单、检查手机号格式,这些都能做;但服务员进不了厨房,也去不了仓库和收银台。

解除这个限制的,是谷歌 Chrome 里的 V8 引擎------一个用 C++ 写的 JavaScript 解析器,性能极强,而且被整个开源了。程序员 Ryan Dahl 由此想到:JavaScript 凭什么只能待在浏览器里?Python、Ruby、PHP 能做的事,它也该能做。

于是他带团队把 V8 从浏览器里拆出来,做成一套独立的运行时,命名为 Node.js(现在也常简称为 Node)。可以理解为给 JavaScript 配了一张"万能厨房通行证":操作文件、连接数据库、监听服务器端口,这些后端能力它都有了。

顺带一提,Node 官网(https://nodejs.org/en)上的版本不是随便选的。要留意每个版本的生命周期:一旦进入 EOL(End of Life,停止维护),就不再接收修复,安全漏洞可能被引入。选型时挑仍在维护的稳定版本,通常选最新的 LTS 或退一档的版本更稳妥。

二、npm 管的东西,落在哪里

npm 官网是 https://www.npmjs.com/,上面托管着超过 200 万个开源包(截至 2025 年),每周下载量以十亿计。

它的功能可以归成四条:安装卸载更新依赖包、管理项目的包信息、运行定义的脚本、发布自己的包。其中最需要分清的是安装位置:

命令 作用范围
npm install <pkg> 局部安装,装进当前项目
npm install -g <pkg> 全局安装,装到系统级目录,任何地方都能调用

判断标准很简单:这个包是项目要用 ,还是你要用。项目依赖走局部,命令行工具走全局。

至于"依赖"这个词,展开说一句:你写了一个 C 包,内部用了别人的 A 包和 B 包,那么 C 就依赖 A 和 B。当你把 C 发布出去,别人安装 C 的时候,A 和 B 会被一并装好------版本对应关系由 npm 处理,不需要使用者手动梳理。

三、npx:npm 负责"拥有",npx 负责"使用"

npx(Node Package Executor,包执行器) 从 npm 5.2.0 起被内置进 npm,装了较新的 Node 就自带。它允许直接运行 npm 仓库里的包,无需先用 npm install 把它永久装上。

一句话概括两者分工:npm 负责"拥有"包,npx 负责"使用"包。

维度 npm npx
定位 包管理器(管理依赖) 包执行器(运行命令)
主要操作 安装、卸载、更新、发布 执行命令、临时运行
是否需预先安装包 是,运行前必须先 npm install 否,可直接运行,临时下载
是否全局安装 装完后包长期存在于 node_modules 或全局目录 未全局安装
典型场景 长期依赖管理、项目初始化 临时命令、脚手架一次性创建

它查找命令的顺序是:当前项目的 node_modules/.bin/ → 全局安装 → 临时下载最新版。这个顺序解释了它为什么好用------先看你项目里有没有,再看全局有没有,都没有才去临时拉一个。

代码演示

一、装 Node,有两处必须改

从官网 https://nodejs.org/en 进入下载页,选对应系统的安装包,安装过程一路下一步即可。装完打开命令行验证:

bash 复制代码
node -v

能正常打印版本号,说明安装成功。npm 和 npx 是随 Node 一起来的,一并确认:

bash 复制代码
npm -v
npx -v

两者版本号一致(例如同为 11.11.0),因为它们本就是同一个 npm 的两副面孔。

第一处要改:镜像源。 npm 默认从国外的 registry.npmjs.org 取包,国内访问经常很慢。换成淘宝镜像源:

bash 复制代码
npm config get registry
npm config set registry https://registry.npmmirror.com
npm config get registry

第一步和第三步是同一个命令------先看改之前是什么,改完再确认一次,这是改配置的通用习惯。

这一步本质上只是把域名换掉 :registry.npmjs.org 与 registry.npmmirror.com 是两个不同的域名,各自解析到不同的服务器,请求自然会落到离你更近的那台上。

📖 参考:《计算机网络知识库》第五节

第二处要改:全局包的安装目录。 默认位置在 C 盘,全局包一多容易把系统盘撑满。先在别的盘建两个目录(例如 D:\lib\node_global 与 D:\lib\node_cache),再指过去:

bash 复制代码
npm config set prefix "D:\lib\node_global"
npm config set cache "D:\lib\node_cache"
npm config list

路径需要按自己的实际目录改。还有一步别漏:把 node_global 加进系统的 PATH 环境变量,否则全局装的命令行工具会提示"找不到命令"。

二、用 npm 装一个包

拿经典的 cowsay 练手最合适------功能极简单:让一头小牛在终端里说出你指定的话。

bash 复制代码
npm install -g cowsay

装完直接调用:

bash 复制代码
cowsay "Hello Bite"
text 复制代码
 ____________
< Hello Bite >
 ------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

这头牛是从哪来的?cowsay 本身是一个 npm 包,npm install -g 把它下载并安装到了你刚才配置的 node_global 目录下,再把可执行文件挂进 PATH,于是敲 cowsay 就能唤醒它。整个链条到此闭合。

三、用 npx 跑一个包,不装也行

同一个 cowsay,这次不安装,直接跑:

bash 复制代码
npx cowsay "Hello, 比特!"
text 复制代码
 ______________
< Hello, 比特! >
 --------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

包没装进任何地方,用的时候临时取来,用完即走。不常驻、不占目录,这就是 npx 存在的理由------一次性的工具,没必要为它做一次永久安装。

当然,如果这个包你每天都要用,还是老实 npm install -g,别每次让 npx 重新下载。

常见误区

把什么都装成全局的。 npm install -g 看着方便,但全局包不写进 package.json,别人拿到你的项目跑不起来。判断标准只有一条:项目依赖走局部,命令行工具才走全局。

不换镜像源就抱怨 npm 慢。 默认源在境外,慢是正常现象,改一行配置就能解决,不必反复重试。

在 Node 版本上随便选。 挑到已进入 EOL 的版本,等于放弃了后续的安全修复。选型前先查版本维护时间表。

以为 npx 是 npm 的替代品。 两者不是竞争关系:npm 管安装与依赖,npx 管执行,装 Node 时两个一起到齐。

配好了全局目录,却漏了 PATH。 自定义 prefix 之后不把该目录加进环境变量,全局工具会一直提示"找不到命令"------包装对了,是系统不知道去哪找。

本节要点

  • npm(Node Package Manager)是 Node.js 的官方包管理器,管三件事:安装包、管理依赖、发布包。
  • 它的能力建立在 Node 之上;Node 本身是把 V8 引擎从浏览器里拆出来做的独立 JavaScript 运行时。
  • 局部安装给项目,全局安装给命令行工具------判断标准是"项目要用"还是"你要用"。
  • npx(npm 5.2.0 起内置)负责"使用"包:不安装也能跑,适合一次性命令与脚手架。
  • 装完 Node 记得做两件事:换国内镜像源、改全局包目录并配好 PATH。

相关:MCP 入门:从 m×n 到 m+n------那篇里一带而过的 npx,本篇展开了

相关推荐
ShineWinsu1 小时前
对于JavaScript:初识JavaScript以及输入输出
java·开发语言·前端·javascript·css·面试·html
鲤鱼_5991 小时前
教培机构一体化运营管理系统操作手册
前端
鶴哥只手遮天2 小时前
React 19.3.1 源码深度剖析-第 3 章 Fiber 架构与双缓冲
前端·react.js·开源
鶴哥只手遮天2 小时前
React 19.3.1 源码深度剖析-第 9 章(下)lazy、retry、hydration 与实战
前端·react.js·开源
鶴哥只手遮天2 小时前
React 19.3.1 源码深度剖析-第 6 章 React DOM 渲染器与 Commit 阶段(把 Fiber 副作用落到真实 DOM)(上)
前端·react.js·开源
鶴哥只手遮天2 小时前
React 19.3.1 源码深度剖析-第 6 章 React DOM 渲染器与 Commit 阶段(把 Fiber 副作用落到真实 DOM)(下)
前端·react.js·开源
鶴哥只手遮天2 小时前
React 19.3.1 源码深度剖析-第 13 章:React 19 新特性深解
前端·react.js·开源
鶴哥只手遮天2 小时前
React 19.3.1 源码深度剖析-第 1 章 总览与架构哲学
前端·react.js·开源
鶴哥只手遮天2 小时前
React 19.3.1 源码深度剖析-第 4 章 Reconciliation 协调算法(Diff 算法全解)
前端·react.js·开源