TypeScript Monorepo中import type语法模块解析失败问题
pnpm workspace下Next.js跨包使用TypeScript类型语法报错解决
环境配置
我使用pnpm workspace,项目结构如下:
workspace/ ├── apps/ ├───── nextjs-app/ ├──────── package.json ├──────── tsconfig.json ├──────── ... ├── packages/ ├───── api/ ├──────── package.json ├──────── tsconfig.json ├──────── index.ts ├── tsconfig.base.json └── package.json
nextjs-app是预配置TypeScript的Next.js初始化项目,仅修改了所有tsconfig.json文件,三个TS配置文件内容如下:
./tsconfig.base.json
{ "compilerOptions": { "target": "es2017", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, "strict": true, "forceConsistentCasingInFileNames": true, "noEmit": true, "esModuleInterop": true, "module": "esnext", "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, "jsx": "preserve", "incremental": true, "noUncheckedIndexedAccess": true, "experimentalDecorators": true } }
./apps/nextjs-app/tsconfig.json
{ "extends": "../../tsconfig.base.json", "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.cjs", "**/*.mjs"], "exclude": ["node_modules"] }
./packages/api/tsconfig.json
{ "extends": "../../tsconfig.base.json", "include": ["index.ts"] }
另外,./packages/api/package.json的配置如下:
{ ... "name": "@my-app/api", "main": "./index.ts", "types": "./index.ts" ... }
已通过以下命令在Next.js项目中安装工作区包:
pnpm --filter nextjs-app add @my-app/api@workspace:*
问题描述
在API包中编写export const foo = 'bar';,可以在Next.js应用中通过import { foo } from '@my-app/api';正常导入使用。
但在API包中使用import type或export type语法时,会出现如下错误:
../../packages/api/index.ts Module parse failed: Unexpected token (14:7) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders | export const foo = 'bar'; | > export type Foo = 'bar'; |
该问题仅在跨包使用类型导入/导出时出现,NextJS项目内部使用import type和export type完全正常。
解决方案
方案1:配置Next.js编译工作区包
修改nextjs-app的next.config.js,添加transpilePackages配置,让Next.js编译指定的工作区包:
/** @type {import('next').NextConfig} */ const nextConfig = { transpilePackages: ['@my-app/api'], } module.exports = nextConfig
这样Next.js会把@my-app/api当作源码处理,编译其中的TypeScript语法,包括类型相关的语法。
方案2:让API包提前编译为JavaScript
- 修改
./packages/api/tsconfig.json,调整编译选项:
{ "extends": "../../tsconfig.base.json", "include": ["index.ts"], "compilerOptions": { "noEmit": false, "outDir": "./dist", "declaration": true } }
noEmit设为false,允许生成编译产物outDir指定编译产物输出目录为distdeclaration设为true,生成类型声明文件
- 修改
./packages/api/package.json,更新入口和类型指向编译后的文件,并添加build脚本:
{ ... "name": "@my-app/api", "main": "./dist/index.js", "types": "./dist/index.d.ts", "scripts": { "build": "tsc" } ... }
- 执行
pnpm --filter api build编译API包,之后Next.js会直接使用编译后的JavaScript文件,避免类型语法解析问题。
内容的提问来源于stack exchange,提问作者chocojunkie
相关产品推荐
相关产品推荐

