首页 > 解决方案 > TypeScript 3 中的项目引用,带有单独的 `outDir`

问题描述

我想利用 TypeScript 3.1 中的项目引用功能。我的项目编译后的目录结构原来是这样的:

.
├── A
│   ├── a.ts
│   ├── dist
│   │   ├── A
│   │   │   └── a.js
│   │   └── Shared
│   │       └── shared.js
│   └── tsconfig.json
└── Shared
    ├── dist
    │   └── shared.js
    ├── shared.ts
    └── tsconfig.json

目录内容Shared

shared.ts

export const name = "name";

tsconfig.json

{
  "compilerOptions": {
    "target": "es5",                          
    "module": "commonjs",                     
    "outDir": "dist",                        
    "strict": true
  }
}

目录内容A

a.ts

import { name } from "../Shared/shared"; 

console.log(name);

tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "outDir": "dist",
    "strict": true
  }
}

我可以通过node dist/A/a.js在A目录中运行来成功运行它。

我不喜欢的是所有内容都被复制到 A 的输出目录中。我认为项目参考是为了解决这个问题。

为了启用项目引用,我在Shared/tsconfig.json.

"composite": true

以及以下内容A/tsconfig.json

"references": [
  { "path": "../Shared" }
]

现在当我编译时,目录结构如下所示,这是我所期望的:

.
├── A
│   ├── a.ts
│   ├── dist
│   │   └── a.js
│   └── tsconfig.json
└── Shared
    ├── dist
    │   ├── shared.d.ts
    │   └── shared.js
    ├── shared.ts
    └── tsconfig.json

但是,当我node dist/a.jsA目录中运行时,出现以下错误:

module.js:538
    throw err;
    ^

Error: Cannot find module '../Shared/shared'

原因是在生成的a.js文件中,对导入模块的引用没有正确解析:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var shared_1 = require("../Shared/shared");
console.log(shared_1.name);

有没有办法让它工作而不将所有输出文件放到同一个目录中?

或者,有没有更好的方法来组织我的项目以利用项目引用?

标签: typescript

解决方案


实际上,让源文件和输出文件都适用的相对导入路径是一件很痛苦的事情。官方的建议,如果我理解正确的话,是为整个复合项目设置一个主输出目录,里面有SharedA子目录,这样源文件和输出文件可以有相同的相对布局。我不知道那是不是你的意思是你不想做。

我知道的唯一其他选择是让每个组件使用指向输出文件的非相对导入(即,将导入类似的路径)导入其他组件(在您的情况下,您只有Aimporting )。由于您使用的是非相对导入,因此源文件或相应输出文件中出现的相同导入路径解析为相同的目标输出文件。在您构建复合项目之前,导入不会在您的 IDE 中解析:这是一个已知限制。由于不重写 imports,因此您需要设置运行时环境和/或使用捆绑器来处理非相对导入,并在必要时设置和TypeScript 编译器选项以匹配。SharedA/a.tsShared/dist/sharedtscbaseUrlpaths

如果需要,我很乐意帮助您了解这两种方法的详细信息;只是让我知道你卡在哪里。


推荐阅读