npm 完全指南:从装包到发布,把日常操作吃透
组里新来的实习生问我:"为什么你把 package-lock.json 也提交了?那不是自动生成的吗?"我意识到这个天天用的工具,很多细节大家都是"会用但说不清"。趁周末把 npm 的核心知识整理成一篇。
package.json:项目的身份证
最常用的字段速查:
{
"name": "my-cli",
"version": "1.2.0",
"description": "一句话描述,npm 搜索靠它",
"main": "index.js",
"bin": {
"my-cli": "./bin/cli.js"
},
"scripts": {
"dev": "node server.js",
"test": "jest"
},
"dependencies": {
"lodash": "^4.17.11"
},
"devDependencies": {
"jest": "~24.8.0"
},
"engines": {
"node": ">=8.0.0"
}
}
几个容易迷糊的:
main:别人require('my-cli')时加载的入口bin:声明命令行工具,全局安装后就能在终端敲my-clidependenciesvsdevDependencies:前者是运行时依赖(会被装进使用你包的项目),后者是开发依赖(测试、构建工具)。库作者分错这个会被用户骂——没人想装个工具库结果被拖进一百个 babel 插件
版本号与 ^ ~ 的区别
语义化版本 major.minor.patch:
1.2.3→ 主版本.次版本.修订号- 主版本:破坏性变更;次版本:新增功能(兼容);修订号:修 bug(兼容)
安装时的范围符:
| 写法 | 含义 | 实际可能装到 |
|---|---|---|
4.17.11 |
锁死这个版本 | 4.17.11 |
^4.17.11 |
兼容 4.x.x 的最新版 | 4.17.21 |
~4.17.11 |
只升到最新修订号 | 4.17.21(不会到 4.18) |
* |
任意版本 | 5.0.0 都可能,别这么干 |
^ 是最常用的,信任作者遵守语义化版本的前提下,自动拿到 bugfix 和新功能。
注意 ^0.x.x 的特例:0.x 版本被认为不稳定,^0.2.3 只允许升到 0.2.x,不会到 0.3.0。
package-lock.json:一定要提交!
npm install 按 ^ 装的是"当时最新",于是三个月后新同事拉代码,装出来的依赖版本和你不一样——"我这明明是好的"惨案就是这么来的。
package-lock.json 记录了每一个包(包括依赖的依赖)的确切版本和下载地址哈希。有了它:
npm ci # 严格按 lock 安装,CI 环境和团队协作必用
npm ci 和 npm install 的区别:ci 会删掉 node_modules 重装、严格按 lock、不会改 lock 文件。部署流水线请一律用 ci。
所以回答实习生的问题:lock 文件必须提交进 Git,它是"所有人装出一样的依赖树"的唯一保障。
npx:临时执行的神器
以前用项目的本地 webpack 要写 ./node_modules/.bin/webpack,或者全局装一份(版本还可能和项目冲突)。npx 解决的就是这事:
npx webpack --config webpack.config.js # 优先用项目本地的 webpack
npx create-react-app my-app # 临时下载脚手架跑完就扔,不留全局污染
逻辑:先找当前项目的 node_modules/.bin,找不到就临时下载到缓存执行。全局安装列表从此清爽。
scripts 的门道
{
"scripts": {
"dev": "nodemon server.js",
"build": "webpack --mode=production",
"pretest": "npm run lint",
"test": "jest",
"posttest": "echo 测试跑完啦"
}
}
npm run dev时,node_modules/.bin 会自动加入 PATH,所以能直接写nodemon而不是全路径pre/post前缀自动串联:跑npm test实际是 pretest → test → posttest 三连npm run不带参数会列出所有可用脚本,比翻 package.json 快
发布自己的包
写过好用的工具函数别只存在 gist 里,发到 npm 上:
npm login # 登录账号(先去官网注册)
npm version patch # 自动把版本号 +0.0.1 并打 git tag
npm publish # 发布
几个注意点:
files字段或.npmignore控制哪些文件进包,别把测试和源码全发上去- 包名先到 npm 官网搜一下,被占了换个
@你的用户名/包名的 scoped 名 - 发错了想撤回:
npm unpublish --force仅限 72 小时内,且会被官方鄙视。正确姿势是npm version patch再发一个修复版
其他高频操作速查
npm install lodash@4.17.10 # 装指定版本
npm outdated # 查哪些包有新版本
npm update lodash # 在版本范围允许内升级
npm uninstall lodash # 卸载
npm ls lodash # 查当前装的是什么版本、谁依赖了它
npm cache clean --force # 玄学问题最后的救赎
npm link # 本地调试自己的库:在库目录 link,在项目里 npm link 库名
小结
- dependencies 是运行时、devDependencies 是开发用,别混
^允许次版本升级,是最常用的范围符;lock 文件锁死依赖树,必须提交- CI 用
npm ci,临时执行用npx,别什么都往全局装 - scripts 的 pre/post 钩子可以串联任务
npm 本身不复杂,但这些细节决定了团队协作时是"顺滑"还是"每天互相对版本"。下一篇准备聊聊 Node 服务的日志实践,敬请期待。
看到这里了?如果这篇文章帮到过你
请我喝瓶可乐就好 🥤

评论0 条
还没有评论,来抢沙发~