依赖问题详解
pnpm vs npm vs yarn、React 版本冲突、peer dependencies、monorepo 场景的完整排查与解决方案
依赖问题详解
依赖安装和版本管理是模板项目最常见的问题来源。本页覆盖包管理器差异、React 版本冲突、peer dependencies 警告、以及 monorepo 特殊场景。
包管理器选择:pnpm vs npm vs yarn
推荐:pnpm
@karinjs/template-react 开发和测试均使用 pnpm,推荐插件项目也用 pnpm:
npm install -g pnpm
pnpm install优势:
- 严格的依赖隔离,避免幽灵依赖(访问未声明的包)
- 磁盘占用更小(全局 content-addressable store)
- 安装速度更快
使用 npm 的注意事项
npm 7+ 对 peer dependencies 更严格,可能报 ERESOLVE 错误:
npm install --legacy-peer-deps或在 .npmrc 里永久设置:
legacy-peer-deps=true--legacy-peer-deps 会跳过 peer 版本检查,可能导致运行时不兼容。优先升级依赖版本解决冲突,只在无法升级时才用此选项。
使用 Yarn 的注意事项
Yarn 1.x (classic) 的 PnP 模式与 ktr 的约定发现机制不兼容,必须用 nodeLinker: node-modules 模式:
nodeLinker: node-modulesYarn 2+ (Berry) 未经测试,遇到问题时切换到 pnpm 或 npm。
React 版本冲突
症状
npm ERR! Could not resolve dependency:
npm ERR! peer react@">=18.0.0" from @karinjs/template-react@x.x.x
npm ERR! node_modules/@karinjs/template-react或者安装成功但运行时报错:
Error: Invalid hook call. Hooks can only be called inside the body of a function component.原因
项目里已有 React 17.x 或更旧版本,或其他依赖(如 UI 组件库)锁定了不兼容的 React 版本。运行时报 hooks 错误通常是因为产物里存在两份 React(源码一份、打包产物一份),hooks 状态无法共享。
解决方案
1. 检查所有 React 版本
pnpm list react react-dom
# 或
npm ls react react-dom输出示例:
karin-plugin-example@1.0.0
├─┬ @karinjs/template-react@0.1.0
│ ├── react@18.3.1
│ └── react-dom@18.3.1
└─┬ some-ui-library@2.0.0
├── react@17.0.2 ← 冲突源头
└── react-dom@17.0.22. 升级到 React 19(与脚手架一致)
peer 只要求 react >=18.0.0,但建议与脚手架默认口径一致,直接装 React 19:
{
"devDependencies": {
"react": "^19.2.8",
"react-dom": "^19.2.8",
"@types/react": "^19.2.18",
"@types/react-dom": "^19.2.4"
}
}pnpm install3. 强制去重(pnpm)
如果某个深层依赖仍然引入旧版 React,在 package.json 里显式覆盖:
{
"pnpm": {
"overrides": {
"react": "^18.3.1",
"react-dom": "^18.3.1"
}
}
}4. 强制去重(npm / yarn)
npm 使用 overrides,yarn 使用 resolutions:
{
"overrides": {
"react": "^18.3.1",
"react-dom": "^18.3.1"
}
}5. 打包时确保只有一份 React
Vite 配置里加 resolve.dedupe:
export default ({
: {
: ['react', 'react-dom']
}
})构建时必须把 React 整体打进产物(ssr.noExternal: true),只有 node-karin 保持外部。组件和渲染器必须共用同一份 React,否则 hooks
崩溃。
Peer Dependencies 警告
症状
pnpm 报 WARN Issues with peer dependencies found,列出一堆不匹配的包:
WARN Issues with peer dependencies found
.
└─┬ @karinjs/template-react
└── ✕ unmet peer react@">=18.0.0": found 17.0.2npm 报 npm WARN peer dep missing。
原因
peer dependencies 声明的是"宿主项目应该提供的版本",用于确保插件和宿主用同一份依赖。@karinjs/template-react 声明了 react >=18.0.0 作为 peer,如果项目安装的版本不匹配就会警告。
解决方案
1. 升级到 React 19(推荐)
peer 只要求 >=18.0.0,建议与脚手架默认口径一致:
pnpm add -D react@^19.2.8 react-dom@^19.2.82. 允许不匹配(pnpm)
strict-peer-dependencies=false或单次安装:
pnpm install --no-strict-peer-dependencies3. 允许不匹配(npm)
npm install --legacy-peer-deps警告不会阻止安装,但可能导致运行时错误。优先升级依赖版本,只在确认兼容但版本号不匹配(如 19.0.0-rc 预发布版本不匹配 >=18.0.0)时才忽略警告。
Monorepo 场景
症状
在 monorepo(如 pnpm workspace、Turborepo、Nx)里,ktr dev 或构建时报错:
Error: Cannot find package '@karinjs/template-react' imported from <插件包路径>或者 renderImage 类型失效、注册表加载失败。
原因
Workspace 协议(workspace:*)、依赖提升(hoisting)、以及符号链接(symlink)导致包解析路径与 ktr 约定发现的假设不符。
解决方案
1. 确保依赖安装在插件包自己的 node_modules
pnpm workspace 默认会提升依赖到 monorepo 根目录。ktr 按 import.meta.url 向上找 package.json 定位包根,如果 node_modules 在外层,相对路径解析会失败。
在插件包的 package.json 里显式声明:
{
"devDependencies": {
"@karinjs/template-react": "^0.1.0",
"react": "^18.3.1",
"react-dom": "^18.3.1"
}
}在 monorepo 根目录的 pnpm-workspace.yaml 里禁用该包的 hoisting:
packages:
- 'packages/*'
# 禁用 hoisting 以确保每个包有独立的 node_modules
public-hoist-pattern: []或者只针对 ktr 相关的包:
public-hoist-pattern[]='!@karinjs/template-react'
public-hoist-pattern[]='!react'
public-hoist-pattern[]='!react-dom'2. 使用 workspace 协议时指定具体版本
{
"devDependencies": {
"@karinjs/template-react": "workspace:^0.1.0"
}
}3. 检查 tsconfig.json 路径
monorepo 里常用 paths 映射模块路径,确保 .ktr/ 和 ktr/ 不被映射到别的位置:
{
"compilerOptions": {
"jsx": "react-jsx",
"paths": {
"@/*": ["./src/*"]
// 不要映射 .ktr 或 ktr
}
},
"include": ["src", "ktr", ".ktr"]
}4. 验证包根定位
在 src/utils/render.ts 里打印包根路径调试:
import { } from '@karinjs/template-react'
.('Current file URL:', import.meta.)
const = (import.meta., {
: { : './temp' }
})运行后检查日志,确认包根定位到插件包自己的目录(包含 package.json 和 ktr/ 的那一层)。
安装后无法找到 ktr 命令
症状
pnpm ktr dev
# command not found: ktr原因
@karinjs/template-react 未安装到项目本地,或 pnpm bin 路径未加到 PATH。
解决方案
1. 确认包已安装
pnpm list @karinjs/template-react未安装时执行:
pnpm add -D @karinjs/template-react2. 通过 package.json scripts 调用
{
"scripts": {
"template": "ktr sync && ktr dev"
}
}pnpm template3. 使用 pnpm exec
pnpm exec ktr dev4. 全局安装(不推荐)
pnpm add -g @karinjs/template-react
ktr dev全局安装会导致版本不跟随项目,团队协作时容易出现版本不一致问题,仅限个人快速测试使用。
依赖安装慢或超时
症状
pnpm install
# 长时间卡在 "Resolving dependencies..." 或网络超时原因
国内网络访问 npm registry 慢,或某些包(如 Puppeteer)下载二进制文件时超时。
解决方案
1. 使用国内镜像
# pnpm
pnpm config set registry https://registry.npmmirror.com
# npm
npm config set registry https://registry.npmmirror.com
# yarn
yarn config set registry https://registry.npmmirror.com2. 代理设置
# HTTP 代理
pnpm config set proxy http://127.0.0.1:7890
pnpm config set https-proxy http://127.0.0.1:7890
# 清除代理
pnpm config delete proxy
pnpm config delete https-proxy3. Puppeteer 国内加速
node-karin 依赖 Puppeteer 截图,二进制下载可能很慢。在 .npmrc 里指定国内镜像:
puppeteer_download_host=https://cdn.npmmirror.com/binaries/chrome-for-testing