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

Node16 module resolution doesn't check side effect imports #50394

Closed
alecmev opened this issue Aug 21, 2022 · 8 comments Β· Fixed by #58941
Closed

Node16 module resolution doesn't check side effect imports #50394

alecmev opened this issue Aug 21, 2022 · 8 comments Β· Fixed by #58941
Labels
Domain: Node ESM Like ES Modules, but specific to Node.js support (cts, cts, mjs, mts) In Discussion Not yet reached consensus Suggestion An idea for TypeScript

Comments

@alecmev
Copy link

alecmev commented Aug 21, 2022

Bug Report

πŸ•— Version & Regression Information

This is the behavior in every version I tried, and I reviewed the FAQ for entries about this.

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

// @module: Node16
import "./file";

πŸ™ Actual behavior

TypeScript says nothing.

πŸ™‚ Expected behavior

I want TypeScript to tell me that .js is missing, the same way it does in any other type of import. I think I understand why it doesn't right now, because side effects have nothing to do with static analysis, so the incorrectness of the import doesn't prevent TypeScript from doing its job in any way, but:

  1. I haven't been able to set this up in the bug workbench, but what happens if the file is being imported from node_modules and has a corresponding .d.ts with a declare ... in it? Will that declare get applied?
  2. Wouldn't this be useful to have either way? I guess ESLint could fill this void, but seeing how eslint-plugin-import is dragging its feet on import/extensions, there's little hope for that.

Apologies if this has been addressed before, couldn't find.

@DanielRosenwasser DanielRosenwasser added Suggestion An idea for TypeScript In Discussion Not yet reached consensus labels Aug 23, 2022
@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented Aug 23, 2022

I believe that this has come up in discussion with @andrewbranch recently. I think that Node16 users probably want to get an error under this mode, but it's hard to say - plus those users need an alternative option if they are trying to get export maps working in conjunction with a bundler.

@DanielRosenwasser DanielRosenwasser added the Domain: Node ESM Like ES Modules, but specific to Node.js support (cts, cts, mjs, mts) label Aug 23, 2022
@fatcerberus
Copy link

I think that Node16 users probably want to get an error under this mode, but it's hard to say - plus those users need an alternative option if they are trying to get export maps working in conjunction with a bundler.

wait, I’m confused - why is this a concern only for side-effect imports?

@andrewbranch
Copy link
Member

I also don’t understand that sentence πŸ€”

@andrewbranch
Copy link
Member

The reason why this isn’t a no-brainer is that it’s common to do

import "./styles.css"

with certain bundler configurations in order to add globally-applicable CSS to the bundle. We don’t check existence of files with arbitrary extensions, so in order to make this resolve, you’d have to add a pattern ambient module for ".*css" or a file at styles.d.css.ts via #51435. But both of these feel a bit pointless for a side-effect import, since the types written in that declaration will never be observed.

I think I would want module resolution to be able to say β€œthere is a file here, but I didn’t read it because it has an unsupported extension” so we could count that as a successful resolution for a side-effect import. That’s a bigger change than just unsilencing an error.

@fatcerberus
Copy link

Perhaps the error should only be unsilenced in bundler resolution mode, assuming that's still planned to be a thing (I haven't been following it too closely as I'm more interested in minimal--browser ESM mode--which is on hold). That CSS import doesn't really make sense outside the context of a toolchain that's actually going to do something with it; even if the runtime understood it, I have to imagine it'd be a no-op pretty much for the same reason it is in TS.

But both of these feel a bit pointless for a side-effect import, since the types written in that declaration will never be observed.

Hmm, in theory though, the types (if they exist) might still be observable if the .d.ts includes any global declarations, right? Is import type 'foo'; a thing?

@andrewbranch
Copy link
Member

You’re right, any global declarations would be observed (and there is no import type "foo"). That just doesn’t seem like what you want if you’re just trying to load a CSS file globally or something.

@qwelias
Copy link

qwelias commented Nov 30, 2023

TS has nothing to do with people importing css or whatever up the toolchain, as a TS user I expect TS to be consistent in it's guarantees, including guarantees on module existence checks.

"Let's ignore module existence checks if it's a side-effect import because someone may import a stylesheet"
Like imagine not requiring a driver to stop at red light if they're a tourist because what if in the country they're from it's ok.

@jakebailey
Copy link
Member

For fun, I have sent #58941 which adds a resolveSideEffectImports option; it seems to catch everything people have already mentioned here, but a lot of things on DefinitelyTyped which I think are actually accidentally broken.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Domain: Node ESM Like ES Modules, but specific to Node.js support (cts, cts, mjs, mts) In Discussion Not yet reached consensus Suggestion An idea for TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants
@DanielRosenwasser @alecmev @andrewbranch @fatcerberus @jakebailey @qwelias and others