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

New --emitExtension and --noImplicitExtensionName compiler options #35148

Closed
wants to merge 30 commits into from

Conversation

Jack-Works
Copy link
Contributor

@Jack-Works Jack-Works commented Nov 17, 2019

Related: denoland/deno#8529, #27957, #35749

fixes #30076, fixes #18442, fixes #16577, fixes #33306

See also: Node.js new ESModule support: https://medium.com/@nodejs/announcing-core-node-js-support-for-ecmascript-modules-c5d6dc29b663

Summary

image

Improve support for deno and browser style import. Note: This pr doesn't include URI style import resolution (https://deno.land/... or std:kv-storage...), about URI style import, see #35749

New --noImplicitExtensionName compiler options.

With this option on, the following code becomes invalid.

This new options will enforce developer to write valid import path on deno (noImplicitExtensionName + emitExtension=.ts) and ES Module for browser (noImplicitExtensionName + emitExtension=.js (default value)).

New --emitExtension compiler options.

This flag allows tsc to emit .mjs, .es.js, .es, .ts or any extension user specifies.

tsconfig.json

{ compilerOptions: { emitExtension: ".mjs", noImplicitExtensionName: true } }

Source files:

Emitted files:

Discussions

According to #35163 (comment) maybe --noImplicitExtensionName should be default to true when the target module system is ESModule

Details

