-
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
TypeScript and <script type="module"></script> #13422
Comments
Just a comment. It seems ironic that you wish to
When it is about the only option comes that close to what you seem to be trying to achieve.
Personally, I think extensionless imports are far better, they make your code far more portable. I suspect the native loader will eventually support configuration. Of course the specification is in major flux, but there is likely to be a configurable API to perform abstracted name resolution for imports like import {Component} from '@angular/core'; because it is clearly needed and because the issue has been discussed at least to some extent. I've heard discussion of how to resolve import $ from 'jquery'; You may find this repository interesting https://github.com/whatwg/loader/
No this is not possible at present. |
I don't see what's ironic in wanting to depend on native and standard features, instead of librairies... |
Sorry I am a dyed in the wool SystemJS user (actually I'm not sorry 😜). But the whole point of SystemJS is to get out of the way, when native loaders are available, but until then polyfill the loader specification (and provide other features such as CommonJS interop). Seriously SystemJS is great. Not every framework uses it well, for example Angular 2, made poor use of it and is now removing it. Look at Aurelia as an example framework that, while not requiring SystemJS, uses it by default and plays to its strengths showing how elegant it can be. |
It's not a charge against SystemJS. Yes, it is a nice tool. But as you said it very well, it was designed as a temporary tool until the native loader is finally here. So now the central part of it is there ( Hopefully configuration is coming. Or hopefully TypeScript will manage it. |
Check this out. https://github.com/guybedford/isomorphic-browser-modules |
SystemJS didn't recommend to use default extension as well. |
i am not sure I see why this is a TS issue. If you put the full file path in the module, it should work. Or putting it diffrentelly, how could you do the same with a plain .js file with the typescript compiler completely out of the picture? |
Whether TypeScript transforms paths or not, it could be an option to add extension to the names of modules (or it could convert .ts to .js). |
|
As far as I know, TypeScript doesn't support absolute paths. So no, it doesn't work. After a deeper thinking, I think the current behavior is really not normal. As a transpiler, TS should produce standard and ready-to-work JavaScript. TS also choose the very good design option to be "just" enhanced JS, ie. backward compatible with normal JS.
|
what do you mean absolute path? can you share an example of an app with a module that is absolute? a CDN path should work with a path mapping entry.
We do not know what node will do yet. but if node considers this invalid filename, the compiler can flag it as an error. either ways, you should just write: import { Something } from './something.js' |
It's already an invalid filename for browsers, which is the main use case of TypeScript.
I agree, that's what I do now to be future proof. Problem is, like I said on first message, that it's a huge change to common practices and a lot of refactoring : official TypeScript docs, Angular, RxJS and so on have all encouraged until know to use the no extension form ( For absolute paths, I mean a code like this :
Otherwise, I need to do things like this :
First, it's a mess, second, it doesn't work if |
And most importantly, I can refactor my code, but I can't refactor librairies I use... |
No it is not if you are using requireJS, Browserify, Webpack, SystemJs, etc.. i.e. any thing other than a browser that supports native ES6 modules, and as i far as i know, there are not many of these around today. |
The loader spec does not really talk about how these absolute paths are allowed. When we have a clear description of that, allowing such should not be hard. |
Implementations have started, it is now in Safari Technology Preview, in Edge Preview and it's coming soon in Chrome Canary. That was the starting point of this issue. TS is supposed to produce standard JS, not JS that need specific tools. Maybe it's too soon to decide, but for now common usage of TypeScript is incompatible with native JS. |
I don't understand why it's so difficult for this issue to be acknowledged. TypeScript is supposed to be JS compatible, and it is also a transpiler. The point of a transpiler is to produce native JS. And it's not right anymore with OK, maybe there are still some points to be clarified (loader spec and Node choices are not final yet), but if navigators have started implementations (even Safari ^^), it's because they think the spec is now stable enough. So now that it's possible in some beta versions to use
And even if native loaders just started to appear, ES6 That's precisely why tools like Systemjs offer a |
this we can solve. and probably should. possibly with a flag to consider the
I would say this is an issue with the Angular code base, and not TS. there are going to be dependencies that do not use full URI, the TS compiler can not go touch all your node_modules to make them ES6 ready. |
But you should fix TypeScript documentation — currently there is no .js extension in examples of using modules. And, for strict code convention, it can be an option of TypeScript to require .js extension in modules. |
It's not an Angular issue. It's a possibility, and the current common usage in all TypeScript projects, not just Angular. It's even the indicated way in official TypeScript documentation. And as valid TypeScript which is here to stay for compatibility reasons (next point), it should be managed and transpiled to valid JavaScript. Of course TypeScript won't rewrite existing projects and files in my And for current librairies to become ES6 compliant and ES6 ready-to-use, TypeScript must start to transpile to valid JS, which is not currently possible.
It won't happen as it would break compatibility. '.js' extension works only since TypeScript 2. As we can't revert things now, transpilation to valid JS must be managed. |
It's true that we have a problem with compatibility and I think it can be an option to choose backward-compatible mode (with adding Why we need that strict mode? The main idea of TypeScript is to be more strict than JavaScript, but currently in modules JavaScript is more strict than TypeScript. TypeScript should be as strict as JavaScript but with additional restrictions. |
Now in Firefox Nightly https://twitter.com/evilpies/status/829604616216125442 Meaning all major browsers are now implementing this. I think it's time for TypeScript to be ready. |
Another point : current TypeScript loaders (ts-loader, awesome-ts-loader and |
@cyrilletuzi Where did you read that support for Edit: Nevermind, found it https://www.chromestatus.com/feature/5365692190687232 |
That's true, but only for JavaScript code. SystemJS TypeScript transpilation doesn't work with a .js extension because there's no file on disk with that name. |
Related to #16577 |
Just ran into this issue and it surprises me that it hasn't been fixed. Workarounds are called workarounds for a reason - even if they work, they have their own problems. |
Unfortunately I've found out that this bug is now considered "working as intended" and affirmatively closed by @RyanCavanaugh in a recent issue in January 2021. According to him there won't be a fix even behind a flag, so. I'm not picking on Ryan though as I imagine this is not his decision alone, but so far I haven't seen a satisfying rationale, across 3 issues and hundreds of comments, as to why this fix is not worth doing. From Ryan it seems that complexity is a problem, and that you should write import specifiers how they're supposed to be during runtime. But I think his reasons pale in front of this argument. I would very much appreciate a response to the linked comment from the TS team. |
Please consider reopening this and implementing it. |
It seems that proper way fix will not be available soon, so I wrote a small js-script as an alternative to |
Given how the ecosystem has changed since 2017. To try summarize the TS position here in mid 2021:
Re: original point about resolving TS in modules in html files- I've been doing some work on that in microsoft/vscode#121517 |
Instead of waiting X years for caniuse import maps to be implemented by all browsers, typescript could implement this itself. For example, typescript already has something similar for lookup (paths), but it doesn't transform output js import paths:
Adding an import map feature, for example:
would allow to transform |
The TypeScript compiler already rewrites The problem isn't that our TypeScript code is wrong - it passes all compile and linting steps perfectly - it's that the compiler is doing the wrong thing when converting to JavaScript for these target module systems. |
With regard to this issue, not only does Typescript use non-extension imports in it's own documentation on modules https://www.typescriptlang.org/docs/handbook/module-resolution.html the VS Code editor, which is also made by microsoft needs special settings to even work https://2ality.com/2021/06/typescript-esm-nodejs.html#visual-studio-code I can understand sticking to a design principle. But I have to ask, WHO is this for? Who is actually benefiting from that design principle? Since it feels like, it's literally for nobody. Especially when nobody is asking to change default behavior, just a switch to append ".js" or ".mjs" when outputting (out of which there are crazier output settings already in the language). To be honest just the confusion aspect of this issue is reason enough to add a simple output @ anyone stumbling here... If you're trying to get your node program to work, just replace whenever you would write If you need it as a shell header, don't forget the |
After tediously reading 4+ years worth of comments on this thread I must say SrcSpider ended the thread on a good note for me. The thing that confuses is me, is I don't understand why no one wants to fix this issue. I don't contribute to TS, so I don't know the project all that well, but usually path resolution issues (from what I have seen) are solvable issues. At the worst case a flag could be added to change TS behavior for ES6 Module path resolution right? IDK, maybe I am out of my league, but the way it is as it stands to be extremely annoying. So annoying it makes me wonder if I am just wasting my time working to make sure I write everything in TS. The whole point of compiling to JavaScript (transpiling) is backwards compatibility, portability, and valid code (or valid ES6 JS in this case), right? Its 2022, and no one working on the project seems to even care. |
@W3Dojo don't miss out part 2 12 hrs of reading |
I've created a pull request wich wich solve this for raltive imports, see: I've added a compiler switch:
|
They said it wasn't possible. Along came some guy who didn't know this and just did it. 🥳 |
According to my trusted sources, the rationale behind this stubborn refusal to actually make If implemented, Typescript newcomers will cease writhing in pangs, thus disrupting the steady supply of bad vibes that keep Ctulhu asleep, and it will make Him emerge from R'lyeh, scramble the letters in all occurrences of Microsoft in existence into Coots Firm and scuttle back into the Ancient City growling unspeakable curses; And the management clearly doesn't want that! Let us all support the stoicism of those behind this unpopular decision and applaud their efforts to redeem the world! |
How exactly do I use this? I can't find anything about this option in the documentation :/ |
it was not accepted |
I can answer this for you :-). Because I am in the same boat as you, but I actually don't want this solution.. The principle that typescript/tsc will preserve import paths, and never try to magically adjust them,
Also, one of the invariant rules of typescript is, that if you feed it a plain javascript file, that file will be re-output unmolested/without needing any adjustments. If you had this import-path adjusting possibility, it would need to be able to adjust import paths in a plain javascript file, violating the guarantee that it won't adjust plain-javascript. I/we are already living variants of this nightmare. This is the hell these 'defenders of typescript' are fighting against/protecting you from :-) :-(. I will now continue on my odyssey to unravel, how their (my 'enemies'.., not the ts-people) non-standard import-syntax can be made to work when using ESBUILD :-/. |
Random addition: one solution to this for browser native ESM is to add a service worker to your app, and append the I also use service workers for things like importing `.css` or other types of files.Basically service workers let you implement a module loader. What you do is you intercept the URL (f.e. for a URL ending in |
A first implementation of
<script type="module"><script>
just landed in Safari Technology Preview 21, so I tried to use it on a TypeScript / Angular project, to finally get rid of system.js.First issue, resolved but unconvenient : ES6 modules paths must include the
'.js'
extension. Fortunately, TS 2.0+ knows how to resolveimport { Something } from './test.js'
intoimport { Something } from './test.ts'
while in dev. But it's a huge change to common practices and a lot of refactoring : official TypeScript docs, Angular, RxJS and so on have all encouraged until know to use the no extension form (import { Something } from './test'
).Second issue, unresolved : TS provides many options to tell the compiler how to resolve paths like
import { Component } from '@angular/core'
. But it never transforms the imported path in the compiled files.'@angular/core'
will stay'@angular/core'
in the transpiled files. After investigation, I've read in many issues it is by design.It's OK with loaders like system.js and others, which provide similar path mapping options. But with
<script type="module"><script>
, as far as I know, there is no configuration, soimport { Component } from '@angular/core'
will always fail.I am missing something, or does that really mean that we won't be able to use the native loader with TypeScript projects ?
If I'm right, is it possible to add an option to force path transformation in compiled files ?
The text was updated successfully, but these errors were encountered: