news 2026/9/30 2:36:02

npm命令解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
npm命令解析

npm i -D unplugin-auto-import

npm i:npm install的简写,用于安装依赖包
-D:--save-dev的简写,装到开发依赖(devDependencies)
unplugin-auto-import: 包名,就是 Vite 里那个自动导入插件

为什么用-D而不是直接npm i?
因为这类插件只在开发 / 构建阶段起作用,跑起来的网页本身不依赖它。所以放 devDependencies。
部署生产环境执行npm install --production时,会跳过安装这个包,缩减部署包大小。 像 Vue、Element Plus 这种页面实际运行时要加载的库,才放在dependencies生产依赖里。

npm install --production: 安装依赖时,跳过devDependencies(开发依赖),只安装dependencies(生产依赖)

package.json里的分工:

"dependencies":{// 运行时需要"vue":"^3.5.40","element-plus":"^2.14.3"},"devDependencies":{// 只在开发/构建时用"unplugin-auto-import":"^21.1.0","unplugin-vue-components":"^32.1.0","vite":"^8.1.5"}

装 “构建工具” 用-D,装 “运行时库” 不用-D

详细步骤

npm i -D unplugin-auto-import 执行时:

1. 读本地(只加载,不判定)
读 package.json(已有依赖)、lock(虚拟树)、node_modules(实际树)

2. 构建理想树
└─先根据package.json建立理想树
├─ 已有边:查 lock 候选 → 满足 → 照抄 lock 版本;不满足/没有 → 问 registry 取范围内最高版
├─ 新边 unplugin-auto-import:lock 里没有 → 问 registry → latest = 21.1.0 → 挂入树
├─ 递归它的 dependencies(unimport、unplugin…):每条边同上判定
└─没有 lock 时:以 node_modules 为起点建树,并进行后续的校验

理想树的边就是依赖

3. diff: 获取操作清单
对比理想树和实际树(node_modules),给出 “该装什么、该删什么、该换什么” 的完整操作清单

关于node_modules的校验:即使在建树阶段校验过了,这里还要校验了,因为建树阶段的校验是为了知道"这条边用什么版本",而diff的校验是为了获得操作清单

4. 实际化(reify):按树下载
照着diff给出的清单执行 → 下载解压、删除孤儿、替换版本

下载好的依赖解压进node_modules
即使我运行npm i <包名>的目的只是想要安装<包名>,npm依旧按照清单下载解压所有的包

5. 保存(全部成功后才写)
先写 package.json(save-prefix(^) + 21.1.0 → “^21.1.0”)→ 最后写 lock(21.1.0 + 整棵树)

关于理想树

理想树是我们想要得到的依赖结构,他是加载到内存中的数据结构。

命令运行结束后,理想树会写进package-lock.json。

我们通常把package-lock.json(及其对应的内存树结构)称为虚拟树,把磁盘上真实存在的node_modules目录结构称为实际树。

构建理想树时以package-lock.json为基础,一方面是因为它锁定了历史版本,能保证跨环境构建结果一致;另一方面是直接复用上次的解析结果,可以大幅提升安装速度。

关于npm install

  1. npm i <包名>(不带版本)= 默认要 latest 标签。
    此时如果这个包已经存在于 lock 文件中,会优先参考 lock 里的版本,只有当 lock 版本不满足 package.json 范围时才去 registry 拉最新
    问registry要 latest,包manifest里有dist-tags: { latest: "21.1.0" }

    registry是 npm 的 “中央仓库服务器”,存放着所有公开 npm 包的地方。
    官方地址:https://registry.npmjs.org
    使用命令行npm config ls -l可以查看本机的具体配置
    manifest是你要装的那个包(unplugin-auto-import)在 registry 上的 “登记档案”

  2. 如果直接执行npm install,会把package.json和package-lock.json里面的依赖全部装齐

    package.json里面是范围,lock 里面是具体版本
    如果package里面有而lock里面没有,下载package范围内的最高版本
    如果package里面有且lock里面也有,下载lock的版本
    如果package里面没有但lock里面有,
    如果这个依赖是某个已声明依赖的传递依赖,保留,如果不是,则清除
    (传递依赖会随着主依赖的下载而顺带着下载)

  3. npm i <包名>@<版本>(指定版本),如果 lock中已经存在该版本,就不会再向 registry 查询

  4. 如果下载没有完全下载好就失败了,那就不会修改package和lock,但是第二次继续下载的时候第一次下载好的包不会重新下载

  5. 在下载依赖的时候,如果该依赖所需的传递依赖本地已经有了,就不会再下载

下载中断后,第二次各包怎么处理

  1. 已完整下载的包: 直接从npm 的本地缓存解压

  2. 下载到一半失败的包:缓存没有合法条目,必须重新下载

  3. 已解压进 node_modules 的包:实际树里有它,重试时 diff 算"已有",连解压都省了

    diff是reify(动手装)之前的第一步:Diff.calculate({ actual, ideal })把 node_modules 现状和理想树逐节点对比,产出一张 “ADD / REMOVE / CHANGE / 不动” 的操作清单,_reifyPackages再照着清单执行。 它是 npm 的 “决策层”,负责回答一个关键问题:到底哪些事值得做。

为什么缓存能 “认出” 要用的文件

npm 的缓存是内容寻址的:每个下载完成的tarball按它的哈希值(integrity)存进_cacache。而 lock 里恰好记录着每个包的 integrity 字段 ——lock 里的 integrity 就是找缓存的钥匙:

"node_modules/left-pad":{"version":"1.0.0","integrity":"sha512-Xvly4CWfzT7TGZRB2Qd7ub2dmJDomZCNf3BuT3XXfrNerQHtta82NNhbvToU4Qiz7IHrgY...","resolved":"https://registry.npmmirror.com/left-pad/-/left-pad-1.0.0.tgz"}

下载时先算哈希,对得上才写进缓存;第二次要装时按同一个哈希查缓存,查到就直接用。

npm i <包名>@<版本> --offline

--offline表示完全不联网,包括查询 registry 也不行。

--prefer-offline表示缓存优先。如果缓存命中了,即使缓存过期了,也不查询registry

默认什么都不加的话也是缓存优先,但如果缓存过期了的话,会查询registry验证一次

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/30 2:35:40

SpringBoot 配置文件详解:properties 与 yml 从入门到实战

目录 ​编辑一、配置文件的作用 二、SpringBoot 配置文件格式 1. 快速修改端口 2. properties 与 yml 共存 三、properties 配置文件 1. 基本语法 连接&#xff1a; 2. 读取配置 3. 缺点 四、yml 配置文件 1. 基本语法 2. 配置不同数据类型及 null 3. 读取 yml 配置…

作者头像 李华
网站建设 2026/9/30 2:35:22

MCP 安全接入工具实战:Java 后端权限、审计与风险控制配置指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/30 2:35:11

Claude Code 自用高效插件:把 settings 改到 TaoToken 打通 HUD 与 Mermaid

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/30 2:34:39

深入理解 DAG Agent:用有向无环图编排智能体的并行任务流

文档教程知识库 【免费下载链接】developer-roadmap Interactive roadmaps, guides and other educational content to help developers grow in their careers. 项目地址&#xff1a; https://gitcode.com/GitHub_Trending/de/developer-roadmap 点击查看 免费下载 本文基于 …

作者头像 李华
网站建设 2026/9/30 2:34:10

Qt 新手必学核心语法(基于 C++,逐句讲解,保姆级)

前置记住&#xff1a;Qt 是C 框架&#xff0c;下面这些是 Qt 额外增加的宏 / 关键字&#xff0c;不是标准 C&#xff0c;靠 moc&#xff08;元对象编译器&#xff09;处理。普通 C 语法&#xff08;if、for、class、指针、vector 等&#xff09;照常使用。 环境&#xff1a;Qt …

作者头像 李华