TypeScript project with references
Asked Answered
V

8

41

I use project references to reference "shared" project from "front" and "back" ones.

tsc -v: Version 3.3.3

Project structure:

./{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

I am tring to import a module to ./front/src/article-view-model.ts from the shared project:

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

The following errors are shown immediately in VS Code GUI:

For alias path:

Cannot find module '@shared/src/article'. ts(2307)

For full relative path:

Output file '../../shared/src/article' has not been built from source file 'c:/{SOMEWHERE_IN_MY_PC}/shared/src/article.ts'. ts(6305)

Intellisense (VS Code) does work for both alias and relative options:

Intellisense

If i try ignore the errors and build, it fails with that:

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

Error: Debug Failure. False expression. at mergeSymbol (C:\Program Files\nodejs\node_modules\npm\bin\node_modules\typescript\lib\tsc.js:25861:26) at C:\Program Files\nodejs\node_modules\npm\bin\node_modules\typescript\lib\tsc.js:25960:47 at Map.forEach () at mergeSymbolTable (C:\Program Files\nodejs\node_modules\npm\bin\node_modules\typescript\lib\tsc.js:25958:20) at initializeTypeChecker (C:\Program Files\nodejs\node_modules\npm\bin\node_modules\typescript\lib\tsc.js:48653:21) at Object.createTypeChecker (C:\Program Files\nodejs\node_modules\npm\bin\node_modules\typescript\lib\tsc.js:25711:9) at getDiagnosticsProducingTypeChecker (C:\Program Files\nodejs\node_modules\npm\bin\node_modules\typescript\lib\tsc.js:71398:93) at Object.getGlobalDiagnostics (C:\Program Files\nodejs\node_modules\npm\bin\node_modules\typescript\lib\tsc.js:71755:72) at Object.getGlobalDiagnostics (C:\Program Files\nodejs\node_modules\npm\bin\node_modules\typescript\lib\tsc.js:73528:86) at buildSingleProject (C:\Program Files\nodejs\node_modules\npm\bin\node_modules\typescript\lib\tsc.js:75803:127)

./front/tsconfig.json contents:

{
    "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 contents:

{
    "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",
    ]
}
Vinia answered 12/3, 2019 at 6:55 Comment(0)
V
9

I solved it little after my last activity here, but i wasn't 100% sure if that happened due to the following changes. I am posting it here anyway, as there are still new views and votes, so it may be valuable for others:

That was the change:

In ./shared/tsconfig.json contents

I added

{
   "outDir": "./lib/",
   ...
   "rootDir": "./src",
}

to give:

{
    "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",
    ]
}
Vinia answered 16/5, 2019 at 15:20 Comment(1)
I needed: {"outDir": "./lib/", "rootDir": "./src"} – Gratulation
P
51

Found this when searching for "typescript references has not been built from source file". My mistake was that I was running tsc -p tsconfig.json when I should've been using the --build flag: tsc --build tsconfig.json. If you run with -p TypeScript will not build the referenced projects. Only if you run with --build.

Peloquin answered 14/1, 2021 at 11:35 Comment(0)
V
9

I solved it little after my last activity here, but i wasn't 100% sure if that happened due to the following changes. I am posting it here anyway, as there are still new views and votes, so it may be valuable for others:

That was the change:

In ./shared/tsconfig.json contents

I added

{
   "outDir": "./lib/",
   ...
   "rootDir": "./src",
}

to give:

{
    "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",
    ]
}
Vinia answered 16/5, 2019 at 15:20 Comment(1)
I needed: {"outDir": "./lib/", "rootDir": "./src"} – Gratulation
P
8

I arrived here trying to solve a "has not been built from source file" error. Turned out a tsc watch process hadn't properly exited, so I had two instances fighting over the files. Just in case anyone else runs into the same issue πŸ˜€

Primalia answered 24/9, 2020 at 10:35 Comment(0)
P
3

