本文目录 3 个章节
Web生态相关技术
下面我从三个层面来讲:
- npm 是什么
- npm 提供了哪些核心功能
- “npm 的构建”(build)在做什么
1. npm 是什么
Node.js 包管理器(Registry + CLI) npm(Node Package Manager)最初是为 Node.js 而生的包管理工具,核心由两部分组成:
- 公共/私有 Registry(即包仓库,https://registry.npmjs.org/):上面存了数百万个 JavaScript/TypeScript 库。
- 命令行工具(CLI):
npm命令本身,负责与 Registry 交互(下载、发布、搜索)、管理本地依赖、执行脚本等。
生态枢纽
- 所有主流的 Node.js/前端框架(React、Vue、Angular、Next.js…)都把模块发布到 npm 上。
- 同时也是团队内部私有包的首选分发方式。
多模式支持
- CommonJS、ES Module(
.mjs或在package.json里"type": "module") - 原生支持 TypeScript → 通过社区维护的「ts-node」、
prepare脚本等方式也能无缝工作。
- CommonJS、ES Module(
2. npm 的核心功能
依赖管理
- 安装:
npm install [包名]→ 拉取最新版本并写入node_modules/,更新package.json和package-lock.json。 - 卸载:
npm uninstall [包名]→ 从node_modules/和dependencies中移除。 - 固定依赖树:
package-lock.json锁住了每个包的精确版本,保证多人、多环境安装一致。
- 安装:
版本控制 & 发布
- 语义化版本(SemVer):
major.minor.patch,npm 在安装时会根据^、~等前缀动态选择版本。 - 发布:
npm publish→ 根据包里的publishConfig、.npmignore或files字段打包并上传到 Registry。
- 语义化版本(SemVer):
脚本执行
- 在
package.json里定义"scripts":
- 在
{
"scripts": {
"build": "tsc -p tsconfig.json",
"test": "jest",
"lint": "eslint src/**"
}
}
- 运行:
npm run build、npm test、npm run lint。 - 支持生命周期脚本(lifecycle scripts),例如
preinstall、prepare、prepublishOnly、postinstall等,npm 会在特定时机自动调用它们。
本地/全局安装
- 本地(项目级)安装:
npm install lodash,仅在当前项目可用。 - 全局 安装:
npm install -g typescript,类似系统命令,可以在任意目录下直接调用tsc。
- 本地(项目级)安装:
安全审计 & 依赖诊断
npm audit:检查已安装包的已知安全漏洞并给出修复建议。npm outdated:列出可升级的依赖版本。
工作区(Workspaces)
- 从 npm v7 开始支持 Yarn 风格的 monorepo 管理:一个仓库里同时管理多个包、共享依赖、统一安装。
npm run build`
触发 Package.json 中的
build脚本- 当你在项目根目录下运行:
npm run build
npm 会依次执行:
prebuildbuildpostbuild这由内置的生命周期控制,保证你配置在这几个钩子里的命令被正确调用。
常见用途
- TypeScript → JavaScript:调用
tsc编译.ts到.js。 - 打包/压缩:调用 Webpack/Rollup/Vite/Esbuild,把模块打包成浏览器友好的包、生成 source map。
- 复制静态资源:把
.css、.html、图片等资源从src/复制到dist/。 - 环境替换:通过环境变量(
NODE_ENV=production)切换不同配置。
- TypeScript → JavaScript:调用
底层原理
- 并不是 npm 自己做编译,而是 npm 充当了脚本跑腿的角色:
npm 看到
package.json里有个叫build的脚本,就在 shell 里执行它。
执行过程:
- 解析
package.json,找到scripts.build的命令字符串。 - 在子进程里以
sh -c "<build 命令>"(UNIX)或cmd /d /s /c "<build 命令>"(Windows)运行。 - 等命令结束后,再执行
postbuild(如果定义了的话)。
- 解析