-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Module path maps are not resolved in emitted code #10866
Comments
Do you use some other bundling tool like browserify or webpack on the generated output? or do you expect this to run directly on node? |
Well and to add context, |
yes, this was the intent - to mitigate the mismatch between runtime and design time experience when module (as it is written by user) can be resolved in runtime but failed to be found by the compiler. At this point compiler always assumes that module id provided by the user is correct and never tries to change it. |
similar response #9910 (comment) |
All right, thanks. It might be useful to document this better in order to prevent more people from being confused. I now use https://www.npmjs.com/package/module-alias to make it work with node. |
Appreciating TS's position, here's a simple solution to the 90% use case for those of us using node, but wanting the convenience of using This solution hooks node's To use, paste this tiny chunk of code at the top of your "main.ts". import * as path from 'path'
import * as fs from 'fs'
(function() {
const CH_PERIOD = 46
const baseUrl = path.dirname(process['mainModule'].filename)
const existsCache = {d:0}; delete existsCache.d
const moduleProto = Object.getPrototypeOf(module)
const origRequire = moduleProto.require
moduleProto.require = function(request) {
let existsPath = existsCache[request]
if(existsPath === undefined) {
existsPath = ''
if(!path.isAbsolute(request) && request.charCodeAt(0) !== CH_PERIOD) {
const ext = path.extname(request)
const basedRequest = path.join(baseUrl, ext ? request : request + '.js')
if(fs.existsSync(basedRequest)) existsPath = basedRequest
else {
const basedIndexRequest = path.join(baseUrl, request, 'index.js')
existsPath = fs.existsSync(basedIndexRequest) ? basedIndexRequest : ''
}
}
existsCache[request] = existsPath
}
return origRequire.call(this, existsPath || request)
}
})() |
If you're going to use the So if you have this in your tsconfig file:
You have to register this in your
|
Got here after wasting some time trying to set it up in a big project. |
install and run "tspath" in your project folder... https://www.npmjs.com/package/tspath |
Also you can try "momothepug/tsmodule-alias" to alias path resolution: |
Only https://www.npmjs.com/package/module-alias worked for me... |
I too managed to get this working with module-alias, with the downside that I have to keep track of my aliases both within tsconfig.json and package.json. Has anyone found a simpler solution? The solution pointed out by @mattyclarkson also works, but I couldn't find a way of using it side-by-side with ts-node. Any ideas? |
Take a look at https://github.com/momoThePug/tsmodule-alias
2018-05-31 15:04 GMT-05:00 edufschmidt <notifications@github.com>:
… I too managed to get this working with module-alias, with the downside
that I have to keep track of my aliases both within tsconfig.json and
package.json. Has anyone found a simpler solution?
The solution pointed out by @mattyclarkson
<https://github.com/mattyclarkson> also works, but I couldn't find a way
of using it side-by-side with ts-node. Any ideas?
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#10866 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ACKT9JWIkb0Wekz0H_Z3zKXvoE-49EIBks5t4EzkgaJpZM4J6vZQ>
.
|
Thanks @DanyelMorales, this is really handy. |
you're welcome! :)
2018-05-31 16:35 GMT-05:00 edufschmidt <notifications@github.com>:
… Thanks @DanyelMorales <https://github.com/DanyelMorales>, this is really
handy.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#10866 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ACKT9GNo30wNv4ZWzSwm_Lv4vesLPI3xks5t4GIzgaJpZM4J6vZQ>
.
|
Can someone tell me what the point of this feature is if the pathnames emitted are actually incorrect? That is to say, if the TypeScript compiler is happy with it, but the end result isn't runnable - what's the use case for this feature? |
How should one do relative path mapping for things that are NOT modules, i.e. not imports? In a node script that reads a certain directory relative to the source file I used to do:
since typescript compiles the script and writes it to another directory (based on config), __dirname will no longer lead to the above path resolving. What would be a solution to this? |
That is really "how do I use Node.js and TypeScript question" and much better asked in Gitter.im or StackOverflow. |
…alias to /src for all files in /src. Unfortunately, this breaks the compiled js because the paths don't get resolved in the js. Working as intended: microsoft/TypeScript#10866 Just going to get rid of that alias entirely - It isn't going to make things easier in the long term like I hoped it would. I originally only intended it to be used in the tests, but if VS code is going to be aggressive about it, then its better to just forgo it entirely.
I love TypeScript but this is insanity. |
I don't get it. Even with me knowing little about the TS codebase, this shouldn't be hard to implement. I've just started using a shared project with client and server... why does TS present the paths functionality in the first place, then makes me jump through hoops to actually use it? Why does TS assume that I want to use a bundler/loader with every project I make? I'm trying to use TS to simplify my projects, not tack on more tooling libraries to compensate for a 90% implemented TS feature. |
I agree with you. I think, TS was developed for frontend, 'cause webpack
already implements quite well ts alias paths, and with Requirejs is also
the same thing. But for Nodejs projects it's so hard. :(
El jue., 20 de sept. de 2018 02:50, Josh Pike <notifications@github.com>
escribió:
… I don't get it. Even with me knowing little about the TS codebase, this
shouldn't be hard to implement. I've just started using a shared project
with client and server... why does TS present the paths functionality in
the first place, then makes me jump through hoops to actually use it? Why
does TS assume that I want to use a bundler/loader with every project I
make? I'm trying to use TS to simplify my projects, not tack on more
tooling libraries to compensate for a 90% implemented TS feature.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#10866 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ACKT9DD_z4KOHpfwddTomMXujEsza9tQks5uc0jbgaJpZM4J6vZQ>
.
|
+1! |
And it is generating executable code if you don´t use features which is
unsupported by JavaScript Engines, that should make a lot of sense right
there, for example: would you blame the C++ compiler if your application
uses dynamic link libraries and that the program won´t run on a machine
that doesn´t have these installed?
This is a feature that can be utilized if you manage the relative paths,
take responsibility for them like Angular does with WebPack or as I do with
all my TypeScript projects with TSPath!
Don´t use them if you don´t understand how to set up a working environment,
I really don´t think that this is Microsoft's responsibility here, they
provided a feature and here´s how it works,
it may not work as you want it or expect it to work but that does not make
it wrong!
Also, I´m curious, are you seriously letting this hinder you from
developing using TypeScript?
Den mån 14 jan. 2019 kl 21:34 skrev Robert Main <notifications@github.com>:
… The TypeScript compiler does exactly what it should do!
If this thread was full of people requesting that tsc also do
minification or some such, I'd agree with you. However it isn't. It's
people requesting that the compiler generate executable code. I really
don't think that's too much to ask from a compiler, do you?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#10866 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAAy_7FeuOJAnI9bXYSVgf_YghJluTyGks5vDOnEgaJpZM4J6vZQ>
.
|
This is a feature which makes the compiler output broken code, code that could be working if they only wrote 1 line of code for properly resolving those paths. The fact that TS needs an external bundler just so that the outputted code can be executed is plain ridiculous. |
I've always understood that TypeScript was supposed to compile to JavaScript. If you're telling me that certain features are not supported by JavaScript engines then why exactly are they there?
No, but I would blame it if it let me link to other C++ code that didn't actually exist with no compiler error or warning. |
You really don´t understand this, do you? The code is not broken, if it´s
broken it is because you have configured the compiler
to generate code that your "platform" does not support, in this case,
aliases!
In your case, don´t use aliases, "you" don´t support them, seriously!
Even if this would be a 1 line fix (of course that´s not the case) it´s a
matter of what a compiler should and
should not do! This feature has been added in order to SUPPORT LOADERS not
the other way around, read up
on Path Mapping in the official documentation, so again, you are using it
wrong!
Again, this feature is for Loaders/Resolvers, you have misunderstood how it
works, so no, Microsoft
should not alter the compiler so that you can paste aliases without an
environment that supports it!
Den tis 15 jan. 2019 kl 04:41 skrev Fabio Spampinato <
notifications@github.com>:
… This is a feature that can be utilized if you manage the relative paths,
take responsibility for them like Angular does with WebPack or as I do with
all my TypeScript projects with TSPath!
This is a feature which makes the compiler output broken code, code that
could be working if they only wrote 1 line of code for resolving those
paths.
The fact that TS needs an external bundler just so that the outputted code
can be executed is plain ridiculous.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#10866 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAAy_zuWKV0qzzWt6_jZNgDLFt1TA0tMks5vDU3vgaJpZM4J6vZQ>
.
|
They are there since Loaders use Path Mapping, that´s why it´s supported!
And since you insist (like me) on using them without a Loader, what is the
problem with
using a tool so that you can make use of the feature?
Den tis 15 jan. 2019 kl 05:10 skrev Robert Main <notifications@github.com>:
… And it is generating executable code if you don´t use features which is
unsupported by JavaScript Engines,
I've always understood that TypeScript was supposed to compile to
JavaScript. If you're telling me that certain features are not supported by
JavaScript engines then why exactly are they there?
would you blame the C++ compiler if your application dynamic link
libraries and that the program won´t run on a machine doesn't have these
installed?
No, but I would blame it if it let me link to other C++ code that didn't
actually exist with no compiler error or warning.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#10866 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAAy_25-ZmS235i1Ic7mvSzEt2QJDX6Bks5vDVTAgaJpZM4J6vZQ>
.
|
Look, I see your point. I do. But part of the compilers job is to sanity check things one last time. At best code that compiles but doesn't run is inconsistent behavior and when I first read into this issue the documentation seemed to suggest behavior that clearly isn't there |
Please point me to that section of the documentation.
tis 15 jan. 2019 kl. 05:31 skrev Robert Main <notifications@github.com>:
… Look, I see your point. I do. But part of the compilers job is to sanity
check things one last time. At best code that compiles but doesn't run is
inconsistent behavior and when I first read into this issue the
documentation seemed to suggest behavior that clearly isn't there
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#10866 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAAy_8e5v8IV-ynmjRTeoC3cp5llwnsIks5vDVm8gaJpZM4J6vZQ>
.
|
https://austinknight.com/wp-content/uploads/2015/04/DesignVSUX.jpeg |
@duffman Can't you see that people here just want this feature??? You are telling everyone that he/she is to stupid to understand how this "feature" should be used. OK - you can look at this that way but who knows - maybe it's the other way around... |
By the way, my opinion is following: As aliases are builtin in compiler and compilation of project with them is OK. It may make users think, that it works way it's suggesting (and this issue is pretty much good proof I'm right). It even seems illogical - why something works in "official" editor (vscode - especially when using "auto import" feature, vscode uses aliased path), why copiler also works OK, when resulting code is not working? Saying "js engine don't support it" makes me wanting to ask even more - wasn't TS meant as a thing to mitigate some of JS "problems"? I would expect one of two solutions of this:
Saying "it's correct behavior" is, I think, wrong. It's not. TS is not assembly language, not even a C/C++. |
Development team should add support for alias resolution. I suggest add a
key for compiler resolution in tsconfig.
It would be nice Microsoft!!!!!!
We beg you, we need your help to improve applications with alias.
:( everybody here is sad and angry(, and hungry) because of lag of
consistency. Typescript is awesome, I love it...
We Love it!
Best regards a Homeless developer...
El mar., 15 de ene. de 2019 08:02, Mike S. <notifications@github.com>
escribió:
… By the way, my opinion is following:
Aliases are builtin in compiler a compilation is OK. It may make users
think, that it should work like they think (and this issue is pretty much
good proof it's true). It seems illogical - why something works in
"official" editor (vscode - especially when using "auto import" feature,
vscode uses aliased path), why copiler also works OK, when resulting code
is not working? Saying "js engine don't support it" makes me wanting to ask
even more - wasn't TS meant as a thing to mitigate some of JS "problems"?
I would expect one of two solutions of this:
1. Correctly overriding imports with aliases
2. Showing a warning
Saying "it's correct behavior" is, I think, wrong. It's not. TS is not
assembly language, not even a C/C++.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#10866 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ACKT9OqexgOaHH1vDFuRcO7U_r2DEC23ks5vDdFbgaJpZM4J6vZQ>
.
|
I really don´t understand what you are trying to point out by establishing that TS is not C++, most of us are well aware of that I think! We have also established that alias/path mapping is used in production all over the world, so naturally, VS Code should support that, but it´s still not an argument for MS to craft the compiler to suit your setup! What I´m having a hard time understanding is why you keep at it, the compiler works as it´s supposed to work, again, read the docs which clearly states what the feature is for! I mean you can set up a working TS development environment with path aliases in like 2 minutes, if you don´t want to use WebPack, you can use TSPath to resolve all paths in all js files in 1 second, add it to the package.json as a run script and you don´t even have to think about it, the problem does not exist, the compiler stays the way it was meant to function and you can carry on happy hurray!? Or if it is so important to you that the actual compiler does this for you, then I suggest you fork the compiler and implement it yourself, maybe it would be a big hit or maybe people are happy the way they are since they have set up their environments to support aliases. |
Summoning the top five TypeScript contributors: @ahejlsberg @andy-ms @DanielRosenwasser @sandersn @sheetalkamat Could the TypeScript team reconsider this issue? I think this thread offers some useful discussion on both viewpoints and given its recent popularity and the amount of time that's passed it should be looked at again. |
The status of this issue left me no other choice but to demote TS to type checker duty only. This is the minimum setup I got working as a drop in replacement for
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@mynamespace/*": ["src/*"]
},
"outDir": "./dist",
"noEmit": true, <--
"allowJs": true,
"target": "ES2017",
"module": "CommonJS",
"lib": [
"ES2017"
]
},
"include": [
"./src/**/*"
]
}
{
"presets": [
"@babel/preset-typescript",
["@babel/preset-env", {
"targets": {
"node": true
}
}]
],
"plugins": [
["module-resolver", {
"root": ["./src"],
"alias": {
"@mynamespace": "./src"
},
"extensions": [".js", ".ts"]
}],
"@babel/plugin-proposal-class-properties",
"@babel/plugin-proposal-object-rest-spread"
]
}
|
I just want to use typescript with absolute path, but seems i have to config webpack or babel or something, it's too hard to achieve this simple feature, it should be easier 😞 |
I acknowledge this problem, I´m not sure I´ve been aware of this specific
problem due to my own personal setup, or maybe I was :) it´s not a super
heavy fix, the fix will simply be to simply (blindly) trust the distPath,
which is actually less and more simple code than the current solution, I´ll
try to have a fix available by tomorrow...
Den mån 28 jan. 2019 kl 15:59 skrev 叶伟伟 <notifications@github.com>:
… I just want to use typescript with absolute path, but seems i have to
config webpack or babel or something, it's toooo hard to achive!!!
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#10866 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAAy_1_T-An7swSND-xdBhL0HNHxQkm6ks5vHxBggaJpZM4J6vZQ>
.
|
Leaving this here because an actual documented use case for the current behavior of "paths": {
"history": [ "history/v2" ]
} The compiler would need an extra option to differentiate between type aliases and "code" aliases. If we change the behavior to actually emit the path aliases then we need to add the ability to the compiler to find the correct types version. This is not an argument against the proposed behavior. I'd rather have emitted aliases and just™ working solution for versioning of types. Just wanted to provide some context why changing this might not be as trivial as people think it is. |
Does not work currently due to microsoft/TypeScript#10866
For the second time during a company-wide TS workshop, I've had to explain this inane and embarrassing behavior... Seriously! What kind of language compiler, especially one whose primary sales pitch is more correctness for JavaScript, produces broken code as a "feature"?!?! |
I'm sorry to have sounded so frustrated in my comment, but the community's views here are seemingly being ignored and downplayed repeatedly. |
Just look at how many times this has been referenced... What a waste of time and attention for so many people. |
I understand your frustration, but lots of people feeling a behaviour is correct, doesn't mean it is the right thing to do. TypeScript rewriting module identifiers is a slippery slippery slope. What has been expressed multiple times in this thread is that TypeScript is configurable to model the behaviour of other module resolvers and other build tools, not replace or implement them. Just because TypeScript can be configured to resolve modules in flexible ways doesn't not mean that TypeScript emits "broken code". Certain loaders and bundlers that mirror this configuration would work just fine. If we were to be critical of anything, we could blame the team for naming the option something that might look like it fixes a problem it was never intended to fix, though the documentation for the option makes it clear that it does not change the emit. Because a particular tool doesn't solve a problem you have doesn't always mean it is that tools fault. It maybe you are just don't have all the tools you need to solve your problem. |
@kitsonk everything you just said is way off the mark. The issue is that TS will operate one way during development / testing, and another after compilation has completed. If TS wants to be a module resolver, it needs to choose a pattern and stick to it. If I run something with It does not, and that is the problem. |
Maybe module maps will alleviate the frustration in the future. But our position here along with the technical problems we want to solve are pretty explicit - path mapping reflects the behavior of an external resolution scheme (e.g. path mapping in AMD and System.js, aliases in Webpack and other bundlers). It doesn't imply we will change your paths. I don't think any recent discussion has been constructive recently, nor do I foresee any future changes here, so I'm going to lock this issue. |
TypeScript Version: 2.0.2
Code
tsconfig.json
app.ts
utils.ts
Expected behavior:
% ./node_modules/.bin/tsc && node app.js Foo
Actual behavior:
app.js
Typescript is finding the right module, but in the emitted code, the module path is left as-is instead of applying the path aliases from
tsconfig.json
. Obviously node has no idea where to find the module. I would have expected typescript to resolve the module path and replace it with something that node can resolve.If this behavior is intended, then how can the path maps be used to solve the relative-import-hell in conjunction with node?
The text was updated successfully, but these errors were encountered: