-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
TypeScript paths config doesn't work with leading slashes. #13730
Comments
Side note, I discovered that I was using RequireJS' require.config({
baseUrl: '/some/place',
map: {
'*': {
common: '../../common'
}
}
}) A TypeScript solution would still be nice. |
I'm also having this problem when attempting to migrate my Meteor application to use TypeScript. I have code like:
Where Meteor maps Meteor doesn't use the RequireJS runtime so I don't have the ability to workaround like this. My ideal would be to able to re-configure the root to my liking in |
Leading slash refers to the root directory, so this is an absolute path. path mapping does not work on absolute or relative paths. |
@mhegazy that's not compatible with Meteor JS which is a VERY popular Javascript application framework. (currently 38,469 stars on their GitHub Repo) https://github.com/meteor/meteor all that would be required to solve this is a way to override the absolute path behavior for frameworks that desire it. The default could remain but just a flag as I described in my previous comment would work great. |
@mhegazy here's some further info on how Meteor structures applications. https://guide.meteor.com/structure.html |
it is not just a flag. it has implications on module names in output and generated declarations, which can then be consumed by third party apps. The is really the same behavior as node today. |
This seems to go against the design goals of TypeScript because it introduces an opinion about import paths should be interpreted which is clearly not the same across all Javascript frameworks and platforms. Bare node interprets it this way, sure, but many frameworks including the popular Meteor framework and also users of babel support mapping the leading slash to mean the project root not filesystem root. Let's face it, importing a file from the filesystem root is about as useful as a caps lock key and we know many people remap that key as well. And not that I think you should support everything that Flow does, but they also support mapping the leading slash to something else: https://www.npmjs.com/package/babel-plugin-root-import#dont-let-flow-be-confused Here's some other examples of platforms that use the leading slash to mean something else: If you can't tell I REALLY want to use TypeScript on this project but this is a show-stopper. Thanks for considering this. |
This is about what a path means. we have mirrored the node module resolution in our module resolution strategy, and that is how
Here is you are expecting the compiler to rewrite your module name in the otuput. this is something the compiler does not do... it only needs to know where the file is, module names do not change. |
Thanks for the extra details. Actually, I just want the compiler to pass it through unchanged as Meteor in this case will properly interpret the paths in the resulting JS. It implements its own module loader. I might have hijacked this thread a bit but ideally I just want TypeScript to find the files in the right location so that it can typecheck everything but I'm fine if it just passes the paths through unchanged and have the framework handle it at in its existing way at runtime. So perhaps I should open a different issue for my case as it's somewhat different than the OP's issue (though related). |
sure. |
Hi @hexsprite, |
Hello Mohamed, you don't have to pick, you can let the end user pick by giving the user a configurable option. Then everyone will be happy doing it their own way. |
There should at least be a way to make this work for javascript. |
I have the same issue as @ribrdb. I am working at a project with other devs and the idea is to use typescript to analyze javascript with jsdoc annotations as the project should stay vanilla js, with using es6 modules in the browser. Removing the leading slash just doesn't work for that. |
I have same issue :/ |
Having the same issue with meteor and typescript... Just need to be able to map the "/" to the root of my project. Right now I have to use |
While you are of course technically correct we could ask 'What does root mean?'. In web applications this means the web root. There are exactly 0 use cases where I want to include anything from the root of my system, my build server or my production server. One could even argue that it's unsafe to allow that. In any case, to me it makes much more sense that I would recommend you to either allow for extensions to influence the resolving process (an example for webpack and an example for eslint) or allow the { "paths": { "/*": "./src/*" } } The default behavior can remain the same and from a naive perspective this change does not seem to involve much as testing for an absolute path is rather easy: |
FYI, this issue prevents VSCode from working with native web browser module loaders. Browsers don't support named imports, only relative paths starting with |
Best point so far IMO. even for nodejs code, server code, there is no real sence to use root directory. The problem is, that the actual "NO WAY TO HACK" is pretty annoying, to me, at least, as it prevent plenty of framework using this syntax to be intellisence-compatible, and im not able to hack it... Im currently using meteor, and it is quite laborious, especially when coding large apps with great amount of data model. Intellisence is really useful to get instantly in the code, get desciptions on the go, and correct eventual spelling problem without having to read all files again. I suggest please to at least add a a js/tsconfig flag, allowing to compute initial "/" as app path instead of system root for intellisence, as it is not possible at all to hack it afterward, as glob does not interpret "/" as any other character. |
I have not heard any convincing arguments to not put this in. I am willing to dive in and create a pull request but I would need some confirmation from the maintainers before I start working on it. TypeScript is a new codebase for me and I never typed anything in TypeScript. So it will take some effort to get to know the conventions, setup the test environment, etc. The investment in time would be too large to just add it and later discover that the change was rejected. I had a peek at the code (at least one place that the configuration was used) and it looks very readable. There is quite some indirection and here some Anyway, do the maintainers want to add this feature? And if so, would accepting the following form be ok?
|
It turns out the matching is not holding us back. It's that leading slash imports are not passed into the path mapping facility. I created a pull request that checks all boxes except for the 'has a label on the issue' one. The essential code that I needed to add was: if (baseUrl && paths && startsWithSlash(moduleName) && getOwnKeys(paths).find(startsWithSlash)) {
const resolved = tryLoadModuleUsingPaths(extensions, moduleName, baseUrl, paths, loader, /*onlyRecordFailures*/ false, state);
if (resolved) return resolved.value;
} |
I forgot to mention in this conversation that we are using leading slash imports instead of adding |
match leading slash imports with path mappings - fixes #13730
Thanks @EECOLOR and the team for all the work you put into this! |
Has this not been resolved yet? |
@EECOLOR, I've just noticed that with |
@red-meadow I should indeed be reported as separate issue. I don't think I'm qualified to help with this issue. A quick search on Github let me to: https://github.com/microsoft/TypeScript/blob/master/src/services/getEditsForFileRename.ts That code is used throughout the code base. From a glance it seems that If this feature would be added it would probably be something like In any case, I would create a separate issue for it and see what direction the Typescript core team would want to go. |
It turns out that path mapping entries are respected, but only the first one and only if it doesn't start with |
This is happening with pure javascript as well. I currently have a Spring boot project and I am trying to use Intelissense with js, but it is currently impossible. Here is my jsconfig.json:
When I try something like |
@andremarcondesteixeira Where do you expect {
...
"compilerOptions": {
...
"baseUrl": "./src/main/resources/static",
...
"paths": {
"/*": ["*"]
}
}
} I am not sure if {
...
"compilerOptions": {
...
"baseUrl": ".",
...
"paths": {
"/*": ["src/main/resources/static/*"]
}
}
} |
Hi EECOLOR, I just try this feature in a brand new project created with nest-cli. However it seems not working as expected: check the detail I was wondering if you could help me with this, Thank you so much |
@jeoy I will check it out as soon as I have time. You could try to add |
Thanks @EECOLOR , added |
@EECOLOR Inside this file I have an ES6 import like this:
when using this path with the trailing slash, I expect it to look for the file in I tried using both your suggestions, but both didn't work as expected. If I remove the trailing slash, vscode can find the file and show me the JSDocs for my class, however, my app stops working because without the trailing slash, ES6 will treat the import as a relative import and will try to find the file in |
@jeoy I checked your link, and I don't see the |
@andremarcondesteixeira Were you able to resolve it ? and with below folder structure I am using gitpod and seems its not working. |
still an issue |
@AjManoj @andremarcondesteixeira Does one of you have a pubic test project that I could check out? I noticed in one of the cases a |
@jeoy Previously I only checked vscode with your example and it worked. I now ran your code and discovered @nest made it fail. Upon digging I found it uses https://www.npmjs.com/package/tsconfig-paths which explicitly states: _ (that doesn't start with "/" or ".")_. That library might not be aware of this change in paths, so you could file an issue with them. |
TypeScript Version: 2.1.1 / nightly (2.2.0-dev.201xxxxx)
2.1.5
Code
Expected behavior:
tsc
should be able to recognize that when it sees a dependency like/common/Foo
it should look forwebsite/common/Foo.js
in the filesystem.Actual behavior:
It can't.
** More details **
I can get the following to successfully resolve files, by simply removing the leading slashes:
In this case, however, the output module contains something like
But this is problematic, because if
baseUrl
in RequireJS config is set,then RequireJS will look for the module at
example.com/some/place/common/Foo.js
which doesn't exist. I need it to look for the dependency atexample.com/common/Foo.js
, f.e. TypeScript would output the following including the leading slash:It would be great if TypeScript could support this case, then the output can still have an absolute path and work as expected.
Unfortunately, RequireJS doesn't support map configs like the following:
I think solving this in TypeScript is the best options because then it can be taken advantage of in other environments besides RequireJS.
The text was updated successfully, but these errors were encountered: