Typescript: What is "rootNames" in "createProgram()" API / Non-root modules are skipped from compilation

Created on 18 Feb 2019  ·  6Comments  ·  Source: microsoft/TypeScript

Hey guys, thank you for your hard work and everything!

I hope it's OK to ask questions about TypeScript API here, due to the lacking documentation and it's complexity.

I'm working on a custom build tool and I'm trying to call TypeScript compiler directly to compile source code. However, the examples in documentation doesn't explain much regarding the loading/parsing the configuration files, so I've tried to figure out it myself, using examples from other similar projects.

My question is regarding the createProgram() function. I'm trying to mimic the tsc behavior. In tsconfig.json documentation there are only files, include and exclude options and there is nothing about a root names. What exactly should I put into this argument?

I have many files in my project and not everything is available through the root index.ts module. I have individual modules like src/*.spec.ts for tests as well. However, if I put index.ts into rootNames, then only modules resolved from index.ts is emitted, but all other individual files are just omitted from the compilation for some reason.

Could you explain a bit, how should I call the compiler in order to process all files mentioned in include array and not only the root files and their dependencies?

Here's the code I use right now for compilation:

  const extraCompilerOptions: CompilerOptions = {
    typeRoots: [
      `${options.projectDir}/node_modules/@types`,
      `${options.projectDir}/types`
    ],
    outDir: options.outputDir,
    declarationDir: options.declarationsOutputDir
  };

  const readConfig = typescript.readConfigFile(options.tsConfigPath, typescript.sys.readFile);

  // I'm adding include/exclude properties externally
  Object.assign(readConfig.config, {
    include: options.include,
    exclude: options.exclude,
  });

  const parsedConfig = typescript.parseJsonConfigFileContent(
    readConfig.config,
    typescript.sys,
    dirname(options.tsConfigPath),
    extraCompilerOptions
  );

  const program = typescript.createProgram(['index.ts'], parsedConfig.options);
  const emitResult = program.emit();

Maybe I'm missing some important bits? Any suggestions will be highly appreciated, thanks!

Question

Most helpful comment

When calling tsc inside the project directory, performCompilation is called with configParseResult.fileNames.

configParseResult is built with parseConfigFileWithSystem > getParsedCommandLineOfConfigFile > parseJsonConfigFileContentWorker > getFileNames.

Try building tsc yourself and putting a breakpoint in getFileNames to see how it is traversing the directory.

All 6 comments

When calling tsc inside the project directory, performCompilation is called with configParseResult.fileNames.

configParseResult is built with parseConfigFileWithSystem > getParsedCommandLineOfConfigFile > parseJsonConfigFileContentWorker > getFileNames.

Try building tsc yourself and putting a breakpoint in getFileNames to see how it is traversing the directory.

Thanks @agentcooper for internals explanation. However, could you also explain from the conceptual point of view, what should go to the rootNames (from the compiler API standpoint) and why I'm experiencing the result where only root modules are compiled. Do I need to resolve all modules manually and pass them as rootNames or something?

configParseResult.fileNames ends up getting passed as rootNames

@RyanCavanaugh I see, but was is relation between include/exclude/files and rootNames? How does it all works together?

include, exclude, and files are all tsconfig-only things that work together to produce a set of rootNames.

Yes, that was my though. However, what confused me is that include and exclude is affecting the compilation process as well, so it must be not only used to construct rootNames?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

fwanicka picture fwanicka  ·  3Comments

siddjain picture siddjain  ·  3Comments

weswigham picture weswigham  ·  3Comments

Roam-Cooper picture Roam-Cooper  ·  3Comments

dlaberge picture dlaberge  ·  3Comments