Describe the bug
Version: 7.1.0
To Reproduce
I don't have a fully isolated repro yet. But here is the diff I'm working with:
before:
const tsconfigOptions = {
...compilerCacheOptions,
...layout.tsConfig.content.options,
outDir: layout.build.tsOutputDir,
}
const builder = ts.createIncrementalProgram({
rootNames: layout.nexusModules.concat(layout.app.exists ? [layout.app.path] : []),
options: tsconfigOptions
})
const errors = project.getPreEmitDiagnostics() // is fine
after:
const tsconfigOptions = {
...compilerCacheOptions,
...layout.tsConfig.content.options,
outDir: layout.build.tsOutputDir,
}
const project = new tsm.Project({
compilerOptions: tsconfigOptions,
})
project.addSourceFilesAtPaths(layout.nexusModules.concat(layout.app.exists ? [layout.app.path] : []))
const errors = project.getPreEmitDiagnostics() // has a diagnostic error
unexpected diagnostic error happened with after case:
[
Diagnostic {
_context: ProjectContext {
logger: [ConsoleLogger],
manipulationSettings: [ManipulationSettingsContainer],
_project: [Project],
fileSystemWrapper: [TransactionalFileSystem],
_compilerOptions: [CompilerOptionsContainer],
compilerFactory: [CompilerFactory],
inProjectCoordinator: [InProjectCoordinator],
structurePrinterFactory: [StructurePrinterFactory],
lazyReferenceCoordinator: [LazyReferenceCoordinator],
directoryCoordinator: [DirectoryCoordinator],
_languageService: [LanguageService]
},
_compilerObject: {
file: undefined,
start: undefined,
length: undefined,
messageText: "Cannot find type definition file for 'fs'.",
category: 1,
code: 2688,
reportsUnnecessary: undefined
}
}
]
Expected behavior
Can seamlessly transition from ts.createIncrementalProgram to new tsm.Project.
I suspect this isn't a bug but incorrectly ts-morph usage on my part 🤔 .
Some similarity between error here and error seen there -> https://github.com/dsherret/ts-morph/issues/534#issuecomment-468935987
I upgraded to version 1.7.2 but no effect.
I set some settings explicitly but no effect:
const project = new tsm.Project({
compilerOptions: tsconfigOptions,
tsConfigFilePath: layout.tsConfig.path,
skipLoadingLibFiles: false,
skipFileDependencyResolution: false,
addFilesFromTsConfig: true,
})
If I simplified the nexus app to an app.ts with console.log('hi') then the error does not occur.
This also works ok import 'fs' (showing that I cannot repro the fs error based on local import of fs).
The error does occur when nexus is imported, even just import 'nexus'.
Some things to try here maybe https://github.com/microsoft/TypeScript/issues/27956
when I stub the fs module with local typings (and tsconfig typeRoots config to point to it) in the Nexus app, it works:
❯ stat types/fs/index.d.ts
16777220 92453754 -rw-r--r-- 1 jasonkuhrt staff 0 0 "Jul 19 14:04:24 2020" "Jul 19 14:04:24 2020" "Jul 19 14:04:24 2020" "Jul 19 14:04:24 2020" 4096 0 0 types/fs/index.d.ts
nexus imports all sorts of packages from the node stdlib. I don't know why fs specifically is having issues.
It is in the node typings like it ought to be:
❯ stat node_modules/@types/node/fs.d.ts
16777220 92028119 -rw-r--r-- 1 jasonkuhrt staff 0 112327 "Jul 18 21:29:33 2020" "Jul 18 21:29:33 2020" "Jul 18 21:29:54 2020" "Jul 18 21:29:33 2020" 4096 224 0 node_modules/@types/node/fs.d.ts
I tried digging into the implementation. There's a lot going on. Can't really make a simple comparison to how we were using createIncrementalProgram before.
I removed every import of fs in the nexus codebase. No effect.
I have been incrementally removing code and discovered that having the return type here be any fixes things:
I don't know why.
Investigating further.
It looks like it's not resolving the node_modules/@types/node folder. It may indeed have something to do with the cwd.
If you can provide a repo that I could clone that reproduces the problem then I could take a look at what's going on.
Hey @dsherret! Here you go: https://github.com/graphql-nexus/examples/tree/repro/tsm-fs/hello-world.
Will post back any more useful findings I have as I try to make the repro more minimal (mostly on the side of that nexus branch).
Interestingly, I'm able to reproduce this with @ts-morph/bootstrap:
const { createProjectSync, ts } = require("@ts-morph/bootstrap");
const project = createProjectSync({
tsConfigFilePath: "./tsconfig.json"
});
console.log(ts.getPreEmitDiagnostics(project.createProgram()));
Also with ts-morph directly:
const { Project } = require("ts-morph");
const project = new Project({
tsConfigFilePath: "tsconfig.json"
});
console.log(project.getPreEmitDiagnostics());
However, I was not able to reproduce this with the compiler API directly:
const ts = require("typescript");
const configJson = ts.parseConfigFileTextToJson("tsconfig.json", ts.sys.readFile("tsconfig.json")).config;
const compilerOptions = ts.convertCompilerOptionsFromJson(
configJson.compilerOptions,
ts.sys.getCurrentDirectory(),
).options;
console.log(compilerOptions);
const program = ts.createProgram(["./api/app.ts"], compilerOptions);
console.log(ts.getPreEmitDiagnostics(program));
There's probably some bug in @ts-morph/common somewhere... maybe with the hosts...
For debugging this, it would be good to use the @ts-morph/bootstrap example I gave and then figure out where in the typescript compiler it creates the diagnostic then work back from there to figure out why that's happening. I can look at this later.
Ok, I found the problem... silly mistake. Will publish a fix soon.
@jasonkuhrt ok, this is fixed and published in 7.1.3. Thanks for reporting it!
@dsherret yup that did the trick! Thanks so much, your work generally and help here are deeply appreciated!
We're getting close to having nexus built atop just ts-mprph.