LESSON 4.2 / MODERN FRONTEND

Node.js、npm 与构建工具

构建工具在开发者写法和浏览器运行代码之间做转换;npm 让依赖跟随项目,而不是散落在电脑里。

预计阅读15–20 分钟
完成结果能运行、构建并解释一个现代前端项目最基本的依赖结构。
本课目标
  • 能运行、构建并解释一个现代前端项目最基本的依赖结构。
  • Node.js 运行环境、npm 包管理和 package.json
  • 初始化一个构建项目,安装一个依赖,观察 package.json 与锁文件的变化。
开始之前
  • 完成 4.1「模块化:让依赖关系变得明确」
01

FOUNDATION

必须理解

构建工具在开发者写法和浏览器运行代码之间做转换;npm 让依赖跟随项目,而不是散落在电脑里。

Node.js 提供浏览器之外的 JavaScript 运行环境,npm 管理项目依赖,Vite 等构建工具负责开发服务与生产打包。三者角色不同,却常在同一条命令中出现。

先建立整体直觉

Node.js 像工厂动力,npm 像材料采购与清单,构建工具像生产线。package.json 是项目说明书,锁文件记录实际使用的材料版本。

贯穿本课的实际场景

任务应用用 npm 安装 React,Vite 在开发时快速刷新页面,在发布前把 TypeScript、模块和资源生成浏览器可运行的产物。

概念 1

Node.js 运行环境、npm 包管理和 package.json

先用白话理解

Node.js 让 JavaScript 能在浏览器之外运行,版本不同会影响工具能不能用。npm 则负责下载项目依赖,也会按 package.json 里的 scripts 帮你运行命令。

基础概念

Node.js 是在浏览器之外运行 JavaScript 的运行时;npm 是包管理器和脚本入口;package.json 是项目的名称、脚本与依赖清单。

进一步理解

开发工具本身也需要程序执行,因此构建、测试和代码生成通常由 Node.js 运行。npm 根据清单安装包,并把项目内可执行工具加入脚本环境。

`scripts` 给复杂命令稳定名称,`dependencies` 记录运行需要的包,`devDependencies` 记录开发工具。Node 与包版本都会影响结果。

放进实际场景

运行 `npm run dev` 时,npm 在 package.json 查找 dev 脚本,再使用项目依赖启动开发服务器,而不是调用系统里某条同名魔法命令。

容易混淆的地方

Node.js 不是框架,npm 也不是依赖仓库本身;一个负责执行,一个管理和调用项目依赖。

这一小节记住:先找 package.json,就能知道这个项目希望怎样安装和运行。

概念 2

dev、build、preview/start 三类命令

先用白话理解

package.json 写着项目需要哪些包和脚本,锁文件继续记下最终装到的精确版本。node_modules 只是根据这些清单装出来的结果,体积很大,也可以重新生成。

基础概念

锁文件记录本次解析出的精确依赖树,node_modules 是按清单安装在本机的实际文件集合。前者用于复现,后者是可以重新生成的工作结果。

进一步理解

package.json 常允许一个兼容版本范围,间接依赖又有自己的范围。锁文件把选择结果固定,让开发机、持续集成和部署尽量使用同一组合。

安装命令会读取清单和锁文件。擅自删除锁文件相当于允许整个依赖树重新选择版本,可能掩盖原问题并引入更多变化。

放进实际场景

团队提交 package-lock.json,不提交 node_modules;新电脑使用锁文件安装,就能得到与验证环境接近的依赖树。

容易混淆的地方

锁文件不是所有平台百分之百相同结果的保证,原生依赖、运行时和操作系统仍会造成差异,但没有锁文件的不确定性更大。

这一小节记住:提交清单与锁定结果,让安装可以重现;本机依赖目录不用进 Git。

概念 3

源代码、依赖目录和生产构建产物

先用白话理解

dev 是方便你边改边看的开发环境,build 会做真正的生产打包,preview 或 start 用来运行打包结果。本地开发页能打开,并不保证 build 一定通过。

基础概念

开发命令为快速反馈优化,构建命令生成并检查生产产物,preview 或 start 用接近生产的方式运行产物。三者处于不同阶段,可能暴露不同问题。

进一步理解

开发服务器常提供热更新和宽松错误界面;构建会进行类型检查、压缩、路由分析和环境替换;生产运行不再读取某些开发专用设置。

因此“dev 能打开”只能证明开发路径的一部分。发布前必须构建,并实际访问构建结果的关键路由与资源。

放进实际场景

