npm包管理器
npm包文件查找的策略
- 查找当前目录下的node_modules目录,看是否有匹配项,如有,命中文件
- 寻找父目录的下的node_modules,如有,命中文件
- 按照这个规则一直往父目录搜索直到到根目录下的node_modules
pnpm的优势
-
文件系统对于文件的硬链接
- 多个本地项目依赖了相同的包,只会安装一次。(文件会直接复用)
- 升级包的时候,与前一个版本相同的文件会复用。
-
npm
的扁平化依赖管理导致node_modules
中的包杂乱无章,而pnpm安装的包都放在.pnpm文件夹中,然后项目真正用到的包才放到node_modules
中,并使用软链接将这些包关联起来。.pnpm文件夹中的包的node_modules
也通过软链接来引用,解决重复包的问题。 -
解决了幽灵依赖的问题,更安全
- 幽灵依赖是什么: 我们假设有个项目工程projectA,它依赖了toolsB这个npm包。由于yarn和npm包安装时为了防止嵌套过深导致重复安装包,它会将项目projectA的dependencies和devDependencies直接安装到
/node_modules
中,并将toolsB这个包里面的package.json中的dependencies也安装到/node_modules
,但是它的devDependencies就并不会安装了,因为他将被视为npm包开发时候才需要的依赖。 但这导致了我们的项目projectA可以直接使用toolsB包的dependencies而无需在package.json中进行声明,这就是幽灵依赖, 因为依赖都扁平化到node_modules
所以项目可以直接访问到幽灵包。 - 因为项目直接使用的包才会在
/node_modules
中,所以不会使用到幽灵包
- 幽灵依赖是什么: 我们假设有个项目工程projectA,它依赖了toolsB这个npm包。由于yarn和npm包安装时为了防止嵌套过深导致重复安装包,它会将项目projectA的dependencies和devDependencies直接安装到
常用命令
// 登录
// # 建议指定registry,避免登录到公司内部的开源库中去
pnpm login --registry https://registry.npmjs.org/
// 全局安装管理器
npm i -g pnpm
npm i -g yarn
// 全局安装
yarn global add create-react-app
// 初始化一个 `package.json` 文件
pnpm init
yarn init
npm init
//查看包信息
npm info lodash // (或者view)
pnpm info lodash // (或者view)
// 根目录安装
pnpm install // pnpm i
yarn
npm install
// 安装某个包
yarn add taco
pnpm i taco
npm install taco —save
// 卸载包
npm uninstall taco —save
yarn remove taco
pnpm remove taco
//更新所有
npm update —save
yarn upgrade
pnpm up
//更新包:
pnpm up xxx
yarn upgrade less@1.8.8
// pnpm up xxx 有时候不会起作用,需要强制更新; 或者 手动更改pkg.json内容 然后再安装
// 强制更新到最新版本
pnpm up starlight-blog --latest
// 全局目录
npm root -g // 查询npm全局目录
yarn global dir // 查询yarn全局目录
//查看缓存
npm config get cache
pnpm store path
yarn cache list // yarn cache dir // 查询yarn缓存目录
// 全局缓存清除
yarn cache clean
npm cache clean --force
pnpm store prune
// 发布包
yarn publish
npm publish
pnpm publish // —tag beta (如果当前包是一个beta版)
pnpm的monorepo命令
// 安装项目公共开发依赖
pnpm install -wD xxx
// 卸载公共依赖
pnpm uninstall -w xxx
// 根目录执行script
pnpm run xxx
// 为pkgname这个子包安装依赖 (-S 和 -D 选项分别代表dep和devDep)
pnpm --filter pkgname i -S lodash
// 在pkgname子包内安装pkgname2子包(基于workspace协议)
pnpm --filter pkgname i -S pkgname2
// 发布所有包名为 @orgname/ 开头的包
pnpm --filter @orgname/* publish
pkg.json字段
{
"version": "0.0.1",
"name": "vue",
// 一句话简介,可以作为关键字搜索的依据
"description": "The progressive JavaScript framework for building modern web UI.",
// 关键字、标签,正确设置可以提高在 npm 的搜索权重与曝光度
"keywords": ["vue"],
// 包的作者,主要 Owner
"author": "Evan You",
// 内部项目不发布到npm
"private": true,
// 开源许可证
"license": "MIT",
// 项目主页
"homepage": "https://github.com/vuejs/core/tree/main/packages/vue#readme",
// 源码仓库
"repository": {
"type": "git",
"url": "git+https://github.com/vuejs/core.git"
},
"publishConfig": {
// 发布包时指定发布到npmjs
"registry": "https://registry.npmjs.org/",
// 机构包(@xxx/开头的包默认是私有包,需要指定为public才能发布到npmjs)
"access": "public"
},
"scripts": {
},
// 发布包时,哪些文件或目录需要被提交到 npm 服务器
"files": [
"LICENSE",
"README.md",
"dist"
],
// BUG 反馈方式,支持 `bugs.email` 邮箱字段
"bugs": {
"url" : "https://github.com/vuejs/core/issue"
},
// d.ts 类型声明的加载入口
"types": "index.d.ts",
// cjs入口
"main": "index.js",
// es入口
"module": "index.mjs",
"exports": {
".": {
// cjs入口
"require": "index.js",
// es入口
"import": "index.mjs",
// d.ts 类型声明的加载入口
"types": "index.d.ts"
},
}
其他
www.npmjs.com 登录
这个还有点坑,需要username(一般网站是手机号/邮箱)+password;username可以从你之前在npm上发布的包信息上看到。
参考文章
https://juejin.cn/post/7124613898115743757#heading-4 新一代包管理工具 pnpm 使用心得
https://blog.csdn.net/handsomexiaominge/article/details/96461786 nodejs模块查找策略
https://zhuanlan.zhihu.com/p/642832967 【从 0 到 1 搭建 Vue 组件库框架】1. 基于 pnpm 搭建 monorepo 工程目录结构 https://juejin.cn/post/7198159223204675643#comment 十分钟搭建一个 Monorepo Vue3 组件库 https://d.umijs.org/guide dumi https://github.com/JohnnyZhangQiao/pnpm-monorepo-learn React18.x + Typescript 组件库 https://zhuanlan.zhihu.com/p/598455629 pnpm技术体系之:打造企业级 pnpm 开源组件
Tags: