You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NPM Workspace作用域模块子文件夹无法导入的问题求助

问题描述

我维护着一个基于NPM Workspace和Turborepo的Monorepo仓库,目录结构如下:

+-- src
    +-- package.json (定义common和modules下的所有工作区模块)
    +-- common
        +-- commonModule (@example/common-module)
            +-- package.json
            +-- tsconfig.json
            +-- src
                +-- index.ts (导出liba)
                +-- liba
                    +-- a.ts (导出代码)
                    +-- index.ts (导出a.ts)
    +-- modules
        +-- mainModules (@example/main-module)
            +-- package.json
            +-- tsconfig.json
            +-- src
                +-- index.ts

在src/modules/mainModules/src/index.ts中尝试导入@example/common-module的子文件:

import { a } from "@example/common-module/src/liba";

经tsc构建后用Node.js 16运行,出现模块找不到错误:

Error: Cannot find module '@example/common-module/src/liba'

但从模块根路径导入则完全正常:

import { lib } from "@example/common-module";

lib.a

所有模块的tsconfig.json配置如下:

{
  "extends": "@tsconfig/node16-strictest/tsconfig.json",
  "compilerOptions": {
    "lib": ["ESNext"],
    "outDir": "dist"
  }
}

想知道Node.js是不是不支持导入作用域模块的子文件夹?或者有什么解决办法?


原因与解决办法

核心原因

Node.js 16的模块解析逻辑中,使用@example/common-module/src/liba这类路径时,会尝试去@example/common-module包对应的路径下查找src/liba,但你的Monorepo工作区模块构建后,源码src目录并不会被Node.js识别为包的可导入路径——模块的构建产物输出到dist文件夹,且package.json默认的main字段指向构建后的入口文件,Node.js只会识别包的入口及明确定义的导出路径,不会直接读取包的源码目录。

解决办法

方法1:配置package.json的exports字段(推荐)

在@example/common-module的package.json中明确声明子路径导出,指定构建后的文件位置:

{
  "name": "@example/common-module",
  "main": "./dist/index.js",
  "exports": {
    ".": "./dist/index.js",
    "./liba": "./dist/liba/index.js"
  }
}

之后在main-module中即可按如下方式导入:

import { a } from "@example/common-module/liba";

方法2:使用TypeScript路径别名

在@example/main-module的tsconfig.json中添加路径别名,直接映射到common-module的源码路径:

{
  "extends": "@tsconfig/node16-strictest/tsconfig.json",
  "compilerOptions": {
    "lib": ["ESNext"],
    "outDir": "dist",
    "baseUrl": ".",
    "paths": {
      "@example/common-module/src/liba": ["../../common/commonModule/src/liba"]
    }
  }
}

注意:构建后Node.js无法直接识别TS路径别名,需要配合tsconfig-paths工具启动项目:

npx tsconfig-paths register --project tsconfig.json && node dist/index.js

方法3:扩展模块根入口导出

在@example/common-module/src/index.ts中直接导出a:

export { a } from './liba';

之后即可直接从模块根导入:

import { a } from "@example/common-module";

这是最简便的方式,也符合Monorepo模块导出的常规实践。


内容的提问来源于stack exchange,提问作者fauh45

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 07:40:27