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

Resolve .tsx + other extensions when importing .js / .jsx files #112

Closed
1 task
karlhorky opened this issue Oct 5, 2022 · 15 comments
Closed
1 task

Resolve .tsx + other extensions when importing .js / .jsx files #112

karlhorky opened this issue Oct 5, 2022 · 15 comments
Labels
bug Something isn't working outdated resolver

Comments

@karlhorky
Copy link

karlhorky commented Oct 5, 2022

Bug description

Hi there, thanks for tsx, looks like a great project! 🙌

It would be great if tsx could also support the same module resolution that tsc does - specifically, resolving *.tsx files when a fully-specified .js ESM-style import is used.

tsc allows:

  • .js to resolve .ts (supported by tsx)
  • .js to resolve .tsx (unsupported by tsx)
  • .jsx to resolve .ts (unsupported by tsx)
  • .jsx to resolve .tsx (unsupported by tsx)
  • (maybe others?)

Ref: microsoft/TypeScript#41887 (comment)

More details on what tsc and esbuild currently support

Reproduction

$ ls *.ts*
abc.tsx  def.ts  index2.ts  index.ts
$ cat index.ts
import abc from './abc.js';
console.log(abc);
$ cat abc.tsx
export default 'abc';

$ npx tsx index.ts
Error: Cannot find module './abc.js'
Require stack:
- /home/runner/JuicySphericalDistributedcomputing/index.ts
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.u.default._resolveFilename (/home/runner/JuicySphericalDistributedcomputing/node_modules/@esbuild-kit/cjs-loader/dist/index.js:1:1486)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.<anonymous> (/home/runner/JuicySphericalDistributedcomputing/index.ts:1:17)
    at Module._compile (node:internal/modules/cjs/loader:1105:14)
    at Object.v (/home/runner/JuicySphericalDistributedcomputing/node_modules/@esbuild-kit/cjs-loader/dist/index.js:1:933)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [ '/home/runner/JuicySphericalDistributedcomputing/index.ts' ]
}

However, importing *.ts files using a fully-specified .js path works:

$ ls *.ts*
abc.tsx  def.ts  index2.ts  index.ts
$ cat index2.ts
import def from './def.js';
console.log(def);
$ cat def.ts
export default 'def';

$ npx tsx index2.ts
def

Replit demo (use the "Shell" tab): https://replit.com/@karlhorky/JuicySphericalDistributedcomputing#index.ts

Environment

  System:
    OS: Linux 5.15 Ubuntu 20.04.2 LTS (Focal Fossa)
    CPU: (8) x64 AMD EPYC 7B12
    Memory: 51.31 GB / 62.80 GB
    Container: Yes
    Shell: 5.0.17 - /bin/bash
  Binaries:
    Node: 16.15.0 - /nix/store/amm5j0ag985nh49n096a78q1dfs2xsfn-nodejs-16.15.0/bin/node
    Yarn: 1.22.18 - /nix/store/lccjrdddvk1bvd8zl29bd09df2z7d5p3-yarn-1.22.18/bin/yarn
    npm: 8.5.5 - /nix/store/amm5j0ag985nh49n096a78q1dfs2xsfn-nodejs-16.15.0/bin/npm
  npmPackages:
    tsx: ^3.9.0 => 3.9.0

Related issues

This is a superset of esbuild-kit/esm-loader#74

Can you contribute a fix?

  • I’m interested in opening a pull request for this issue.
@karlhorky karlhorky added bug Something isn't working pending triage labels Oct 5, 2022
@karlhorky karlhorky changed the title Resolve .tsx, other extensions when importing .js / .jsx files Resolve .tsx + other extensions when importing .js / .jsx files Oct 5, 2022
@jraoult
Copy link

jraoult commented Oct 9, 2022

I'm hitting the same issue. I suspect this will be solved when #344 is.

@mshima
Copy link

mshima commented Oct 9, 2022

To fix this, you will need to patch the resolveTsPath and related mapper.
resolveTsPath will need to return an array so a core-utils breaking change or duplicate the function and deprecated the old to avoid the breaking change.

And change it's usage to handle the returned array in a loop at https:/esbuild-kit/cjs-loader/blob/e7ba7caf42cb1bdceacb0bcafd2db3fd747931c0/src/index.ts#L179

@mshima
Copy link

mshima commented Oct 9, 2022

#344 could be refactored to use this new resolveTsPath

@jraoult
Copy link

jraoult commented Oct 9, 2022

@mshima I have to confess I didn't try too hard to get into the details, but my use case is with ESM. I patched esm-loader with a rebased version of your PR (on top of main) and adding the .js to .tsx mapping worked like a charm for me.

@mshima
Copy link

mshima commented Oct 9, 2022

@jraoult great, just saying the reproduction case is commonjs:

    at Module.require (node:internal/modules/cjs/loader:1005:19)

For esm, the PR change should fix the issue.

@karlhorky
Copy link
Author

karlhorky commented Oct 9, 2022

What extension resolutions do tsc and esbuild support?

See this Replit with a demo of what tsc supports: https://replit.com/@karlhorky/TypeScript-tsc-extension-resolution-js-jsx-cjs-mjs#index.ts

All of these extensions work (at least, they do not throw an error running tsc):

Screen Shot 2022-10-09 at 16 51 13


I also made a Replit with [email protected] on its own (no tsx or tsc) to test the resolution of all extensions (using --bundle mode), and it seems that they are all respected:

https://replit.com/@karlhorky/esbuild-extension-resolution-js-jsx-cjs-mjs#index.ts

Screen Shot 2022-10-09 at 18 16 41

@aredridel
Copy link

This affects our codebase too, with moduleResolution: "Node16", and our imports are fully specified .mjs, and it fails to look up the equivalent .mts.

@privatenumber
Copy link
Owner

@aredridel

The problem you're describing is different from what the issue is reporting.
Resolving .mjs -> .mts works: https://stackblitz.com/edit/node-3oq8qv?file=index.ts

Please open a new issue with reproduction if it doesn't work for you.

@karlhorky
Copy link
Author

tsm implemented imports from the new file extensions over here, in case this is inspiration for an implementation in tsx:

@wesbos
Copy link

wesbos commented Jan 18, 2023

Also hitting this issue. Migrating a codebase to TypeScript and I'm importing a .ts file from a .js file.

tsc will follow a .js import to it's real .ts location. tsx wont - it complains the module is not found.

Using .ts extension fixes it in tsx, but then tsc` complains of not finding the file.

using tsx for dev and tsc to compile for production.

@karlhorky
Copy link
Author

karlhorky commented Jan 19, 2023

I'm importing a .ts file from a .js file

This sounds similar, but not really the same issue that I described above - I am not using any .js files.

Probably deserves a new issue for this, maybe also good to report one for tsm if it has the same behavior.

@privatenumber
Copy link
Owner

Yep, it's this: #135

@privatenumber
Copy link
Owner

All TypeScript extensions should be supported now in https:/privatenumber/tsx/releases/tag/v4.0.0

Tests: https:/privatenumber/tsx/blob/v4.0.0/tests/specs/smoke.ts#L515-L533

Hope this new release works well for you!

@karlhorky
Copy link
Author

@privatenumber Thanks! Can confirm that [email protected] works for our projects, which include imports with .js extensions which now resolve correctly to their .tsx files on disk.

@spearmootz
Copy link

im doing import x from "sample.js" the read file is sample.ts

i get Cannot find module. i have TSX version 4.6.2 on node 16.14.2

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 10, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working outdated resolver
Projects
None yet
Development

No branches or pull requests

7 participants