I'm able to reproduce the errors you get if I have an errant tsconfig.json in the directory that contains front, back and shared. In this case running tsc -b will pick up the errant tsconfig.json in the current directory and since it is not configured with the right paths or anything else, the compilation fails with the same errors you get.

Otherwise, if I use your files and issue tsc -b front instead of tsc -b, it compiles without error.

The reason VSCode does not run into trouble is that in order to provide completion, TypeScript editors (normally) use a tool provided by TypeScript called tsserver. And when an editor gives a file path to tsserver, tsserver gets a relevant tsconfig.json by looking in the directory that contains the source file, and then up into the parent directory, and so on, until it finds a tsconfig.json file. So when VSCode works on front/src/foo.ts and asks tsserver to provide completion, tsserver looks in front/src which has no matching file, and then front, and finds the tsconfig.json there.

Pugging answered 14/3, 2019 at 20:50 Comment(3)
I don't have a tsconfig.json file in ./ folder. Updated question a bit. – Vinia
If you have a tsconfig.json file higher in the directory hierarchy it would also be picked up. – Pugging
There isn't in any level – Vinia
A
2

It seems that this error can be caused by many things. For me the problem was that I deleted the output directory in the shared project without deleting the tsconfig.tsbuildinfo file. It seems that this file is some sort of cache to prevent referencing projects from rebuilding the shared project.

Agna answered 26/11, 2022 at 4:29 Comment(1)
tsconfig.tsbuildinfo is such a pain, it's always doing this to me. What's the point of caching anything if you simply need to delete it all the time to get anything to work! – Convincing
I
1

This totally doesn't answer your question directly, but I feel it might still be useful to offer an alternative.

One way to solve this in a 'more standard' fashion, would be to make your 3 codebases all an NPM package.

This way your import would be something like @vendor/shared/foo instead of ../../../../shared/src/article.

Using npm link it's easy to work on a project cross-dependency.

You don't technically even need to modify your source structure (although maybe you want to). The shared dependency just gets softlinked via node_modules.

Interknit answered 14/3, 2019 at 17:11 Comment(5)
As an advice, I should say that using npm link is not always the best way to go. I've found some issue since symbolic links are used, and so dependencies cannot be flattened, leading to differences between final build and development. It's a cool tool sure for development, but not always the best solution. Just my two cents! – Gladine
@Gladine that's good to know! Usually having 'npm link' on is a temporary state for me until I can stop doing cross-repo development. I can definitely see that that can become an issue. – Interknit
I try to use yalc for local development, It works like npm link, has flattening support and a nice watch mode, I suggest it! – Gladine
@Gladine - "... symbolic links are used, and so dependencies cannot be flattened" needs a little more explanation to make sense. Symbolic links enable dependencies to be flattened - that's the whole point. There is one caveat - at least for yarn - links for bin executables are not created during "yarn install [--offline] [--force]" unless the path in package.json::"bin{name:path}" actually exists. To get around that "yarn install [--offline] [--force]" must be called again after compilation has completed successfully, before the executables are called. – Rhaetian
This answer is vastly underrated. – Rhaetian
G
1

If you are compiling from root folder, try to add a local tsconfig.json file with all references set up, i.e. references: { path: './shared' }. Otherwise, tsc will not find relevant project to build.

Furthermore not having a root tsconfig.json will not allow VSCode GUI to work properly as it looks for root tsconfig.json (this is the state last time I checked it, here you can find the related issue).

The error seems to be related to missing file. If you can provide further details about the building steps you take, I can try to check it better

Gladine answered 15/3, 2019 at 14:57 Comment(0)
P
0

Check to Make Sure You Have a .tsconfig File in the Referenced Directory

This error will also occur if the .tsconfig file does not exist in the target directory. The error message is misleading as the directory can exist but gives you an impression it cannot find it.

Also, if "composite": true is not present in the .tsconfig file you will get another error.

Powers answered 2/11, 2023 at 14:32 Comment(0)

© 2022 - 2024 β€” McMap. All rights reserved.