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

Non-script entries should append .js, not replace extension. #1667

Open
dzearing opened this issue Oct 7, 2021 · 2 comments
Open

Non-script entries should append .js, not replace extension. #1667

dzearing opened this issue Oct 7, 2021 · 2 comments
Labels

Comments

@dzearing
Copy link

dzearing commented Oct 7, 2021

I have a non-script entry, like "Foo.scss" or "Foo.json". I have loaders set up to convert these to modules.

Expected:
The output file is named "Foo.scss.js" or "Foo.json.js".

Resulted:
The output file's extension is replaced "Foo.js", removing the ability to distinguish it from other entries like "Foo.tsx".

(Note: totally makes sense to replace the extension for .ts | .tsx | .jsx, but for non-script entries, it's preferred to retain the original extension for differentiation. It makes importing the file across externalized boundaries seamless. (e.g. you can import Foo.scss and the module system will resolve to Foo.scss.js without custom loaders.)

@evanw evanw added the breaking label Oct 8, 2021
@evanw
Copy link
Owner

evanw commented Oct 8, 2021

Marking this as breaking because this would be a breaking change if it were made, and would require a non-patch version bump to avoid accidentally breaking people who automatically accept non-breaking upgrades.

@nicoburns
Copy link

nicoburns commented Jan 20, 2022

@evanw

I would like to add a +1 for this change or something similar. As far as I can tell, importing non-JS/TS files from a TypeScript file using es6 import syntax is currently impossible in a node.js environment where esbuild is being used without bundling (two examples I've tried so far are importing json files, and importing .sql as a plain string)

To illustrate why this causes a problem, consider the following setup:

foo.ts

import bar from 'IMPORT_PATH_HERE';
console.log(bar.hello);

bar.json

{
   "hello": "world"
}

The problem is what IMPORT_PATH_HERE should be set to:

  • If I set IMPORT_PATH_HERE to./bar.json then the import will fail at runtime as the file won't be found as esbuild changes the filename to bar.js when copying the file to the output directory.
  • If I set IMPORT_PATH_HERE './bar` then the code runs completely correctly at runtime, but the TypeScript type checker can no longer find the file causing it to fail.

The only way I could get this to work was to resort to a dynamic require like const bar = require(path.resolve(__dirname, 'bar.json));, which works but loses all type information.

IMO the correct fix here is for esbuild to make import bar from './bar.json' work, either by renaming the json file in the output or by rewriting the input path in the output javascript.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants