带有引用的 TypeScript 项目

Posted

技术标签:

【中文标题】带有引用的 TypeScript 项目【英文标题】:TypeScript project with references 【发布时间】:2019-08-02 14:01:43 【问题描述】:

我使用project references 来引用“前”和“后”项目中的“共享”项目。

tsc -v: Version 3.3.3

项目结构:

./MY_PROJECT.code-workspace   /* the only file in this level */
./back
./back/tsconfig.json
./shared/src/
./shared/
./shared/tsconfig.json
./shared/src/
./front
./front/tsconfig.json
./front/src

我正在尝试从共享项目中将一个模块导入./front/src/article-view-model.ts

import Article from "@shared/src/article";            // alias path
import Article from "../../shared/src/article"; // full relative path
export default class ArticleViewModel 

以下错误会立即在 VS Code GUI 中显示:

对于别名路径:

找不到模块“@shared/src/article”。 ts(2307)

完整的相对路径:

输出文件 '../../shared/src/article' 不是从源文件 'c:/SOMEWHERE_IN_MY_PC/shared/src/article.ts' 构建的。 ts(6305)

Intellisense (VS Code) 确实适用于别名和相对选项:

如果我尝试忽略错误并构建,它会失败:

C:\Program Files\nodejs\node_modules\npm\bin\node_modules\typescript\lib\tsc.js:1296 扔 e; ^

错误:调试失败。虚假表达。 在 mergeSymbol (C:\Program Files\nodejs\node_modules\npm\bin\node_modules\typescript\lib\tsc.js:25861:26) 在 C:\Program Files\nodejs\node_modules\npm\bin\node_modules\typescript\lib\tsc.js:25960:47 在 Map.forEach () 在 mergeSymbolTable (C:\Program Files\nodejs\node_modules\npm\bin\node_modules\typescript\lib\tsc.js:25958:20) 在 initializeTypeChecker (C:\Program Files\nodejs\node_modules\npm\bin\node_modules\typescript\lib\tsc.js:48653:21) 在 Object.createTypeChecker (C:\Program Files\nodejs\node_modules\npm\bin\node_modules\typescript\lib\tsc.js:25711:9) 在 getDiagnosticsProducingTypeChecker (C:\Program Files\nodejs\node_modules\npm\bin\node_modules\typescript\lib\tsc.js:71398:93) 在 Object.getGlobalDiagnostics (C:\Program Files\nodejs\node_modules\npm\bin\node_modules\typescript\lib\tsc.js:71755:72) 在 Object.getGlobalDiagnostics (C:\Program Files\nodejs\node_modules\npm\bin\node_modules\typescript\lib\tsc.js:73528:86) 在 buildSingleProject (C:\Program Files\nodejs\node_modules\npm\bin\node_modules\typescript\lib\tsc.js:75803:127)

./front/tsconfig.json 内容:


    "compilerOptions": 
        "allowSyntheticDefaultImports": true,
        "baseUrl": ".",
        "module": "amd",
        "noEmitOnError": true,
        "noImplicitAny": false,
        "out": "./lib/front-bundle.js",
        "paths": "@shared/*" : ["../shared/*"],
        "preserveConstEnums": true,
        "removeComments": true,
        "sourceMap": true,
        "target": "es2015",
        "watch": true
    ,
    "include": [
        "./src/**/*.ts",
    ],
    "references": [
        
            "path": "../shared"
        
    ]

./shared/tsconfig.json 内容:


    "compilerOptions": 
        "allowSyntheticDefaultImports": true,
        "composite": true,
        "declaration": true,
        "module": "amd",
        "noEmitOnError": true,
        "noImplicitAny": false,
        "out": "./lib/shared-bundle.js",
        "preserveConstEnums": true,
        "removeComments": true,
        "sourceMap": true,
        "target": "es2015",
        "watch": true
    ,
    "include": [
        "./src/**/*.ts",
    ]

【问题讨论】:

【参考方案1】:

这完全不能直接回答您的问题,但我觉得提供替代方案可能仍然有用。

以“更标准”的方式解决此问题的一种方法是将您的 3 个代码库全部设为 NPM 包。

这样您的导入将类似于@vendor/shared/foo 而不是../../../../shared/src/article

使用npm link 可以轻松处理项目的交叉依赖关系。

从技术上讲,您甚至不需要修改源代码结构(尽管您可能想要)。 shared 依赖项只是通过 node_modules 软链接。

【讨论】:

作为建议,我应该说使用npm link 并不总是最好的方法。由于使用了符号链接,我发现了一些问题,因此无法展平依赖关系,从而导致最终构建和开发之间存在差异。它肯定是一个很酷的开发工具,但并不总是最好的解决方案。只是我的两分钱! @leonardfactory 很高兴知道!通常打开“npm link”对我来说是一种暂时的状态,直到我可以停止进行交叉回购开发。我绝对可以看到这可能会成为一个问题。 我尝试使用 yalc 进行本地开发,它的工作方式类似于 npm 链接,具有扁平化支持和良好的观看模式,我建议!【参考方案2】:

我能够重现您遇到的错误如果我在包含frontbackshared 的目录中有错误的tsconfig.json。在这种情况下,运行tsc -b 会在当前目录中找到错误的tsconfig.json,并且由于它没有配置正确的paths 或其他任何东西,因此编译失败并出现与您遇到的相同的错误。

否则,如果我使用您的文件并发出 tsc -b front 而不是 tsc -b,它编译不会出错。

VSCode 没有遇到问题的原因是,为了提供补全功能,TypeScript 编辑器(通常)使用 TypeScript 提供的名为 tsserver 的工具。当编辑器给出tsserver 的文件路径时,tsserver 通过查找包含源文件的目录,然后向上查找父目录,以此类推,直到找到一个相关的tsconfig.json 987654334@ 文件。因此,当 VSCode 在front/src/foo.ts 上工作并要求tsserver 提供补全时,tsserver 会查找没有匹配文件的front/src,然后查找front,并在那里找到tsconfig.json

【讨论】:

我在./ 文件夹中没有tsconfig.json 文件。稍微更新了问题。 如果您在目录层次结构中有更高的tsconfig.json 文件,它也会被拾取。 任何级别都没有【参考方案3】:

如果您是从根文件夹编译,请尝试添加一个本地 tsconfig.json 文件并设置所有 references,即 references: path: './shared' 。否则,tsc 将找不到相关的项目来构建。

此外,没有 root tsconfig.json 允许 VSCode GUI 在查找 root tsconfig.json 时正常工作(这是我上次检查的状态,在这里你可以找到related issue)。

该错误似乎与丢失文件有关。如果您可以提供有关您所采取的构建步骤的更多详细信息,我可以尝试更好地检查它

【讨论】:

【参考方案4】:

我在这里的最后一次活动后几乎没有解决它,但我不能 100% 确定这是否由于以下更改而发生。反正我还是发在这里,因为还有新的观点和投票,所以可能对其他人有价值:

这就是变化:

./shared/tsconfig.json 内容中: 而不是:


    "compilerOptions": 
        "allowSyntheticDefaultImports": true,
        "composite": true,
        "declaration": true,
        "module": "amd",
        "noEmitOnError": true,
        "noImplicitAny": false,
        "out": "./lib/shared-bundle.js", <-------------
        "preserveConstEnums": true,
        "removeComments": true,
        "sourceMap": true,
        "target": "es2015",
        "watch": true
    ,
    "include": [
        "./src/**/*.ts",
    ]

用途:


    "compilerOptions": 
        "allowSyntheticDefaultImports": true,
        "composite": true,
        "declaration": true,
        "module": "amd",
        "noEmitOnError": true,
        "noImplicitAny": false,
        "outDir": "./lib/", <-------------
        "preserveConstEnums": true,
        "removeComments": true,
        "rootDir": "./src", <-------------
        "sourceMap": true,
        "target": "es2015",
        "watch": true
    ,
    "include": [
        "./src/**/*.ts",
    ]

【讨论】:

【参考方案5】:

我来到这里是为了解决“尚未从源文件构建”错误。原来tsc 监视进程没有正确退出,所以我有两个实例争夺文件。以防万一其他人遇到同样的问题?

【讨论】:

哇,谢谢! IDE 正在运行另一个手表。【参考方案6】:

在搜索“尚未从源文件构建打字稿参考”时发现此问题。 我的错误是当我should've been using the --build flag:tsc --build tsconfig.json 时我正在运行tsc -p tsconfig.json。如果您使用-p 运行,TypeScript 将不会构建引用的项目。仅当您使用--build 运行时。

【讨论】:

该死的。这很奇怪。这也为我解决了谢谢。

以上是关于带有引用的 TypeScript 项目的主要内容,如果未能解决你的问题,请参考以下文章

如何将 jQuery 导入 Angular2 TypeScript 项目?

图书TypeScript实战指南

新的 TypeScript 版本不包括“window.navigator.msSaveBlob”

带有 TypeScript 的 Angular 4:通过引用传递参数

如何在 Jest 的自定义测试环境文件中使用 TypeScript?

vscode下搭建Typescript编译环境