Due to the ts meeting note for this pr (#35589 )
I decided to rewrite ts pr to follow the ts design principle.

  • Resolve TS file by --emitExtension
  • Type error for import with no extension name
  • Emit file as ext of emitExtension
  • Allow import .ts and .tsx file when emitExtension === .ts or .tsx
  • If the extension name !== emitExtension, emit a compile error

Resolve TS file by --emitExtension

Resolve type of import './x.mjs' to the file x.ts.
Will NOT rewrite the emitted file path.

@Jack-Works

This comment has been minimized.

@Jack-Works

This comment has been minimized.

@Jack-Works Jack-Works changed the title Allow import .ts and .tsx, New --emitExtension compiler options [Rewriting] New --emitExtension compiler options Dec 14, 2019
@Jack-Works Jack-Works changed the title [Rewriting] New --emitExtension compiler options New --emitExtension and --noImplicitExtensionName compiler options Dec 15, 2019
@Jack-Works
Copy link
Contributor Author

@DanielRosenwasser @RyanCavanaugh Hello, I have fully rewrittened this PR. Please checkout the new behavior! (There is no path rewriting anymore!)

@MicahZoltu
Copy link
Contributor

The thing that bugs me about including extensions as enforced by the noImplicitExtensions flag is that I don't necessarily know at dev time what the file extensions for my files will be. I commonly have two tsconfig.json files in my project, one for targeting es2015 modules and one for targeting commonjs modules. If I switch to targeting es2015 modules for both and instead change to having one emit .js and the other emit .mjs then using something like this will result in one of them generating bad code. If I hard-code .js in my import statements then the tsconfig that emits .mjs files will not work. If I hard-code .mjs in my import statements then the tsconfig that emits .js files will not work.

@Jack-Works
Copy link
Contributor Author

I'm sorry but the ts team doesn't accept the previous version of this pr that will do the extension name rewrite for you. So I think there is no way to resolve this problem. @MicahZoltu

@MicahZoltu
Copy link
Contributor

Yeah, I have been following along and am frustrated with the current situation. Browser and NodeJS have diverged, and TypeScript is caught in the middle with an unwillingness to resolve that divergence on behalf of users. This means TypeScript users are forced to "pick a side" and they can no longer write TypeScript that runs in both browser and NodeJS.

My plan for the time being is to continue using a TypeScript transformer to add the extension as part of the TSC build process. This way I can use a different transformer based on target without having to write TypeScript that has "picked a side".

@Jack-Works
Copy link
Contributor Author

I guess https://github.com/cevek/ttypescript is a good project to start with for your case

@Jack-Works
Copy link
Contributor Author

About deno & browser style import, see: #35749

@sandersn sandersn added the For Milestone Bug PRs that fix a bug with a specific milestone label Feb 1, 2020
@Jack-Works
Copy link
Contributor Author

Jack-Works commented Feb 8, 2020

if ts team ( @sandersn ) wants me to rebase my code to the latest codebase, @ me at any time!

@ExE-Boss
Copy link
Contributor

ExE-Boss commented Feb 8, 2020

Fixes #30076, #18442, #16577, #33306

You need to write the "fixes" keyword before each issue to close multiple issues.

@MrCheater
Copy link

+1

@sandersn
Copy link
Member

@rbuckton I added you as the main reviewer since #33306 was assigned to you for 3.8.1,
but @weswigham, can you review this too since you've spent a lot of time thinking about modules?

@dilyanpalauzov
Copy link

dilyanpalauzov commented May 13, 2020

I want to use TypeScript to check the types. But to compile the code fast I want to strip the types with @babel/preset-typescript.

When I write in some of my files import x from ./x.ts tsc 3.9.2 says: “An import path cannot end with a .ts extension”, but rollup/@rollup/plugin-babel/@babel-preset-typescript eat the input happy.

When I write instead import x from ./x.js, typescript does eat the input, but rollup/@rollup/plugin-babel/@babel/preset-typescript cannot find the file. Likewise, when I use import x from ./x.

This code, a.js:

import b from './b.ts'
console.log(b)

b.ts:

export default 'blub'

is valid JavaScript, it just does not work in Node.JS, as the latter refuses to accept .ts file extension.

But when b.ts is delivered with the correct mime type, then this works:

<html>
  <body><script type='module' src='./a.js'></script>
  Firefox and Epiphany print “blub” on the console.</body>
</html>

Demonstration: https://mail.aegee.org/dpa/35148/file.html

To sum up,

import b from './b.ts'

is valid JavaScript, and tsc refuses to accept valid JavaScript.

How to get now the same input working in both tsc 3.9.2 and rollup/@rollup/plugin-babel/@babel/preset-typescript?

rivy added a commit to rivy/js.os-paths that referenced this pull request Jan 7, 2021
- TypeScript fails to correctly generate an ESM module with correct line endings
  - ref: <microsoft/TypeScript#18442 (comment)>
  - ref: <microsoft/TypeScript#18442>
  - ref: <microsoft/TypeScript#37582>
  - ref: <microsoft/TypeScript#35148>
rivy added a commit to rivy/js.os-paths that referenced this pull request Jan 7, 2021
- TypeScript fails to correctly generate an ESM module with correct line endings
  - ref: <microsoft/TypeScript#18442 (comment)>
  - ref: <microsoft/TypeScript#18442>
  - ref: <microsoft/TypeScript#37582>
  - ref: <microsoft/TypeScript#35148>
rivy added a commit to rivy/js.os-paths that referenced this pull request Jan 7, 2021
- TypeScript fails to correctly generate an ESM module with correct line endings
  - ref: <microsoft/TypeScript#18442 (comment)>
  - ref: <microsoft/TypeScript#18442>
  - ref: <microsoft/TypeScript#37582>
  - ref: <microsoft/TypeScript#35148>
rivy added a commit to rivy/js.os-paths that referenced this pull request Jan 7, 2021
- TypeScript fails to correctly generate an ESM module with correct line endings
  - ref: <microsoft/TypeScript#18442 (comment)>
  - ref: <microsoft/TypeScript#18442>
  - ref: <microsoft/TypeScript#37582>
  - ref: <microsoft/TypeScript#35148>
rivy added a commit to rivy/js.os-paths that referenced this pull request Jan 10, 2021
- TypeScript fails to correctly generate an ESM module with correct line endings
  - ref: <microsoft/TypeScript#18442 (comment)>
  - ref: <microsoft/TypeScript#18442>
  - ref: <microsoft/TypeScript#37582>
  - ref: <microsoft/TypeScript#35148>
rivy added a commit to rivy/js.os-paths that referenced this pull request Jan 11, 2021
- TypeScript fails to correctly generate an ESM module with correct line endings
  - ref: <microsoft/TypeScript#18442 (comment)>
  - ref: <microsoft/TypeScript#18442>
  - ref: <microsoft/TypeScript#37582>
  - ref: <microsoft/TypeScript#35148>
rivy added a commit to rivy/js.os-paths that referenced this pull request Jan 11, 2021
- TypeScript fails to correctly generate an ESM module with correct line endings
  - ref: <microsoft/TypeScript#18442 (comment)>
  - ref: <microsoft/TypeScript#18442>
  - ref: <microsoft/TypeScript#37582>
  - ref: <microsoft/TypeScript#35148>
rivy added a commit to rivy/js.os-paths that referenced this pull request Jan 11, 2021
- TypeScript fails to correctly generate an ESM module with correct line endings
  - ref: <microsoft/TypeScript#18442 (comment)>
  - ref: <microsoft/TypeScript#18442>
  - ref: <microsoft/TypeScript#37582>
  - ref: <microsoft/TypeScript#35148>
rivy added a commit to rivy/js.os-paths that referenced this pull request Jan 11, 2021
- TypeScript fails to correctly generate an ESM module with correct line endings
  - ref: <microsoft/TypeScript#18442 (comment)>
  - ref: <microsoft/TypeScript#18442>
  - ref: <microsoft/TypeScript#37582>
  - ref: <microsoft/TypeScript#35148>
rivy added a commit to rivy/js.os-paths that referenced this pull request Jan 11, 2021
- TypeScript fails to correctly generate an ESM module with correct line endings
  - ref: <microsoft/TypeScript#18442 (comment)>
  - ref: <microsoft/TypeScript#18442>
  - ref: <microsoft/TypeScript#37582>
  - ref: <microsoft/TypeScript#35148>
rivy added a commit to rivy/js.os-paths that referenced this pull request Jan 11, 2021
- TypeScript fails to correctly generate an ESM module with correct line endings
  - ref: <microsoft/TypeScript#18442 (comment)>
  - ref: <microsoft/TypeScript#18442>
  - ref: <microsoft/TypeScript#37582>
  - ref: <microsoft/TypeScript#35148>
rivy added a commit to rivy/js.os-paths that referenced this pull request Jan 11, 2021
- TypeScript fails to correctly generate an ESM module with correct line endings
  - ref: <microsoft/TypeScript#18442 (comment)>
  - ref: <microsoft/TypeScript#18442>
  - ref: <microsoft/TypeScript#37582>
  - ref: <microsoft/TypeScript#35148>
rivy added a commit to rivy/js.os-paths that referenced this pull request Jan 11, 2021
- TypeScript fails to correctly generate an ESM module with correct line endings
  - ref: <microsoft/TypeScript#18442 (comment)>
  - ref: <microsoft/TypeScript#18442>
  - ref: <microsoft/TypeScript#37582>
  - ref: <microsoft/TypeScript#35148>
rivy added a commit to rivy/js.os-paths that referenced this pull request Jan 11, 2021
- TypeScript fails to correctly generate an ESM module with correct line endings
  - ref: <microsoft/TypeScript#18442 (comment)>
  - ref: <microsoft/TypeScript#18442>
  - ref: <microsoft/TypeScript#37582>
  - ref: <microsoft/TypeScript#35148>
@shrinktofit
Copy link

What's the status?

@Jack-Works
Copy link
Contributor Author

Typescript team rejected this idea 😭

rivy added a commit to rivy/js.xdg-portable that referenced this pull request Jan 26, 2021
…tensions)

- TypeScript fails to correctly generate an ESM module with correct file extensions
  - ref: <microsoft/TypeScript#18442 (comment)>
  - ref: <microsoft/TypeScript#18442>
  - ref: <microsoft/TypeScript#37582>
  - ref: <microsoft/TypeScript#35148>
@awkj

This comment has been minimized.

@timreichen
Copy link

timreichen commented Apr 25, 2021

@Jack-Works Why?

@knightedcodemonkey
Copy link

There are some options for dealing with this that might suit some use cases described here:

  • @knighted/specifier for changing your ESM/CJS specifiers as you see fit.
  • @knighted/duel for creating dual TypeScript packages with correct file and specifier extensions.
  • babel-dual-package similar to @knighted/duel except using Babel and @babel/preset-typescript.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Declined The issue was declined as something which matches the TypeScript vision For Milestone Bug PRs that fix a bug with a specific milestone
Projects
Archived in project