Read more

ES6 imports are hoisted to the top

Henning Koch
November 02, 2021Software engineer at makandra GmbH

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

Illustration UI/UX Design

UI/UX Design by makandra brand

We make sure that your target audience has the best possible experience with your digital product. You get:

  • Design tailored to your audience
  • Proven processes customized to your needs
  • An expert team of experienced designers
Read more Show archive.org snapshot

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', ...)
Posted by Henning Koch to makandra dev (2021-11-02 12:53)