Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What really determines the order JavaScript modules are executed in the .html?

Tags:

javascript

I read that the module that appears first is loaded first. This wasn't true.

Before I bountied this question I learned:

  1. Modules that have no imports (leaf modules) are executed first.
  2. A module that imports will not execute until the module it imports from executes.

This has allowed me to explain a basic scenario like this:

2.js logs 2 and exports functionTwo (which, when called, logs "2-export").
1.js logs 1 and imports and executes functionTwo from 2.js.

No matter the source-order of these modules, 2.js always executes first because 1.js can't execute before 2.js - it relies on something 2.js exports to it. The console always reads: '2, 1, 2-export'.


However it is an incomplete answer for these 2 scenarios:

  1. ModuleA imports from ModuleB. ModuleB imports from ModuleA.
  2. ModuleA imports from ModuleB. ModuleC imports from ModuleD. I've been experimenting with source-order and I can't intuitively pick up the rule that determines the complete order of execution of modules. All I do know is that D or B has to execute first. (Sometimes DB or BD executes first; sometimes DC or BA executes first)

P.s.

Is it true that the ruling we're talking about only applies to modules without the async attribute? Is it true modules with the async attribute are simply executed as soon as they are loaded?

like image 916
tonitone120 Avatar asked Aug 14 '20 17:08

tonitone120


People also ask

How does JavaScript modules work?

A module in JavaScript is just a file containing related code. In JavaScript, we use the import and export keywords to share and receive functionalities respectively across different modules. The export keyword is used to make a variable, function, class or object accessible to other modules.

What are modules in HTML?

HTML Modules allow web developers to package and access declarative content from script in a way that allows for good componentization and reusability, and integrates well into the existing ES6 Modules infrastructure.

Which statements are necessary for using JavaScript modules?

Modules are pretty simple to create and use. An ES6 module is essentially just a file containing some JavaScript. Everything inside the module is scoped to that module only. If you want to make something—like a function, a variable, or a class—available somewhere else, you need to use an export statement.

How do ES6 modules work?

A module is nothing more than a chunk of JavaScript code written in a file. By default, variables and functions of a module are not available for use. Variables and functions within a module should be exported so that they can be accessed from within other files. Modules in ES6 work only in strict mode.

What is the Order of execution of JavaScript?

JavaScript Execution Order 1 The Location of JavaScript on Your Web Page. Since the JavaScript on your page executes based on certain factors, let's consider where and how to add JavaScript to a web ... 2 Code Directly on the Page. ... 3 Code Assigned to Event Handlers and Listeners. ... 4 Customized Visitor User Scripts. ...

What is a module in JavaScript?

A module in JavaScript is just a file containing related code. In JavaScript, we use the import and export keywords to share and receive functionalities respectively across different modules. The export keyword is used to make a variable, function, class or object accessible to other modules. In other words, it becomes a public code.

Is JavaScript directly in the head or body of the page?

It also doesn't matter whether the event handlers are hard-coded into the page or added by the JavaScript itself (except that they can't be triggered before they are added). What does it mean to say that JavaScript is directly in the head or body of the page? If the code is not enclosed in a function or object, it is directly in the page.

Is it better to use JavaScript or JS for modules?

It is good for clarity, i.e. it makes it clear which files are modules, and which are regular JavaScript. It ensures that your module files are parsed as a module by runtimes such as Node.js, and build tools such as Babel. However, we decided to keep to using .js, at least for the moment.


1 Answers

The rule is pretty simple: the leafs of the dependency trees are imported first (their code is being executed), then all of the intermediate modules up to the root modules.

That's why you observed this behavior:

  • 1 is a leaf module, it's being executed first (console.log('1') and the functionExport declaration)
  • 2 imports 1 so it's being executed right after (console.log('2'))
  • 2 eventually calls the function from 1 (console.log('1export')

The ES6 specification actually doesn't detail clearly whether the imports should be processed sequentially or not. Some browsers might have sequential imports while some other browsers might not.

If you want to guarantee a certain order of execution and have a consistent behavior across browsers, you have to specify a chain of imports accordingly. Two chains of imports are not guaranteed to execute separately (that's why you see DB first sometimes, instead of DC). Two chains of imports are not guaranteed to execute in a certain order (that's why you see sometimes DB, sometimes BD).

The only guaranteed thing is that a script executes after its imports have already executed.

Last word about the async attribute, it allows to defer the fetching and execution while the browser continues to parse the page. It applies to module scripts just like regular scripts, the only difference is that they also load their dependencies, to comply with the rule stated above.

like image 131
Guerric P Avatar answered Nov 09 '22 20:11

Guerric P