Skip to content
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

Allow extensions in local import paths (again) #11901

Closed
mavericken opened this issue Oct 27, 2016 · 8 comments
Closed

Allow extensions in local import paths (again) #11901

mavericken opened this issue Oct 27, 2016 · 8 comments

Comments

@mavericken
Copy link

Between TypeScript 2.0 Beta and now, ability to specify the file extension in relative path imports is gone. It appears to have been done intentionally.

Example, we used to be able to this.

import {view} from './front.tsx'
import {store} from './store'

But now:
image

For people who don't need the feature, they can simply not use it.
For people who do need it, its removal substantially complicates things.

@mhegazy
Copy link
Contributor

mhegazy commented Oct 27, 2016

how is the .tsx loaded at runtime?

@mavericken
Copy link
Author

mavericken commented Oct 27, 2016

Interesting question... it looks like it actually works anyways. So then is this just a problem with the language service?

Edit: I suppose I need more to add more detail here. I am using Visual Studio Code 1.6.1, and I don't see the error when I point my typescript.tsdk to 2.0.0beta, but I do see the error when I point to 2.0.6. That's why I assumed the problem was with TypeScript itself and not VSCode.

@aluanhaddad
Copy link
Contributor

aluanhaddad commented Oct 27, 2016

@mavericken Older versions of TypeScript allowed this, but it is now an error and that is a very good thing too.
Code like that is not portable and for no good reason.
Let's suppose, to answer @mhegazy's question, that you are using SystemJS with plugin-typescript to load the file. It would work if you had the following configuration loaded beforehand.

SystemJS.config({ meta: { '*.tsx': { loader: 'plugin-typescript'} } });

But what if you, or someone else, compiled the file in some other way? For example, say you used

> tsc ./utils.tsx --outDir ../dist

If you try to load ./utils.tsx from ../dist, an error occurs because there is no such file, rather there is utils.js. Worse, you cannot fix the error with config e.g. *.tsx: { defaultExtension: 'js' } because your file would then be loaded as ./utils.tsx.js.
Either use no extension or use .js.
Personally I think no extension is much better for portability as it doesn't assume how, when, or by what you code is being compiled.

Of course you may be using a different environment, but omit the .tsx, it is an error.

@mavericken
Copy link
Author

@aluanhaddad After trying to come up with arguments against your points, I can see why this change was made now.

@tolu
Copy link

tolu commented Aug 20, 2017

@aluanhaddad I'd really like to open this issue again for another reason - using modules natively in the browser.

I'm working on a PWA that uses native JS modules for browsers that handle them and a fallback bundle for everyone else.
For this i run tsc on my /src folder and output to /js with target esnext.
The bundle is created with webpack with ts-loader using target es2016.

That means that the browser fails to load imported modules if the extension is missing since my server can't know that a specific route should resolve as a *.js file.
This can of course be solved with a specific server setup but I want this to be a static website that can run on GitHub pages and then we have a problem.

This is basically my setup:

index.html

        <!-- html, head, body etc... -->
        <script type="module" src="dist/main.js"></script>
        <script nomodule src="dist/bundle.js"></script>
    </body>
</html>

src/main.ts

import dep from './dep'; // network request fails if ".js" is not specified
import dep from './dep.ts'; // transpile fails if ".ts" is specified
import dep from './dep.js'; // bundle fails is ".js" is specified

If I'm not missing some simple way of solving this (please let me know!) I would think that this could be common use case that others will run into when building and playing with the newest browser and javascript features.

@wujohns
Copy link

wujohns commented Oct 26, 2017

@aluanhaddad without the file extension, the code can't be compiled when using webpack

@aluanhaddad
Copy link
Contributor

It is now possible to write

import a from './a.js';

and TypeScript will resolve it to './a.ts' at design time.

My remarks were made when I had more hope for the loader spec actually being practical.

We've ended up with an anemic living standard that hasn't even decided if it will support path mapping and bare name resolution yet.

I also don't see this as only a TypeScript issue because it affects anyone depending on code that doesn't itself specify file extensions.

I was saying that it's a good idea to omit the extensions because then you can let your loader or environment determine what the default should be in each context. I still feel that way except that the loader specification doesn't provide for anything of the sort.

You're absolutely correct that we shouldn't have to depend on server rewrites and moreover, those can only get you so far.

What I'm saying is that what browsers currently implement is woefully insufficient.

@lastmjs
Copy link

lastmjs commented Mar 16, 2018

@aluanhaddad For some use cases you might want to omit the file extension, for other use cases, @tolu and my own, you may desire to put in explicit file extensions. I don't see why TypeScript itself should be discriminating and telling us which extensions are allowed and which are not. The module spec says nothing about file extensions, so why does TypeScript? Could this be reopened and addressed? My build process works just fine whether or not TypeScript gives me an error for explicitly putting a .ts extension, but it would be great to not have the squiggly red lines telling me I'm doing something wrong when I'm really not

@microsoft microsoft locked and limited conversation to collaborators Jul 25, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants