kit icon indicating copy to clipboard operation
kit copied to clipboard

Example apps should include file extensions in import statements

Open GeoffreyBooth opened this issue 2 years ago • 8 comments

Describe the problem

Per @Rich-Harris in https://github.com/nodejs/node/issues/46074#issuecomment-1370102411:

. . . allowing modules to import each other without specifying the .js extension was a silly mistake that added untold complexity for no good reason. It makes authored code more ambiguous and less self-explanatory, makes runtimes slower, and adds a complexity tax to tooling that has compounded immeasurably over time. It was a horrible error.

I ran npm create svelte@latest today and chose “SvelteKit demo app,” “JavaScript with JSDoc comments” and looked around at the files, and many had references to extensionless files. For example, src/routes/sverdle/+page.server.js has import { Game } from './game'; (instead of ./game.js) and src/routes/sverdle/game.js has import { words, allowed } from './words.server'; (instead of ./words.server.js).

Describe the proposed solution

Let’s ensure that all the example import statements that refer to individual files (not library exports) include extensions, even for JavaScript files.

Alternatives considered

No response

Importance

nice to have

Additional Information

No response

GeoffreyBooth avatar Jan 04 '23 23:01 GeoffreyBooth

This is an unintended consequence of the fact that those files are generated from typescript source, but touché - we should definitely fix this

Rich-Harris avatar Jan 05 '23 00:01 Rich-Harris

While I agree this was a design mistake in node module resolution, I don't think we should change it right now.

  • people will probably be confused by it because it's not as common
  • even more so if you use typescript, where imports still need to have a .js ending
  • IDE auto imports will do all other file imports without the file ending (except you add a specific configuration, which almost noone uses), so you'll end up with a weird mix

dummdidumm avatar Jan 05 '23 08:01 dummdidumm

people will probably be confused by it because it's not as common

I don't agree with this — people might be surprised, because they're used to doing things wrong, but no-one will be confused by it since it reduces ambiguity.

even more so if you use typescript, where imports still need to have a .js ending

not sure I follow? I'm only suggesting we'd add the .js extension when starting a JavaScript project

IDE auto imports will do all other file imports without the file ending (except you add a specific configuration, which almost noone uses), so you'll end up with a weird mix

The VSCode default is to match existing imports — if you have an existing import foo from './foo' in a given module then bar will auto-import from ./bar, but if you have ./foo.js it will auto-import from ./bar.js. (It's true that if a module doesn't yet have any imports it will default to omitting the extension, which is a bafflingly short-sighted decision from the VSCode maintainers that I've tried in vain to change.) I don't know what other editors do.

Rich-Harris avatar Jan 05 '23 21:01 Rich-Harris

https://www.typescriptlang.org/docs/handbook/esm-node.html recommends including the .js in the import statement within TypeScript files intended for running as ESM in Node. Isn’t the solution here to just update the TypeScript files for the demo app to include .js? That should work for both the TypeScript version and the JavaScript one.

GeoffreyBooth avatar Jan 05 '23 21:01 GeoffreyBooth

The TypeScript files aren't intended for running as ESM in Node though — they're consumed via a bundler rather than transpiled 1:1. It would 'work' for the TypeScript case but I think it's just too weird to have modules explicitly referencing .js files that don't actually exist.

Rich-Harris avatar Jan 06 '23 00:01 Rich-Harris

Same is true for the JavaScript files though, it's all processed by Vite

dummdidumm avatar Jan 06 '23 07:01 dummdidumm

Of course, but the arguments in favour of using file extensions still hold

Rich-Harris avatar Jan 06 '23 13:01 Rich-Harris

FWIW TypeScript is introducing new moduleResolution options for 5.0, https://github.com/microsoft/TypeScript/issues/50152, which would allow using .ts extensions

gtm-nayan avatar Jan 12 '23 10:01 gtm-nayan

In which case we should definitely switch to using file extensions when 5.0 lands. In the meantime the question is whether 4.x's behaviour is reason enough to keep doing the wrong thing for JavaScript projects in the name of consistency, to which I would argue the answer is definitely 'no'

Rich-Harris avatar Feb 01 '23 20:02 Rich-Harris

Hi, I just wanted to bump this discussion now that TS 5.0 is well and truly out. "moduleResolution": "bundler" allows optional ".js" extensions in imports, as well as optional ".ts" extensions in imports if allowImportingTsExtensions is true. Since both svelte-kit and svelte-package build through Vite rather than tsc, I think this should be compatible with existing projects.

lachlancollins avatar Apr 30 '23 03:04 lachlancollins