rules_nodejs icon indicating copy to clipboard operation
rules_nodejs copied to clipboard

Proposal: ambient_srcs and declared_modules

Open DavidANeil opened this issue 5 years ago • 0 comments

Current

Currently ts_library generates a tsconfig file that contains all of the transitive inputs in the "files" attribute. When tsc encounters this attribute it is forced to load, parse, and bind the source file.

Proposal

The core of this proposal is to simply not do that. By only including the current project's sources in "files" then tsc will automatically resolve imports to discover new files, then only those used files will be loaded from disk.

Most projects would not compile under that scheme. To create a workaround for this breaking change, two new attributes will be added to ts_library and js_library: ambient_srcs and declared_modules

ambient_srcs is a list of sources that contain ambient type declarations, which means they neither import nor export any types. These are things such as @types/node/globals.d.ts, they affect the global scope simply by being loaded. All ambient_srcs of deps (TODO: direct or transitive?) will always be included in the "files" attribute, so that they can affect the global scope.

declared_modules is a string_list_dict that contains a mapping from "module-name" to any source files that declare that module. Each entry in declared_modules will be added to "paths" attribute of tsconfig. This allows source declaration files that only declare modules to be loaded lazily as a regular entry in srcs rather than eagerly as ambient_srcs. Declared modules are a type of ambient declaration that do not affect the global type scope, only the import scope. That is, if @types/node/fs.d.ts has been loaded with its

declare module "fs"

then tsc will know to resolve an import from "fs" to the type information in that declared module. Instead of relying on the file already being loaded, declared_modules allows us to put an entry in the "paths" attribute of the tsconfig to teach the compiler how to resolve the import.

Unblocks

Since this saves tsc from needing to open every source fill of every transitive dependency this unblocks the usage of unused_inputs_list which can drastically reduce the action graph in many real-life use cases.

Results

In practice the above changes have reduced build times for one of our applications from ~2200s to ~1000s. Adding unused_inputs_list further decreases that down to 7s when making changes to a file that is not depended on.

DavidANeil avatar Nov 16 '20 20:11 DavidANeil