Open aleclarson opened 5 years ago
Currently we treat sourceRoot
as a verbatim path, so that you can control what the source map's final sourceRoot
should be if you are deploying these files to another location, i.e.:
{
"compilerOptions": {
"sourceMap": true,
"sourceRoot": "https://foo.com/debug/sourcemaps/"
}
}
However, we could change this to identify absolute paths and URLs and keep those verbatim. We don't currently use the sourceRoot
for any path calculations when generating source maps, but this change could be a breaking change for some users.
@aleclarson: You can work around this by specifying the following in your tsconfig.json:
{
"include": ["src"],
"compilerOptions": {
"baseUrl": ".",
"outDir": "dist",
"sourceMap": true,
"sourceRoot": "../src"
}
}
@RyanCavanaugh, @DanielRosenwasser: I am concerned this could be a breaking change for some users. Do we want to pursue changing the behavior of sourceRoot
, or perhaps introduce a sourceRootDir
option that can be used instead of sourceRoot
and performs the correct relative path calculation (with the Dir
suffix indicating that we're talking about an actual file system directory)?
This is an issue for anyone using a monorepo with Typescript. Unless the definition of a function/class/type is directly in the index.ts file of the referenced module, then "go to definition" functionality lands inside a .d.ts file instead.
As far as a breaking change, could this be resolved by detecting the value is a URL and then NOT putting relative paths into the map files?
This also breaks debugging in, at least, VSCode as it is unable to resolve the source -> JS mappings when the map files have a "sourceRoot".
We have had to remove "sourceRoot" from the project being debugged (we have yet to evaluate any other side effects) but we cannot debug other modules from within the same mono-repo which are being used by that project.
Can we get confirmation of a work-around or that this will actually be in 4.1.0? This issue has been pushed off for over a year and it's crippling to our development team.
I discussed this with the team. To support this without introducing a breaking change we will have to add a sourceRootDir
option to specify a path that should be:
tsconfig.json
(similar to rootDir
/outDir
)sourceRoot
option (they are mutually exclusive)It appears the "fix" is not to use "sourceRoot" when sources are on the local filesystem and only use it when source will be hosted. VSCode now correctly finds the original source both when editing and when debugging.
The documentation lead us to believe that we had to have "sourceRoot" set in order for mappings to be correct but it's actually the opposite.
Is the solution expected to be implemented in TypeScript 4.2.0?
The solution, for us, was to remove "sourceRoot" from tsconfig.json. All the map files are now generating with the correct paths.
What I would like to see is a clarification of the documentation as to when/why you would use sourceRoot (ie. only when hosting the source at an absolute location like a URL).
The solution, for us, was to remove "sourceRoot" from tsconfig.json. All the map files are now generating with the correct paths.
What I would like to see is a clarification of the documentation as to when/why you would use sourceRoot (ie. only when hosting the source at an absolute location like a URL).
As I've said before, we treat sourceRoot
as a verbatim path and don't do any path resolution for it. It should only really be used when its pointing to an absolute URL or some other absolute path that might be defined as part of your build process. We won't be changing the behavior of sourceRoot
as that would be a breaking change. While we are considering adding something like sourceRootDir
, it likely won't make it for 4.2 due to holiday schedules.
Thanks for clarifying. I am expecting something like sourceRootDir
. Hope it will come to real soon.
@rbuckton @RyanCavanaugh @andrewbranch any estimate around when this new sourceRootDir
feature will be available? I'm using Bazel to build packages in a monorepo and it is really important for us to have this flag so we can control the source files locations in relation to the sourcemaps location correctly. At the moment our IDE features when click and following implementation for those packages are only working for files in the top level folders as whatever we set in the sourceRoot
, even if it is a relative path, will be immutable and not correctly changed for nested folder files.
@RyanCavanaugh this issue keeps being postponed for a long time. Is there anyway to prioritise it 😃 ? It is blocking us in a monorepo with Bazel and I believe it is also affecting others in the same setup too.
I will restate, one last time: we removed "sourceRoot" from our configuration and the files all generated with the correct roots. It is evident that "sourceRoot" should only be used when hosting your map files on a web-site.
We have a monorepo with 60+ packages. Most of those packages have the following structure:
src\ - Typescript source
dist\ - Javascript output, maps, .d.ts files, and assets
This works for debugging, VSCode link following, and everything else we've tried.
Our initial issue was a misunderstanding of when to use "sourceRoot" which appears to only be when you're placing the .map, .d.ts, etc. files in a completely separate location. I can't think of a reason to do that except to host the files on a web-site.
IMO - the only issue here is documentation.
@raijinsetsu thanks for the inputs here. I actually know what you mentioned and confirm this. However our use case is different. When using Bazel, the compilation happens in a sandbox in a temporary location. The build contents are then located outside of the repo and symlinks are created. I really need the option to control the 'sourceRoot' content, which we have at the moment, but the relative path is not correctly calculated for nested files/folders under the package root. We need to patch that behaviour on sourceRoot
or introduce the new param the sourceRootDir.
@raijinsetsu thanks for the inputs here. I actually know what you mentioned and confirm this. However our use case is different. When using Bazel, the compilation happens in a sandbox in a temporary location. The build contents are then located outside of the repo and symlinks are created. I really need the option to control the 'sourceRoot' content, which we have at the moment, but the relative path is not correctly calculated for nested files/folders under the package root. We need to patch that behaviour on
sourceRoot
or introduce the new param the sourceRootDir.
Would that not be fixed by putting the symlink in the same relative location to the src folder as it is within the sandbox?
Sandbox: /src /lib
Repo: /src /lib -> SANDBOX/lib
@raijinsetsu we don't have that level of control on Bazel and honestly I dont want to create a new symlink for each package target folder. Developing on windows is already slower and symlinks/junctions there are always painful. What we really need is that sourceRoot behaves like rootDir
and calculates the nested relative paths correctly accordingly the value passed on the setting. In alternative a new sourceRootDir param will also work okay! 😃
This one's been around a long while and we haven't yet seen the quantity of feedback that would justify further complicating the file resolution process.
@mistic just curious if you found any workaround? Also in need for relative workspace source root paths.
@tinganho I endup implementing a custom Typescript types summariser with sourcemaps support that runs over the d.ts
files and produces a single output. Then the sourcemaps correctly generated for this summary
will allow the IDE to correctly map the point and click. However I'm now thinking about pivoting from this approach and just run the typecheck on the IDE over the sources and thats it. Only CI will run the typecheck step out from the sources
Thanks @mistic for your answer.
@RyanCavanaugh do you accept PR on this or still awaiting feedback? I think this blocks Bazel IDE debugging adoption for TypeScript atm.
Also on the last point on @rbuckton proposal:
- Cannot be used in combination with the sourceRoot option (they are mutually exclusive)
First, I have hard time seeing a use case for verbatim sourceRoot
alone? Unless, you have a single folder with source files, on your entire project? Second, isn't there a use case of combining sourceRoot
+ sourceRootDir
, for instance to create http://localhost/sourcemaps/[workspace_path_to_source_file]
, where sourceRoot
is http://localhost/sourcemaps/
and sourceRootDir
is .
(project root)?
fwiw, my initial thought was that sourceRoot
was behaving as the proposed sourceRootDir
.
This would be really needed when working with a monorepo utilising workspaces. Consider the scenario where root/packages/a
contains an src
and build
folder. But root/packages/a
is symlinked into root/node_modules/@my_org/a
.
Whenever any other package uses @my_org/a
the files will be loaded from root/node_modules/@my_org/a/build/*
.
Without sourceRootDir
a debugger has no idea that for root/node_modules/@my_org/a/build/*
the sources should be located in root/packages/a/src/*
.
Right now the only solution is to set sourceRoot
to the absolute path of each package's src
folder.
However, how such configuration is supposed to be manageable? We cannot commit local absolute paths into a repo, it would collide with everyone else's setup. Another approach could be to use the --sourceRoot
CLI parameter and use pwd
to set the correct absolute path for builds. It can be rather convenient if configured in package.json
scripts.
... As long as you don't use references, because than this setup will be broken for all the dependent packages (even if the --sourceRoot
CLI param is taken into account or not).
So if someone is using some external monorepo tools, like Nx or so, they can manually configure appropriate scripts for each packages and rely on the tool to trigger rebuild of dependent packages.
But with references it is not suitable.
Right now as a workaround we have a root level script in place that auto-generates a tsconfig.build.local.json
for every package, extending tsconfig.build.json
, but overriding sourceRoot
to the actual absolute path. We have tsconfig.build.local.json
on .gitignore
, so the setup works for everyone regardless of the local path on their machine. But it is not elegant...
We need a solution that is not copied verbatim, like compilerOptions.sourceRoot
, but instead would be processed by tsc
and adjusted for each sub-folder level in the package. So setting that setting to "../../../../packages/a/src/"
would mean:
sourceRoot
in the sourcemap of root/node_modules/@my_org/a/build/index.js
would be "../../../../packages/a/src/"
pointing correctly to root/packages/a/src
, andsourceRoot
in the sourcemap of root/node_modules/@my_org/a/build/foo/index.js
would be "../../../../../packages/a/src/"
(one more ../
!) still pointing correctly to root/packages/a/src
, and so on.Indeed we have to acknowledge that in this case the sourcemaps inside root/packages/a/build
are pointing to a non-existent location, but since files would never run from this location it is fine.
TypeScript Version: 3.5.1
Search Terms: sourceRoot, sources, sourcemap
Code
Create a module like:
src/nested/foo.ts
Use the following
tsconfig.json
with tsc:Expected behavior:
Inside
nested/foo.js.map
, thesourceRoot
should be../src/
instead ofsrc/
. Otherwise, the paths in thesources
array cannot be found.Actual behavior:
The
sourceRoot
issrc/
regardless of nesting.Playground Link: N/A
Related Issues: None