任务应用开发时即时更新正常,但 build 发现服务端组件误用了浏览器 API;只有修复并重新构建,才具备发布条件。

容易混淆的地方

preview 不是新的构建,它通常运行已有产物;修改源码后未重建,看到的仍可能是旧版本。

这一小节记住:开发验证速度,构建验证可交付性,生产运行验证真实行为。

项目脚本不是系统命令
运行前先确认
  • 命令必须在包含该 package.json 的目录运行。
  • 项目依赖已经按照现有锁文件安装。
{
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  }
}
这段代码在做什么

npm run dev 会查找 package.json 中名为 dev 的脚本,并在当前项目依赖环境中执行。

  1. scripts 中的 dev 是项目为启动开发环境定义的稳定名称。
  2. 执行 npm run dev 时,npm 展开右侧命令并使用项目内的 vinext。
  3. dependencies 与 devDependencies 由安装过程解析,精确结果继续写入锁文件。
你应该观察到

终端会显示开发服务器地址;若当前目录错误,npm 会明确提示找不到 package.json,而不是启动另一个项目。

02

AI COLLABORATION

AI 如何参与

安装依赖前让 AI 解释用途、版本和是否真的需要;构建失败时保留完整命令与日志。

推荐协作顺序

  1. 1

    把 Node 版本、package.json 和完整报错交给 AI。

  2. 2

    让它先指出错误发生在安装、开发运行还是生产构建。

  3. 3

    只尝试最小修复,修复后重新跑原来失败的那条命令。

可直接使用的 Prompt
我是零基础学生,看到 package.json、package-lock.json、node_modules、src、dist 五个名字。请用“任务应用从源代码到浏览器”的流程解释每个职责,再给出安装依赖前应检查的 5 项清单。不要建议全局安装。
应该得到什么

解释运行时、包管理与构建产物的区别,并指出哪些文件应提交、哪些可以重新生成。

人工检查清单

  • 确认 AI 没随意要求升级所有包、删除锁文件或提交 node_modules。
  • 要求 AI 先读取项目已有脚本、Node 版本和锁文件,再建议命令或依赖变化。
  • 分别运行开发与生产构建,并核对出错阶段,不能用 dev 成功替代 build 证据。
03

COMMON TRAPS

常见误区

错误不是需要隐藏的失败,而是帮助你看清系统边界的证据。下面三类问题在 AI 辅助学习中最常出现。

误区 1

把 Node、npm 和 Vite 混成一个工具

你会看到
npm 命令失败时反复重装 Vite,仍然不知道哪一层有问题。
为什么发生
一次升级全部依赖会同时改变大量行为,失败后无法归因;把 node_modules 提交又把本机产物扩散给所有环境。
怎样纠正
先分清运行环境、包管理器和构建工具各自负责什么。
误区 2

随手升级全部依赖

你会看到
为了修一个报错执行全量更新,结果出现更多不兼容。
为什么发生
混用包管理器会生成不同锁文件与安装算法,同一项目出现多个互相竞争的依赖真相。
怎样纠正
锁定当前问题涉及的包和版本,只做可说明的升级。
误区 3

开发能跑就不做构建

你会看到
本地页面正常,上线时才发现类型或生产打包失败。
为什么发生
删除锁文件让版本重新解析,短期可能绕过冲突,却不再是原来验证过的依赖组合。
怎样纠正
每个阶段性成果都运行一次 build,尽早暴露生产差异。
04

HANDS-ON

动手任务

初始化一个构建项目,安装一个依赖,观察 package.json 与锁文件的变化。

准备条件
  • 完成 4.1「模块化:让依赖关系变得明确」

跟着做

  1. 01

    记录当前 Node 与 npm 版本。

  2. 02

    创建最小 Vite TypeScript 项目并查看初始文件。

  3. 03

    运行开发命令,确认本地地址和终端日志。

  4. 04

    安装一个小依赖,比较 package.json 与锁文件变化。

  5. 05

    运行生产构建,区分 src 与 dist 的内容。

完成标志

能运行、构建并解释一个现代前端项目最基本的依赖结构。

加餐挑战

在新目录只复制源码与依赖清单,重新安装并验证构建可复现。

离开本课前,自问四件事

  • Node.js、npm、package.json、锁文件和 node_modules 分别是什么?
  • 为什么项目脚本可以找到没有全局安装的工具?
  • dev、build 与 start/preview 的验证目标有什么不同?
  • 依赖出错时为什么不应先删除锁文件或全部升级?
完成本课了吗?

确认完成后,会同步更新学习中心的课程学习进度。