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
tsc does not support transforming absolute module paths into relative paths for modules located outside node_modules. In client side apps, this is often not an issue because people tend to use Webpack or similar tool for transformations and bundling, but for TypeScript apps targeting Node.js, this is an issue because there is usually no need for complex transformations and bundling, and adding additional build steps and tools on top of tsc only for path transformation is cumbersome.
Example input (es2015 style):
import{myModule}from'myModuleRoot/a/b/my_module';
Example output (CommonJS style):
constmyModule=require('./a/b/my_module');
My personal opinion is that relative module paths (import { ... } from '../../xxx/yyy';) are an abomination and make it difficult to figure out and change application structure. The possibility of using absolute paths would also be a major benefit of using TypeScript for Node.js apps.
My personal opinion is that relative module paths (import { ... } from '../../xxx/yyy';) are an abomination and make it difficult to figure out and change application structure.
While I heartily agree with your sentiment, I think rewriting such imports would open up a can of worms that would ultimately break or complicate an insanely large number of tools and workflows that rely on the emitted JavaScript using the same module specifiers. Even under a flag, I think it will introduce a lot of complexity.
I hate relative paths that go up, it is just awful for maintainability, but my two cents is that this needs to be done on the NodeJS side, not the transpiler side. Of course it's extremely unlikely that will ever happen...
Reacted by Vasiliy Telyatnikov, Nathan Floris Copier, Alex and Raphael Schweikert
Reacted by Luke Tanner, Rafael Vidaurre, Samuel Oloruntoba, ivibe, PendletonJones, 小池貴之, Nick Laros, Jacob Smith, menya, Andrey Rublev and 129 more
Reacted by Badeline and KCM
Reacted by Towrabbit, Igor, Icheka Ozuru, Gabriele Tomberli, Badeline and TomN
Aluan Haddad (@aluanhaddad) I've been using path rewrite (Webpack) on client-side since I began writing React apps. How would it cause problems on the server side if it doesn't cause problems on the client side? Editors already support setting module roots, and linters (ESLint, TSLint) seem to be fine also.
To the maintainers of TypeScript: Please add support for custom module roots so that we can get rid of the awful and unmaintainable import paths.
Reacted by Luke Tanner, Stefan Knoch, Michael Fry, PendletonJones, 小池貴之, Nick Laros, Jacob Smith, SGrajdean, Patrick Geyer, Rameş Aliyev and 45 more
ikokostya Many tools have special treatment for node_modules, and it is always treated as a folder for external code. Putting app code into node_modules may solve the import path problem, but introduces potential other problems. It is also ugly solution that shouldn't, in my opinion, be recommended to anyone.
Reacted by Luke Tanner, Peng Qi, Nick Laros, Pavel Ravits, Ivan Wang, Lebogang Mabala, Nathan Harris, Cole Jancsar, zak sesti, Fearnbuster and 18 more
@Kitanotori perhaps I misunderstood your suggestion, TypeScript supports this feature with the --baseUrl flag.
My point was that NodeJS doesn't support it and that TypeScript should not attempt to provide the future on top of NodeJS by rewriting paths in output code.
There are too many to count but TypeScript is definitely an example of such a tool.
I think putting application code in a node_modules folder is a very ill-advised hack.
Reacted by Raymond Tijhaar, Ronald Suwandi, jurajkocan, Thomas, Eli Perkins, David Peicho, Cole Jancsar, zak sesti, Robin C Samuel, AlexanderGudkov and 5 more
Reacted by Rodrigo Quesada, Joseph Ashwin Kottapurath and klm127
Aluan Haddad (@aluanhaddad) --baseUrl setting enables to transpile the app, but what's the point of being able to transpile successfully if you can't execute it? ts-node does not seem to support --baseUrl, so I think it is inaccurate to say that TypeScript supports custom absolute paths.
ikokostya Thanks for the links. It seems that setting NODE_PATH in the startup script is the best way currently. I think I will go with that approach.
Reacted by Marcos Díaz, Miguel Dorta, carlosgarbiatti, Ivan Wang, Ryan Dsouza, Phil Brown, Samuel Bodin, Massimiliano Kraus, Rodrigo Quesada, Mateus Pereira and 9 more
Aluan Haddad (@aluanhaddad) --baseUrl setting enables to transpile the app, but what's the point of being able to transpile successfully if you can't execute it? ts-node does not seem to support --baseUrl, so I think it is inaccurate to say that TypeScript supports custom absolute paths.
The point is that it does execute perfectly in environments that support that. RequireJS, SystemJS, and even Webpack support setting a base URL.
What I'm trying to say is that the issue is on the NodeJS side. TypeScript provides base URL configuration to integrate with and take advantage of those other tools.
Our general take on this is that you should write the import path that works at runtime, and set your TS flags to satisfy the compiler's module resolution step, rather than writing the import that works out-of-the-box for TS and then trying to have some other step "fix" the paths to what works at runtime.
We have about a billion flags that affect module resolutions already (baseUrl, path mapping, rootDir, outDir, etc). Trying to rewrite import paths "correctly" under all these schemes would be an endless nightmare.
Reacted by Aluan Haddad, Rich Adams, Adam Palaniuk, Edvard Chen, Ravi van Rooijen, Randy Creasi, Andrii Dieiev, Martin Johns, Jordan Austin, Raphael Schweikert and 4 more
Reacted by Oleg Kurochkin, Taylor McIntyre, Yuri Pereira Constante, Luke Tanner, Daniel Beaupre, Paul, Luca Steeb, Dima Korolev, David Wolever, Rodrigo Alves and 180 more
Reacted by 何锦余
Reacted by Vitor Villar, Julian Berryessa, a11delavar and Daniel Ferenc Balogh
Ryan Cavanaugh (@RyanCavanaugh) Sorry to hear that. If Webpack team was able to deliver such feature, I thought TypeScript team could also - considering that TypeScript even has major corporate backing. It's a shame that people are forced to add another build step on top of tsc for such a widely needed feature.
Reacted by Igor Soloydenko, Luke Tanner, Qwerty (Vítězslav Ackermann Ferko), ivibe, Nick Laros, Jacob Smith, Heartlander, Conner Ruhl, SGrajdean, Marcos Díaz and 117 more
Reacted by Marin Marinov, Morlay, Aluan Haddad, phanmn, Denis Pshenov, David Noreña Perez, Qwerty (Vítězslav Ackermann Ferko), Conner Ruhl, Jon Thompson, leohoe and 6 more
Still hope TypeScript could support this.
Or Just make it easy to create a plugin, so we can build something like babel-plugin-module-resolver to make it work. (ref: #11441)
Reacted by Mikael Nakajima, chadhahn, AngrySean, Denis Pshenov, sfger, Luke Tanner, zhao5363, Owen Jeon (전원철), Dmitrii Kanatnikov, Serhii and 42 more
For anyone who may concern this:
I've found a custom transformer: LeDDGroup/typescript-transform-paths
We can load it with ts-loader or awesome-typescript-loader by wrting such config:
Ryan Cavanaugh (@RyanCavanaugh) If your goal is to stick to the JS standards, then please do that.
This means you should by default assume any import is referring to an es6 module, not a node module, and treat it as such.
I get that when typescript came out we didn't have modules outside of node, but we do now.
As it stands, by not wanting to disagree with the runtime, you mean "do not disagree with the node runtime".
We NEED the ability to tell the compiler we are running in a node or es environment, as the way imports are handled in those two environments are fundamentally different.
Reacted by TomN, Emilia, Alexey Iskhakov, Jochen Kühner, Enix, Yiheng, Kasopej, alamothe and Marcos Pereira
I don't know if anyone looks at old, closed issues, but I suppose this goes here.
In my ignorance of this controversy, I implemented a flag to rewrite the paths (#60723) after many, increasingly dodgy, attempts at recommended workarounds. The glorious feeling of finally being able to stop fighting vscode and tsc was very short lived when I became aware of just how adamantly forbidden it was.
I thought my use case must be very unusual, because of course tsc should be doing this, but this thread has disabused me.
The dogma is that JS must not be modified; but at least in my scenario JS requires relative paths for everything, and I want the JS to be modified. I suppose I could preprocess the TS to fix the paths, or I could postprocess the JS, but the tsconfig paths and rootUri already do exactly what I want - but then it skips the final logical step and throws the information away.
I know how long it took me to try and get around this apparent oversight (before giving up), and we can multiply that by the many thousands of other people facing the same situation. I have read the arguments against modifying the paths and I'm sure there are cases where they make sense, but this is not one of them. Typescript exists to improve the experience and safety of developing javascript, and enabling non-relative paths would absolutely add to that mission.
Reacted by Jeff Baker, Alexey Iskhakov, alamothe and JonasDoe
I know how long it took me to try and get around this apparent oversight (before giving up), and we can multiply that by the many thousands of other people facing the same situation. I have read the arguments against modifying the paths and I'm sure there are cases where they make sense, but this is not one of them. Typescript exists to improve the experience and safety of developing javascript, and enabling non-relative paths would absolutely add to that mission.
Welcome to the fight ha.
Sadly I don't see them moving on this any time soon. I ended up integrating vite into my .net build runtime to get around this issue.
Is it ok that their philosophy is to force us to these measures? No. Will it change? Probably not.
Activity
aluanhaddad commentedon May 5, 2017
While I heartily agree with your sentiment, I think rewriting such imports would open up a can of worms that would ultimately break or complicate an insanely large number of tools and workflows that rely on the emitted JavaScript using the same module specifiers. Even under a flag, I think it will introduce a lot of complexity.
I hate relative paths that go up, it is just awful for maintainability, but my two cents is that this needs to be done on the NodeJS side, not the transpiler side. Of course it's extremely unlikely that will ever happen...
ikokostya commentedon May 5, 2017
This issue can be solved if add
node_modulesdirectory with symlink tosrcdirectory:In this case you can use the following import in
c.ts:instead
All will work in typescript and commonjs. You just need to add
excludefield intsconfig.json:{ "exclude": [ "src/node_modules" ] }nakamorichi commentedon May 6, 2017
Aluan Haddad (@aluanhaddad) I've been using path rewrite (Webpack) on client-side since I began writing React apps. How would it cause problems on the server side if it doesn't cause problems on the client side? Editors already support setting module roots, and linters (ESLint, TSLint) seem to be fine also.
To the maintainers of TypeScript: Please add support for custom module roots so that we can get rid of the awful and unmaintainable import paths.
nakamorichi commentedon May 6, 2017
ikokostya Many tools have special treatment for node_modules, and it is always treated as a folder for external code. Putting app code into node_modules may solve the import path problem, but introduces potential other problems. It is also ugly solution that shouldn't, in my opinion, be recommended to anyone.
ikokostya commentedon May 6, 2017
Could you provide example of such tools? In my example all external code are placed in
node_modulesinproject_root.Which problems?
Maybe you should read this
And why it's ugly? It uses standard way for loading from
node_modules.aluanhaddad commentedon May 7, 2017
@Kitanotori perhaps I misunderstood your suggestion, TypeScript supports this feature with the
--baseUrlflag.My point was that NodeJS doesn't support it and that TypeScript should not attempt to provide the future on top of NodeJS by rewriting paths in output code.
ikokostya
There are too many to count but TypeScript is definitely an example of such a tool.
I think putting application code in a
node_modulesfolder is a very ill-advised hack.nakamorichi commentedon May 7, 2017
Aluan Haddad (@aluanhaddad) --baseUrl setting enables to transpile the app, but what's the point of being able to transpile successfully if you can't execute it? ts-node does not seem to support --baseUrl, so I think it is inaccurate to say that TypeScript supports custom absolute paths.
ikokostya Thanks for the links. It seems that setting NODE_PATH in the startup script is the best way currently. I think I will go with that approach.
aluanhaddad commentedon May 9, 2017
@Kitanotori
The point is that it does execute perfectly in environments that support that. RequireJS, SystemJS, and even Webpack support setting a base URL.
What I'm trying to say is that the issue is on the NodeJS side. TypeScript provides base URL configuration to integrate with and take advantage of those other tools.
RyanCavanaugh commentedon May 9, 2017
Our general take on this is that you should write the import path that works at runtime, and set your TS flags to satisfy the compiler's module resolution step, rather than writing the import that works out-of-the-box for TS and then trying to have some other step "fix" the paths to what works at runtime.
We have about a billion flags that affect module resolutions already (baseUrl, path mapping, rootDir, outDir, etc). Trying to rewrite import paths "correctly" under all these schemes would be an endless nightmare.
nakamorichi commentedon May 9, 2017
Ryan Cavanaugh (@RyanCavanaugh) Sorry to hear that. If Webpack team was able to deliver such feature, I thought TypeScript team could also - considering that TypeScript even has major corporate backing. It's a shame that people are forced to add another build step on top of tsc for such a widely needed feature.
morlay commentedon May 10, 2017
Still hope TypeScript could support this.
Or Just make it easy to create a plugin, so we can build something like babel-plugin-module-resolver to make it work. (ref: #11441)
87 remaining items
ArcticLampyrid commentedon Feb 7, 2023
For anyone who may concern this:
I've found a custom transformer: LeDDGroup/typescript-transform-paths
We can load it with
ts-loaderorawesome-typescript-loaderby wrting such config:feat(typescript): Absolute to relative path transform
Make import relative instead of absolute.
joecarl commentedon Oct 27, 2023
I'm quoting this comment here because I come from this other issue
I know the issue discussed here is not exactly about what I'm going to say but here it goes:
Look at this typical import statement:
Is that javascript code? Well, yes it is. But the problem here is that each language will interpret this line differently!
And when you transpile code shouldn't it be in a way so the transpiled code is interpreted exactly in the same way the original code was?
It's not about changing JavaScript semantics but rather aligning TypeScript's behavior with JavaScript to ensure consistent interpretation.
I don't know, maybe the followingTypescript dev team principle should be reconsidered.
RyanCavanaugh commentedon Oct 27, 2023
This is exactly why we don't modify the paths - so that it's never a potential source of disagreement between you, TypeScript, and the runtime.
The new module documentation covers this in exhaustive detail and I'd recommend reading it.
The problem here is not that we haven't thought about it over the hundreds of comments we've posted and thousands of comments we've read.
RacerDelux commentedon Nov 16, 2023
Ryan Cavanaugh (@RyanCavanaugh) If your goal is to stick to the JS standards, then please do that.
This means you should by default assume any import is referring to an es6 module, not a node module, and treat it as such.
I get that when typescript came out we didn't have modules outside of node, but we do now.
As it stands, by not wanting to disagree with the runtime, you mean "do not disagree with the node runtime".
We NEED the ability to tell the compiler we are running in a node or es environment, as the way imports are handled in those two environments are fundamentally different.
Do not massage declaration import paths
Do not massage declaration import paths
revert to relative paths for libraries rather than introduce more bui…
Relative imports (#63)
adrianstephens commentedon Dec 11, 2024
I don't know if anyone looks at old, closed issues, but I suppose this goes here.
In my ignorance of this controversy, I implemented a flag to rewrite the paths (#60723) after many, increasingly dodgy, attempts at recommended workarounds. The glorious feeling of finally being able to stop fighting vscode and tsc was very short lived when I became aware of just how adamantly forbidden it was.
I thought my use case must be very unusual, because of course tsc should be doing this, but this thread has disabused me.
The dogma is that JS must not be modified; but at least in my scenario JS requires relative paths for everything, and I want the JS to be modified. I suppose I could preprocess the TS to fix the paths, or I could postprocess the JS, but the tsconfig paths and rootUri already do exactly what I want - but then it skips the final logical step and throws the information away.
I know how long it took me to try and get around this apparent oversight (before giving up), and we can multiply that by the many thousands of other people facing the same situation. I have read the arguments against modifying the paths and I'm sure there are cases where they make sense, but this is not one of them. Typescript exists to improve the experience and safety of developing javascript, and enabling non-relative paths would absolutely add to that mission.
RacerDelux commentedon Dec 11, 2024
Welcome to the fight ha.
Sadly I don't see them moving on this any time soon. I ended up integrating vite into my .net build runtime to get around this issue.
Is it ok that their philosophy is to force us to these measures? No. Will it change? Probably not.
adrianstephens commentedon Dec 11, 2024
Jeff Baker (@RacerDelux) at least we have a support group
"I am Adrian, and I tried to use non-relative paths in typescript"
I'm going to use my forked version for now because I can be stubborn too!
ArcticLampyrid commentedon Dec 11, 2024
For everyone who met this, I recommand to use https://github.com/LeDDGroup/typescript-transform-paths, which seems more friendly to maintainers than making a fork directly.
Do not massage declaration import paths