pzavolinsky / ts-unused-exports

ts-unused-exports finds unused exported symbols in your Typescript project

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support recognizing TypeScript files imported with `.js` suffix

mon-jai opened this issue · comments

commented

In TypeScript, it is valid to import TypeScript files with .js extension. TypeScript will match the coresponding .ts files if they exist. This behaviour is commonly used in Node.js projects as .js file extensions are required in Node.js ESM imports.

It would be great if ts-unused-exports also recognize variable imported with .js suffix.

Related: evanw/esbuild#1343 (comment), microsoft/TypeScript#16577 (comment), microsoft/TypeScript#16577 (comment)

Example

In this example project derived from example/simple, inc() from math.ts was imported with .js extension.

import inc from './math.js';

And TypeScript recognize it sucessfully.

56-18-22-235633

However, ts-unused-exports failed to recognize that the default import ofmath.ts was imported in app.ts.

Screenshot 2022-02-19 000527

hm I'm not sure we will support imports of .js files in this way.

That link seems to be discussing ECMAScript (the spec for JavaScript).

However ts-unused-exports currently processes TypeScript.

Besides that, I don't really understand why this feature would be needed - isn't it possible use all TypeScript with Node.js ?

Perhaps if you can explain the use case a bit more, that would help ...

commented

.js file extensions are required by Node.js ESM imports, and TypeScript won't add them for you by design.

Therefore, for any project that output target is ES6 or above, all import statements must be ended with .js extension (in TypeScript source files), so the compiled output will contain file extensions in import statements, and work on Node.js.

In fact, example/simple only works when the output format is set to commonjs. If I modify it to output ESM instead,

"target": "es6",
"module": "es6",

the compiled output won't run.

$ tsc && node app.js
node:internal/process/esm_loader:94
    internalBinding('errors').triggerUncaughtException(
                              ^

Error [ERR_MODULE_NOT_FOUND]: Cannot find module 'D:\GitHub\ts-unused-exports\example\simple\math' imported from D:\GitHub\ts-unused-exports\example\simple\app.js
Did you mean to import ../math.js?
    at new NodeError (node:internal/errors:371:5)
    at finalizeResolution (node:internal/modules/esm/resolve:394:11)
    at moduleResolve (node:internal/modules/esm/resolve:944:10)
    at defaultResolve (node:internal/modules/esm/resolve:1041:11)
    at ESMLoader.resolve (node:internal/modules/esm/loader:530:30)
    at ESMLoader.getModuleJob (node:internal/modules/esm/loader:251:18)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:79:40)
    at link (node:internal/modules/esm/module_job:78:36) {
  code: 'ERR_MODULE_NOT_FOUND'
}

Node.js v17.4.0

So if I am developing a project which must output ESM code, ts-unused-exports won't work for it.

Edit: explain the issue more clearly.

commented

Specifying the .js extension is the only way to load TypeScript files when using Node with native ES Modules, as ESM requires the extension to be specified and as @mon-jai said, TypeScript decided to not modify import paths at all (not replacing .ts with .js and not adding .js if the extension is unspecified)

Currently having to disable this tool in all our repos since migrating to node16/esm. There are plenty of details in the ts docs if you need to understand why we have to import like this now @mrseanryan .

Hello - this is somewhat tricky to add support for...

Here is a PR that adds initial support:

#255

If someone can try it out, that would be great ...

Released as 9.0.0 - thank you