17

I am creating an single page app in vanilla JavaScript. I want to organize my code in different files to make it modular, which means I should be able to access functions defined in one file in another file. I am using ES6 native import export for this:

file-1.js:

export function func1() {}
export function func2() {}

file-2.js:

import { func1, func2 } from './file-1';

index.html:

<script src="file-1.js"></script>

When I run index.html in Chrome (version 65), I get the following error: Uncaught SyntaxError: Unexpected token {.

What's wrong in my code? Chrome 65 fully supports ES6 module system.

darKnight
  • 5,651
  • 13
  • 47
  • 87

2 Answers2

24

Here is a working example

file1.mjs

function log1() {
  console.log('log1');
}
function log2() {
  console.log('log2');
}
export { log1, log2 };

file2.mjs you must explicitly write .mjs extension

import { log1, log2 } from './file1.mjs';

log1();
log2();

index.html Notice attribute type="module"

<body>
    <script type="module" src="file2.mjs"></script>
</body>

Then you need a static server to get rid of CORS block.

$ yarn global add serve
$ serve ./

Finally go to http://localhost:5000 and it will work

Update: It is recommended to use .mjs file extension for modules instead of .js

Community
  • 1
  • 1
Cuong Vu
  • 3,423
  • 14
  • 16
  • Where is the actual CORS happening here? I have everything from your answer, except the last part (static server) and I don't even see request for my module (file2.js) happening at all. – croraf Nov 09 '18 at 14:21
  • Something has changed inside Chrome, now it doesn't even notify the CORS block in the console tab anymore. I'm not sure but maybe Chrome's file:// protocol has some specific rules so that the requests were not shown in the Chrome Dev Tools. But you should always use a local server to work with Javascript on the browser so you can replicate a real website while developing. – Cuong Vu Nov 09 '18 at 15:23
  • Using a server the "import" syntax indeed does work. Thanks. Where do you think CORS happens in the above case? – croraf Nov 09 '18 at 15:58
  • As I said, in some previous versions of Chrome, it used to explicitly notify problem in ***CONSOLE*** tab when using `file://` protocol. – Cuong Vu Nov 09 '18 at 16:00
  • 1
    You don't need to use .mjs extension as you mentioned in the edit. I'm doing it on chrome with .js using a server. Regarding CORS, I see now the articles that "file://" protocol can cause CORS issues on some browsers. Unfortunately if CORS indeed is a problem, it's a pitty there is no more warning in the console. – croraf Nov 09 '18 at 16:08
  • Got the same issue. Including type=' module' such an important thing to get it work, start a local server to use http:// protocol rather than file:// one cuz the CORS policy blocking your file from executing in Chrome v70+ `Access to script at 'file:///*.js' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.` – Khoa Nguyen Sep 07 '19 at 09:50
4

Chrome (v70) has some kind of issues when working with import syntax on the local files served using file protocol. It is probably CORS blocking that can happen using file protocol according to some articles. But Chrome also does not show CORS warning in the console in this case - which is strange. Therefore some kind of HTTP server is needed so the files are served via HTTP protocol (as Vu showed in his answer). Firefox v63 (probably >v60) doesn't have these issues and you can compose html with js modules using file:// protocol without a special server.

Also make sure to:

  • use file type extensions when importing (import { func1, func2 } from './file-B.js';).

  • use type="module" in html script element (<script type="module" src="file-A.js"></script>)

croraf
  • 4,332
  • 2
  • 31
  • 50
  • 1
    Actually we can ignore browser CORS policy like this [How to launch html using Chrome at “--allow-file-access-from-files” mode](https://stackoverflow.com/questions/18586921/how-to-launch-html-using-chrome-at-allow-file-access-from-files-mode) @croraf – Khoa Nguyen Sep 07 '19 at 10:34