ES6 imports are hoisted to the top

Posted . Visible to the public. Repeats.

From Exploring ES6 Show archive.org snapshot :

Module imports are hoisted (internally moved to the beginning of the current scope). Therefore, it doesn’t matter where you mention them in a module and the following code works without any problems:

foo();
import { foo } from 'my_module';

Footgun example

When you're not aware of import hoisting you may be surprised that your code runs in a different order than you see in the source file.

The example below is taken from the excid3/esbuild-rails Show archive.org snapshot package.

Let's say we have an application.js bundle that imports jQuery, sets window.$ and then imports code that uses the global $() function:

// application.js
import jquery from 'jquery'
window.jQuery = jquery
window.$ = jquery
import 'site'

// site.js
$('...').on('click', ...)

The code in site.js will fail because it is run before window.$ is set. The broken code above will run (and fail) in the following order:

import jquery from 'jquery'
$('...').on('click', ...)
window.jQuery = jquery
window.$ = jquery

The fix is to import and set jQuery globals in a separate file, that is imported as a whole before we use $():

// application.js
import 'jquery'
import 'site'

// jquery.js
import jquery from 'jquery'
window.jQuery = jquery
window.$ = jquery

// site.js
$('...').on('click', ...)
Profile picture of Henning Koch
Henning Koch
Last edit
Henning Koch
License
Source code in this card is licensed under the MIT License.
Posted by Henning Koch to makandra dev (2021-11-02 11:53)