【问题标题】:Project references in TypeScript 3 with separate `outDir`TypeScript 3 中的项目引用,带有单独的 `outDir`
【发布时间】:2019-03-13 23:46:11
【问题描述】:

我想利用 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
  }
}

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

我不喜欢的是所有内容都被复制到 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

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

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


    【解决方案1】:

    确实,获取适用于源文件和输出文件的相对导入路径是一件很痛苦的事情。 official recommendation,如果我理解正确的话,就是为整个复合项目设置一个主输出目录,里面有SharedA子目录,所以源文件和输出文件可以有相同的相对布局.我不知道那是不是你的意思是你不想做。

    我知道的唯一其他选择是让每个组件使用指向输出文件的非相对导入(即@987654328 @ 将导入类似Shared/dist/shared) 的路径。由于您使用的是非相对导入,因此出现在源文件或相应输出文件中的相同导入路径解析为相同的目标输出文件。在您构建复合项目之前,导入不会在您的 IDE 中解析:这是一个known limitation。由于tsc doesn't rewrite imports,您需要设置运行时环境和/或使用捆绑器来处理非相对导入,并在必要时设置baseUrlpaths TypeScript 编译器选项以匹配。

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

    【讨论】:

    • 感谢 Matt 的回答并证实了我的发现。我不想更改现有项目的 out 文件夹,但我想它比第二个选项更好。我想我会尝试第一种方法。
    • 使用第一种方法,我现在遇到了节点模块的问题,因为它们是在每个项目中定义的,我猜当我尝试从主输出目录运行应用程序时节点找不到它们。有什么想法吗?
    • 我没有很好的解决方案;项目引用支持是非常新的,TypeScript 团队显然还没有考虑到所有的使用场景。您可以随时设置NODE_PATH,也可以尝试使用 lerna 或 yarn 工作区等工具。这在您之前的设置中是如何工作的,其中所有内容都复制到 A 的输出目录?
    • 我将研究 lerna 和 yarn 工作区,感谢您的指点。我们在每个项目中都有用于运行应用程序的 npm 脚本,例如 node dist/A/a.js。以前它可以工作,我猜是因为node_modules 目录就在dist 旁边。但是现在我创建了一个主输出目录,node ../dist/A/src/a.js 抱怨找不到一些模块。确实NODE_PAHT 是一个解决方案,如果我在A 中指定当前node_modules 的节点路径,它就可以工作。如果此项目引用在不更改输出目录的情况下正常工作,那就太好了。
    猜你喜欢
    • 2019-08-02
    • 2021-07-04
    • 1970-01-01
    • 2021-09-01
    • 2018-03-07
    • 2017-03-17
    • 1970-01-01
    • 2011-07-19
    • 1970-01-01
    相关资源
    最近更新 更多