背景
这是一个已有项目,之前 install 后一切正常。但某天我重新拉取仓库到新目录,准备在新仓库上继续开发时,却发现 build 和运行都报错了。
报错信息如下:
perl
09:15:03 [vite] Pre-transform error: Failed to resolve entry for package "@vue-office/docx". The package may have incorrect main/module/exports specified in its package.json.
09:15:04 [vite] Internal server error: Failed to resolve entry for package "@vue-office/docx". The package may have incorrect main/module/exports specified in its package.json.
Plugin: vite:import-analysis
File: E:/rag-op-admin-web/src/views/application/create/components/FilePreviewDialog.vue
at packageEntryFailure (file:///E:/rag-op-admin-web/node_modules/.pnpm/vite@5.4.1_@types+node@20.16.1_sass@1.77.8/node_modules/vite/dist/node/chunks/dep-Cy9twKMn.js:46533:15)
at resolvePackageEntry (file:///E:/rag-op-admin-web/node_modules/.pnpm/vite@5.4.1_@types+node@20.16.1_sass@1.77.8/node_modules/vite/dist/node/chunks/dep-Cy9twKMn.js:46530:3)
at tryNodeResolve (file:///E:/rag-op-admin-web/node_modules/.pnpm/vite@5.4.1_@types+node@20.16.1_sass@1.77.8/node_modules/vite/dist/node/chunks/dep-Cy9twKMn.js:46346:16)

或是找不到对应的 CSS 文件。
奇怪的是,旧的项目目录(一直没动过)却能正常运行。对比发现,旧项目的 node_modules/@vue-office/excel/lib/ 目录下存在 index.js 和 index.css,而新拉的仓库里却没有这些文件。
明明配置文件没改过,node 和 pnpm 版本也在兼容范围内,为什么新建的仓库总是缺少文件呢?
解决办法
经过排查,最终通过以下几个步骤解决了问题。下面分享排查和解决的过程。
1. 检查 package.json 中的 ignoredBuiltDependencies
perl
"ignoredBuiltDependencies": [
"@vue-office/docx",
"@vue-office/excel",
"@vue-office/pdf",
"@vue-office/pptx",
"esbuild",
"vue-demi"
]
这是 pnpm 用于在安装时忽略某些依赖的构建步骤和 postinstall 脚本 的配置。由于 @vue-office 的所有包都被列在这里,它们的 postinstall 脚本就被跳过了。
2. 检查 .npmrc 文件
ini
enable-pre-post-scripts=false
这个配置禁用了 npm/pnpm 的 pre 和 post 脚本执行。这意味着所有包的 postinstall 脚本都不会自动运行,自然也包括 @vue-office 包的 postinstall 脚本。所以要把它改成true
3. 手动执行 postinstall 脚本
即使检查了上面两项,我还是没能立即解决问题。最终我手动执行了各个包的 postinstall.js 脚本:
bash
node node_modules/@vue-office/excel/lib/script/postinstall.js
node node_modules/@vue-office/docx/lib/script/postinstall.js
node node_modules/@vue-office/pdf/lib/script/postinstall.js
node node_modules/@vue-office/pptx/lib/script/postinstall.js
执行完毕后,再去查看 node_modules/@vue-office/excel/lib/ 目录,发现 index.js 和 index.css 文件已经生成,项目也恢复正常了。
4. 更彻底的解决方式
手动执行脚本虽然能临时解决问题,但下次重新安装依赖时又会丢失。为了避免这种情况,可以:
-
移除
ignoredBuiltDependencies中的相关包(如果确实不需要忽略的话) -
删除
.npmrc中的enable-pre-post-scripts=false,或者将其改为true -
使用 pnpm 的 approve-builds 命令 (适用于 pnpm 10.x):
运行
pnpm approve-builds,然后根据提示选择允许这些包的构建脚本(注意这是交互式操作,适合手动构建时使用) -
在项目级别创建一个自定义的 postinstall 脚本 ,在
package.json的scripts中添加:json
perl"postinstall": "node node_modules/@vue-office/excel/lib/script/postinstall.js && node node_modules/@vue-office/docx/lib/script/postinstall.js && ..."
分析原因
为什么会出现这个问题?为什么旧项目没问题,新拉取的仓库却出问题?
1. @vue-office 包需要运行 postinstall 脚本
@vue-office 是一个同时支持 Vue 2 和 Vue 3 的库。为了兼容两个版本,它在安装后需要通过 postinstall 脚本自动检测项目中的 Vue 版本,并将对应版本的代码复制到 lib 目录下(生成 index.js 和 index.css)。
如果 postinstall 没有执行,lib 目录下就会缺少这些文件,导致项目在引入时报模块找不到的错误。
2. 为什么新拉取的仓库 postinstall 没有执行?
- pnpm 10.x 引入了新的安全特性,默认会忽略构建脚本
- 需要使用
pnpm approve-builds来批准这些包的构建脚本,但这需要交互式操作 - 或者可以创建一个自定义的 postinstall 脚本在项目级别
总结
遇到类似"模块找不到"的问题,尤其是在重新拉取项目后出现,可以按以下思路排查:
- 检查项目中的
.npmrc和package.json中与脚本执行相关的配置 (如enable-pre-post-scripts、ignoredBuiltDependencies)。 - 确认依赖包是否需要 postinstall 脚本(查看包的文档或源码)。
- 尝试手动执行 postinstall 脚本,看是否能生成缺失的文件。
- 考虑 pnpm 版本的安全策略 ,必要时使用
pnpm approve-builds或自定义 postinstall 脚本。
通过以上方法,可以确保项目在任何环境下都能正确安装依赖并运行。