lukeed / tsm

TypeScript Module Loader
MIT License
1.18k stars 19 forks source link

support `.js` extension for imports in `.ts` files #1

Closed dominikg closed 2 years ago

dominikg commented 2 years ago

It is supported in ts-node/esm and according to typescript that's the recommended way to import https://twitter.com/orta/status/1444958295865937920

foo.ts

import bar from './bar.js'  // bar.js does not exist on disk, it is the transpilation result of bar.ts

Right now this fails with ENOENT, here's how it looks like in uvu's typescript.module example when you use math.ts and utils.ts instead of .js

devDependencies:
+ loadr 0.1.1
+ tsm 2.0.0
+ uvu 0.5.1
dominikg@mb14:~/develop/uvu/examples/typescript.module$ pnpm test

> @ test /home/dominikg/develop/uvu/examples/typescript.module
> tsm node_modules/uvu/bin.js tests

(node:8503) ExperimentalWarning: --experimental-loader is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
Error: ENOENT: no such file or directory, open '/home/dominikg/develop/uvu/examples/typescript.module/src/math.js'
lukeed commented 2 years ago

Waiting on the next version of esbuild which might handle this automatically: https://github.com/evanw/esbuild/issues/1505#issuecomment-934070846

Also, TS 4.5 is still in beta so this isn't officially doable yet

lukeed commented 2 years ago

Also, could you just drop the extension in this case?

import * as math from '../src/math';
// resolves to math.ts cuz it exists

That uvu example only includes the ".js" extension inside the import to match the reproduction it was closing. The other "typescript" example doesn't include extensions in the imports because TS has never needed it when importing another TS file.

For example: https://github.com/lukeed/uvu/blob/master/examples/typescript/tests/math.ts#L3

dominikg commented 2 years ago

My understanding of authoring typescript esm is that you should always use import from 'foo.js' in .ts files , not import from 'foo.ts' or import from 'foo'. - Please correct me if i'm wrong here. Dropping the extension works, but if using .js is the official recommendation, tsm should support it.

regarding typescript 4.5: I think that only adds support for mts/cts, 4.4 already works with "type": "module" in package.json and .ts files importing .js extension

lukeed commented 2 years ago

I've always left off extensions, but I also always only use TS alongside a bundler of some kind, so it doesn't matter. Going extension-less & relying on tsc output alone to produce JS files (with ESM flavor) would put you in a bad spot since the output also wouldn't include an extension, making the ESM runtime (node or browser) bail.

But you're right, it should match.

Playing with it now – fairly easy on the ESM side. Unblocking --require tsm might be a little trickier.

lukeed commented 2 years ago

Resolved :) Thanks for opening this up

karlhorky commented 2 years ago

I think these fully-specified ESM paths (with extensions) may not be fully working yet - eg. with other extensions such as .tsx:

$ ls
index.ts                            abc.tsx

$ cat index.ts
import abc from './abc.js';

$ yarn tsm index.ts
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/k/p/project/abc.js' imported from /Users/k/p/project/index.ts
    at new NodeError (node:internal/errors:371:5)
    at finalizeResolution (node:internal/modules/esm/resolve:416:11)
    at moduleResolve (node:internal/modules/esm/resolve:932:10)
    at defaultResolve (node:internal/modules/esm/resolve:1044:11)
    at resolve (file:///Users/k/p/project/node_modules/tsm/loader.mjs:1:870)
    at Loader.resolve (node:internal/modules/esm/loader:89:40)
    at Loader.getModuleJob (node:internal/modules/esm/loader:242:28)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:76:40)
    at link (node:internal/modules/esm/module_job:75:36)
    at processTicksAndRejections (node:internal/process/task_queues:96:5) {
  code: 'ERR_MODULE_NOT_FOUND'
}

tsc resolves the file just fine:

$ yarn tsc
✨  Done in 0.81s
karlhorky commented 2 years ago

Should I open a new issue for that?

karlhorky commented 2 years ago

Opened a PR instead: https://github.com/lukeed/tsm/pull/33

karlhorky commented 1 year ago

Nice, tsm@2.3.0 (PR #43) is working, thanks! 🙌