You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Calculation of paths in the “sources” field of source-maps generated by tsc #1513
I was recently compiling TypeScript files into JavaScript using tsc with the --sourcemap option set. And I noticed that the paths in the "sources" field of the generated source-map changed in different ways depending on how I set the --sourceRoot option. I always used the absolute path of the TS files when compiling. So here are the different scenarios I was getting:
When I don't supply the --sourceRoot option, I get a source-map that has only the filename in the "sources" field. And, the "sourceRoot" field is empty.
When I supply / or any other value as the --sourceRoot option, then I get a source-map where the "sourceRoot" field is appropriately set, but the value of the "sources" field is some relative path to the TS file.
And it seems that the relative path doesn't follow any trend when I checked with different files. But most importantly, this behavior is only present when I tried to compile an individual TS file that has references to external modules. I was not able to reproduce it with a simple TS file that doesn't have any references. In the case of a simple TS file, it didn't matter how I passed the --sourceRoot option. The "sources" field only had the filename as the value. And in addition, the "soruceRoot" was set to the respective value.
So the only assumption I was able to make is that this path in the "sources" field is affected when the TS file to be compiled is referencing other external modules. I would appreciate any help in regards to this problem I am having. How is the value of the "sources" field computed when the source-map is generated?
I dug around the source code and found out how the file paths are set. The following method in sourceMapping is where it happens:
privatesetNewSourceFilePath(document: Document,emitOptions: EmitOptions){vartsFilePath=switchToForwardSlashes(document.fileName);if(emitOptions.sourceRootDirectory()){// Use the relative path corresponding to the common directory pathtsFilePath=getRelativePathToFixedPath(emitOptions.commonDirectoryPath(),tsFilePath);}else{// Source locations relative to map file locationtsFilePath=getRelativePathToFixedPath(this.sourceMapDirectory,tsFilePath);}this.tsFilePaths.push(tsFilePath);}
So it looks like when the sourceRoot is available, a common directory path for all the files to be compiled is computed and then the relative path from this computed path to the tsFile is used as the value of the sources field in the source-map.
It currently entails so long as a source root is provided, the sources field of the source-map will always vary depending on the respective paths of the files to be compiled. Is there any way we can add some form of flexibility to this method here? (e.g. using some constant parameter to use as reference to the relative path calculation)
Depending on whether you supplied --souceRoot, sourceRoot field in source map will either be the string provided or empty.
When the sourceRoot is specified, the sources has entry to ts file that is relative to common sources directory. Hence --sourceRoot is designed for correct access to sources in case you want to notify debugger where to find sources for the source map you are debugging.
If --sourceRoot is not specified, the sources are just the relative paths to current directory but if --mapRoot is specified they are relative path to the source map directory specified.
I understand that part, but the issue I am having is with the calculation of the common sources directory. Let us say I am selectively compiling TS files and those TS files are lower modules and found very low in the folder hierarchy. So as it stands if I compile these files alone, I get different sources entry in their maps as opposed to the output I would be getting when compiling them with higher modules (on a higher hierarchy). N.B. The projects that I have is set up in a way where these lower module files don't have references to the higher modules and they don't need to as they're just some plugins. I was hoping to find a way where I can set the sources entry of the TS files map relative to a preferred root directory instead of using a common source directory of the to-be-compiled files.
Yonathan Negussie Mengesha (@ymengesha) what about using tsconfig.json (#1667)? this will allow you to set the root of your project, and it does not matter where you start your tsc process, it will pick up the correct roots?
Just for the record, we're also having this issue in TouchDevelop. Because it's a large project, we invoke tsc per-folder, so that if one touches a folder high enough in the folder dependency graph, only a few tsc calls are needed. (We then concatenate files.)
Some of our folders don't have "big enough" dependencies to trigger the right "common folder" computation. The proposed solution with tsconfig.json would be great for us.
(Granted, I assume I could generate a fake dependency just to get the desired result, but that sounds fairly hackish!)
Activity
RyanCavanaugh commentedon Dec 17, 2014
I think Sheetal Nandi (@sheetalkamat) can explain what happens here.
ymengesha commentedon Jan 2, 2015
I dug around the source code and found out how the file paths are set. The following method in sourceMapping is where it happens:
So it looks like when the
sourceRootis available, a common directory path for all the files to be compiled is computed and then the relative path from this computed path to the tsFile is used as the value of thesourcesfield in the source-map.It currently entails so long as a source root is provided, the
sourcesfield of the source-map will always vary depending on the respective paths of the files to be compiled. Is there any way we can add some form of flexibility to this method here? (e.g. using some constant parameter to use as reference to the relative path calculation)sheetalkamat commentedon Jan 9, 2015
Depending on whether you supplied --souceRoot, sourceRoot field in source map will either be the string provided or empty.
When the sourceRoot is specified, the sources has entry to ts file that is relative to common sources directory. Hence --sourceRoot is designed for correct access to sources in case you want to notify debugger where to find sources for the source map you are debugging.
If --sourceRoot is not specified, the sources are just the relative paths to current directory but if --mapRoot is specified they are relative path to the source map directory specified.
ymengesha commentedon Jan 12, 2015
I understand that part, but the issue I am having is with the calculation of the common sources directory. Let us say I am selectively compiling TS files and those TS files are lower modules and found very low in the folder hierarchy. So as it stands if I compile these files alone, I get different sources entry in their maps as opposed to the output I would be getting when compiling them with higher modules (on a higher hierarchy). N.B. The projects that I have is set up in a way where these lower module files don't have references to the higher modules and they don't need to as they're just some plugins. I was hoping to find a way where I can set the sources entry of the TS files map relative to a preferred root directory instead of using a common source directory of the to-be-compiled files.
ymengesha commentedon Jan 29, 2015
Sheetal Nandi (@sheetalkamat) Do you have any suggestions / tips regarding this ?
sheetalkamat commentedon Jan 30, 2015
I dont think currently there is any way to specify common source directory to the compiler. Mohamed Hegazy (@mhegazy) jonathandturner do you think of anything?
mhegazy commentedon Jan 30, 2015
Yonathan Negussie Mengesha (@ymengesha) what about using tsconfig.json (#1667)? this will allow you to set the root of your project, and it does not matter where you start your tsc process, it will pick up the correct roots?
msprotz commentedon Feb 10, 2015
Just for the record, we're also having this issue in TouchDevelop. Because it's a large project, we invoke tsc per-folder, so that if one touches a folder high enough in the folder dependency graph, only a few tsc calls are needed. (We then concatenate files.)
Some of our folders don't have "big enough" dependencies to trigger the right "common folder" computation. The proposed solution with
tsconfig.jsonwould be great for us.(Granted, I assume I could generate a fake dependency just to get the desired result, but that sounds fairly hackish!)
Add a new project root option (fixes microsoft#1513).
mhegazy commentedon Apr 21, 2015
We have recently added --rootdir option to solve this
ymengesha commentedon Apr 21, 2015
Thank you guys!