46

I installed chrome beta - Version 60.0.3112.24 (Official Build) beta (64-bit)

In chrome://flags/ I enabled 'Experimental Web Platform features' (see https://jakearchibald.com/2017/es-modules-in-browsers)

I then tried:

<script type="module" src='bla/src/index.js'></script>

where index.js has a line like:

export { default as drawImage } from './drawImage';

This refer to an existing file drawImage.js

what I get in the console is error in

GET http://localhost/bla/src/drawImage 

If I change the export and add ".js" extension it works fine.

Is this a chrome bug or does ES6 demands the extension in this case ?

Also webpack builds it fine without the extension !

kofifus
  • 17,260
  • 17
  • 99
  • 173
  • Yes, because a browser can't 'guess' what files exist on your server. It needs to have a full path. Node will check a few different file patterns because it's cheap, but this would be unacceptable in a browser. – Evert Feb 23 '22 at 20:14

3 Answers3

18

No, modules don't care about extensions. It just needs to be a name that resolves to a source file.

In your case, http://localhost/bla/src/drawImage is not a file while http://localhost/bla/src/drawImage.js is, so that's where there error comes from. You can either add the .js in all your import statements, or configure your server to ignore the extension, for example. Webpack does the same. A browser doesn't, because it's not allowed to rewrite urls arbitrarily.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • 8
    As a general statement this is incorrect: "modules don't care about extensions". Webpack may be able to resolve the file without `.js`, but browsers currently do not. – Luke Oct 08 '20 at 15:51
  • 2
    @Luke Browsers resolve the path to an url, but they don't do any magic about extensions because they don't know what resources exist on your webserver. They just fetch the resolved url. If your server actually has a module at the extension-less url, it does work fine as well. – Bergi Oct 08 '20 at 16:26
  • 1
    @gilamran What part of the answer is incorrect? I'd be happy to clarify. – Bergi Jul 08 '21 at 13:28
  • 1
    I'm taking it back, this is incorrect in nodejs environment – gilamran Jul 08 '21 at 19:37
  • 1
    @gilamran The first paragraph of the answer even applies to nodejs. The module doesn't care whether there is an extension or not. The name just needs to be resolvable by the environment - and sure, node does resolve "bare specifiers" differently than "relative specifiers". – Bergi Jul 08 '21 at 19:47
  • 1
    This answer is wrong. Check [this](https://stackoverflow.com/a/65790837/10908886) out. Or read the docs given in that answer. As it says: `7. If pjson?.type exists and is "module", then 7.1 If url ends in ".js", then 7.1.1 Return "module". 7.2 Throw an Unsupported File Extension error.` – Muhammed Aydogan Dec 31 '21 at 13:59
  • 1
    @MuhammedAydogan The answer you linked is about nodejs. The question I answered is about ES6 modules in browsers. – Bergi Dec 31 '21 at 14:24
  • @Bergi Oh, my bad. Tho it's written, the title of the question is misleading, I suggested an edit. – Muhammed Aydogan Dec 31 '21 at 14:43
16

The extension is part of the filename. You have to put it in.

As proof of this, please try the following:

  • rename file to drawImage.test
  • edit index.js to contain './drawImage.test'

Reload, and you'll see the extension js or test will be completely arbitrary, as long as you specify it in the export.

Obviously, after the test revert to the correct/better js extension.

Utmost Creator
  • 814
  • 1
  • 9
  • 21
pid
  • 11,472
  • 6
  • 34
  • 63
  • 3
    thx ! I'm confused as it seems that import does not need an extension ? also webpack works fine without the extension ! – kofifus Jun 11 '17 at 08:40
  • 1
    I've never tried those experimental features, but in node.js you use the `commonJS` mechanism. I've come across similar problems and the solution was to avoid letting the loader *guess* the extension. Also, if you have two files both may be viable, such as `data.js` and `data.json`. I think it's better to be explicit, but that's just my opinion. – pid Jun 11 '17 at 09:00
  • 2
    @pid yes better to be explicit, totally agree. if your environment allows other stuff, fine, but there's no reason for modules or module systems to guess – jimmont Aug 17 '18 at 23:42
10

ES6 import/export need “.js” extension. There are clear instructions in node document:

  1. Relative specifiers like './startup.js' or '../config.mjs'. They refer to a path relative to the location of the importing file. The file extension is always necessary for these.
  2. This behavior matches how import behaves in browser environments, assuming a typically configured server.

https://nodejs.org/api/esm.html#esm_import_expressions

谭礼渊
  • 125
  • 1
  • 3