7

Node now has built-in support for imports, which is awesome. But that support requires you to specify the file extension, which is annoying.

I'm sure there's some justification for why this is (likely having to do with their weird obsession with the .mjs extension), but is there any way to work around it and make import work "like normal" (where you can leave .js off)?

machineghost
  • 33,529
  • 30
  • 159
  • 234
  • Are you really sure that omitting get the .js extension is a good idea? I mean in a world where we have hundreds of file extensions whats to say that other developers are going to be able to distinguish between arbitrarily ```users.js``` or ```users.ts``` – Dan Starns Aug 15 '19 at 22:34
  • If 100% of my codebase is currently `.js` files, the (very small) possibility that some future percentage might be `.ts` files, and *those* (future, small possibility) files might have to specify ".ts" ... doesn't in any way take away the value of me not having to type three characters for literally every file in my codebase today. Even if I were to switch to Typescript tomorrow I'd still have saved a day of typing ".js", and I won't have lost anything: nothing I've written will in any way stop me from writing `import "foo.ts"` tomorrow. – machineghost Aug 15 '19 at 22:38
  • I do agree with your argument... However, by omitting the file extension, it's adding another layer of abstraction into your application and in my opinion very irresponsible. Even the creator of node Ryan Dahl [mentions](https://youtu.be/M3BM9TB-8yA?t=840) that this is one of his regrets. – Dan Starns Aug 15 '19 at 22:46
  • Yes this is needed. If you have users.js and users.ts in the same folder you have bigger problems. – Dirigible Apr 08 '20 at 21:18
  • Anybody figure out the solution to this? – Aditya Anand Jun 18 '20 at 13:26

2 Answers2

6

You can achieve this by setting "type": "module" on a top level of your package.json and running nodejs with --experimental-specifier-resolution=node command line switch (works for nodejs v14)

dobryy
  • 96
  • 1
  • 4
  • Personally I think `-r esm` is shorter/simpler, but yes this approach will also work if you're averse to using a 3rd party library. Also if you take this approach I think you *might* still need to rename some files, under some conditions, with the `.mjs` extension though (instead of `.js`). – machineghost Aug 06 '20 at 14:43
3

I fixed this was with the esm package.

In short, the Node organization has done an awful job of rolling out ES Module support, but the saving grace is that in the meantime the guy who made the Lodash library has already added far better support, and it's super easy to get.

Two steps:

  1. npm i esm
  2. node -r esm index.js (instead of just node index.js)

If you just do the above you don't need any special Node flags (like experimental-modules) or anything else, and ES Module syntax (import/export) will work perfectly in your application ... including not requiring .js in imports.

machineghost
  • 33,529
  • 30
  • 159
  • 234
  • _ES Module syntax (import/export) will work perfectly in your application_. Should that be the same case for native `addon`? I mean, can `import` we used with `addon`s? (or only [require](https://nodejs.org/api/addons.html#addons_loading_addons_using_require) can be used to import them) – rellampec Feb 23 '21 at 11:23
  • You can `import` them, using ES Module syntax. – machineghost Feb 24 '21 at 17:34
  • 2
    I just used this on my project and I'm getting an error `[ERR_REQUIRE_ESM]: Must use import to load ES Module` not sure exactly what's going wrong, but I will replace this comment if I find a soloution. – Sam Spade Mar 23 '21 at 20:56
  • @SamSpade: Ditto. Ever find a way forward? – kjhughes Oct 11 '21 at 21:42
  • 1
    @kjhughes Nope. Just added .js extensions to all my imports and gave up :/ – Sam Spade Oct 20 '21 at 19:09