rootDir not respected
Given rootDir (or lack thereof) is not respected during compilation, this essentially breaks relative paths that traverse outside of the current directory.
BUILD
ts_project(
name = "current-dir",
srcs = ["current-dir.ts"],
deps = [
"//src/outside/root-dir",
"//src/outside/current-dir/inside/root-dir",
],
tsconfig = "//:tsconfig",
....
)
current-dir.ts
// works
import { something } from './inside/root-dir';
// fails with: somethingElse is outside of the configured 'rootDir'
import { somethingElse } from '../outside/root-dir';
tsconfig.json (@ root)
{
"compileOnSave": false,
"exclude": ["bazel-*"],
"compilerOptions": {
"rootDir": "."
}
}
This occurs because in ts_project.bzl it assigns rootDir via _lib.calculate_root_dir(ctx):
https://github.com/aspect-build/rules_ts/blob/main/ts/private/ts_project.bzl#L62
calculate_root_dir essentially assigns rootDir to package_name() + given ctx.attr.root_dir
I would expect that rootDir should be exactly what is given in the tsconfig.json or omitted from the command if not provided.
AFAIK this is by design. Essentially, ts_project is a tsc wrapper that passed just enough information to make tsc behave the right way under bazel. If you omit root_dir attribute, then ts_project will generate one to prevent tsc from including anything outside of rootDir as a source. I believe this is the reason behind auto-generated rootDir but @alexeagle might know more.
I would expect that
rootDirshould be exactly what is given in thetsconfig.jsonor omitted from the command if not provided.
This is not possible due to how bazel works. It is not possible to read files during analysis phase, therefore ts_project can't tell if the tsconfig.json has a rootDir already. that's why you have to provide the rootDir attribute.
If you omit root_dir attribute, then ts_project will generate one to prevent tsc from including anything outside of rootDir as a source
tsconfig.json is passed to tsc so it should be able to infer the rootDir as-is?
This is not possible due to how bazel works. It is not possible to read files during analysis phase, therefore ts_project can't tell if the tsconfig.json has a rootDir already. that's why you have to provide the rootDir attribute.
I see, makes sense but, explicitly setting root_dir just appends to the generated rootDir instead of replacing it
I see, makes sense but, explicitly setting root_dir just appends to the generated rootDir instead of replacing it
The ts_project(root_dir) gets appended to the directory of the ts_project rule (the directory of the BUILD file). So yes it is relative just like executing tsc in the folder of the BUILD. Bazel will have the extra restriction that the rootDir must still be within the directory that the BUILD owns - you can't tell ts_project to access files it does not own.
You can't tell
ts_projectto access files it does not own.
I'm confused, it's a dependency. This is the same concept as referencing an npm package, that path should, and does, exist on disk. The rootDir is a virtual path relative to the tsconfig.json, if I run tsc by passing in a tsconfig.json in that BUILD folder it would actually infer the rootDir the longest common path of all non-declaration input files relative to the tsconfig.json dir.
You can even bypass the behaviour by specifying paths in the tsconfig.json and call it via the alias eg:
import { somethingElse } from '@outside/root-dir;
rules_ts passes the --rootDir cli arg 100% of the time so the tsconfig.json rootDir and default inferred path will never be used.
The ts_project(root_dir) is relative to the BUILD its in just like the tsconfig one is relative to the tsconfig and --rootDir is relative to the cwd etc.
Note that rootDirs might do what you're trying to? Those 2 are different and very awkwardly named though.
@pullard Do you feel that your question has been answered?
Oh sorry, @cgrindel, yes this is satisfactory solution!