在Next.js中安装本地编译的TypeScript共享包问题排查
问题
我确信这类问题已有多种变体被多次提问,但我始终无法解决。我有一个本地monorepo,包含三个TypeScript包:(nestjs-)backend、(nextjs-)frontend,以及供两者使用的共享包。该共享包不仅包含类型声明,还包含业务逻辑,因此需要编译。由于这个共享包仅用于这两个应用,无需发布到npm,我选择本地构建并安装它:
共享包package.json配置
{ "name": "@someapp/shared", "scripts": { "build": "tsc -p tsconfig.json" }, "exports": { "import": "./dist/src/index.js" }, "files": [ "dist/src/**/*" ], "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", "dependencies": { "typescript": "^4.8.4" } }
共享包tsconfig.json配置
{ "compilerOptions": { "composite": true, "declaration": true, "declarationMap": true, "outDir": "./dist", "baseUrl": "./", "target": "ESNext", "moduleResolution": "Node" } }
在共享包中运行npm run build可成功将带声明的JS文件输出到dist目录。通过npm i ../shared从前端安装该包后,它会被链接到node_modules中,包含dist目录。但构建前端应用时,webpack报错:
Module parse failed: Unexpected token (2:18) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.
显然前端导入共享包时,尝试加载ts文件而非编译后的js文件。请问我哪里操作有误,该如何解决?
解决方案
1. 配置Next.js编译指定包
Next.js默认不会编译node_modules内的包,而本地安装的共享包是软链接形式,Next会直接读取源TS文件而非编译后的JS文件,导致webpack解析失败。
在前端项目的next.config.js中添加transpilePackages配置:
/** @type {import('next').NextConfig} */ const nextConfig = { transpilePackages: ['@someapp/shared'], } module.exports = nextConfig
2. 完善共享包的导出配置
当前exports字段仅配置了import场景,可能存在模块解析兼容性问题,建议补充完整导出规则,并明确模块类型:
{ "name": "@someapp/shared", "type": "module", // 若使用ES模块需添加 "scripts": { "build": "tsc -p tsconfig.json" }, "exports": { ".": { "import": "./dist/src/index.js", "require": "./dist/src/index.js", "types": "./dist/src/index.d.ts" } }, "files": [ "dist/src/**/*" ], "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", "dependencies": { "typescript": "^4.8.4" } }
3. 确保TS编译覆盖所有文件
检查共享包的tsconfig.json是否配置了include字段,确保所有需要编译的TS文件都被纳入编译范围:
{ "compilerOptions": { "composite": true, "declaration": true, "declarationMap": true, "outDir": "./dist", "baseUrl": "./", "target": "ESNext", "moduleResolution": "Node" }, "include": ["src/**/*"], "exclude": ["node_modules", "dist"] }
4. 替换软链接为实体包安装
如果软链接是问题根源,可通过生成tar包的方式安装共享包:
# 在共享包目录执行 npm pack # 生成someapp-shared-x.x.x.tgz后,到前端目录执行 npm install ../shared/someapp-shared-x.x.x.tgz
内容的提问来源于stack exchange,提问作者prohit
相关产品推荐
相关产品推荐

