- ECMAScript Modules (ESMs) allow for the modularization of JavaScript into independent, reusable modules and aim to standardize module syntax.
- ESMs are supported natively in modern browsers but require flags to be enabled. Node.js also supports ESMs with flags and a new proposal enables ESMs by detecting a "mode" field in package.json.
- ESMs are asynchronous, have strict parsing rules, and different interoperability with CommonJS compared to asynchronous CommonJS modules used in Node historically. Adoption of ESMs provides standardized modules across browsers and Node.
7. @sebpertus#DevoxxFR
Modules ?
• No Html files in Node to load Javascript files
• Implementing a way to load files as « modules » in a fair way
• 2009 : Projet ServerJS was born (later changed its name to CommonJS)
• They defined a first version of « what could be a module »
9. @sebpertus#DevoxxFR
Browsers
• AMD (Asynchronous Module definition) is format defined for browser
modules loader
• Implemented by framework like require.js
<script src="lib/require.js"></script>
define(function () {
return { getHello: function () { return 'Hello World';} };
});
define(function (require) {
var messages = require('./messages');
var m = messages.getHello();
});
10. @sebpertus#DevoxxFR
ESM : EcamScript Modules
• Landed in ES6
export class person {
getFullName() { return `${this.lastName} ${this.firstName}`; }
}
import * as people from './person';
var p = new people.person();
17. @sebpertus#DevoxxFR
ESM. In browsers. Rember that !
• Modules are deferred. Run after document loaded
• "import" and "export" statements can only appears at the top-level
• Modules are strict mode by design (think "use strict" )
20. @sebpertus#DevoxxFR
Demos
Demo 02 : Writing EcmaScripts
Modules for browsers.
Demo 03 : Creating an Express
application and modules
Demo 04 : Using bundler to
handle non ESM browsers
23. @sebpertus#DevoxxFR
ESM vs CJS
export class person {
getFullName() { return `${this.lastName} ${this.firstName}`; }
}
import * as people from './person';
var p = new people.person();
class person {
getFullName() { return `${this.lastName} ${this.firstName}`; }
}
exports.person = person;
const people = require("./person");
var p = new people.person();
24. @sebpertus#DevoxxFR
ESM modules in NodeJS
• https://github.com/nodejs/node-eps/blob/master/002-es-
modules.md
• Implement interoperability for EcmaScript 6 modules (ESM) and
Node’s existing module system (CJS)
• Allow a common module syntax for Browser (ES6 spec) and Server
side
25. @sebpertus#DevoxxFR
EF modules vs NodeJS modules
• CommonJS is a dynamic loader modules system
• Synchronous
• Evaluated during runtime
• ES is a static loader modules system
• Asynchronous
• Evaluated during parse time
27. @sebpertus#DevoxxFR
ESM vs CJS. Solutions evaluated ?
• Does Node.js want to ship a synchronous or asynchronous module
loader?
• Returning a promise (async)
• Returning an object (sync)
• Both ?
• Multiple Solutions investigated:
• Use CJS (require) for actuals .js files / Use ESM (import) with a newly file .mjs
• Use a double parsing time
• Config file
• Obiwan Kenobi
31. @sebpertus#DevoxxFR
Michael Jackson Script
Code compiler must know if it’s a CJS or ES module
In certain circumstance an import * from ‘foo’ could be
a CJS module or an ES module (same syntax !)
Node.js will need to have some kind of mechanism for
identifying in advance what kind of file is being loaded
foo.js will treat foo.js as CommonJS
bar.mjs will treat bar.mjs as an ESM Module.
console.log(`Module load ${Date()}`)
32. @sebpertus#DevoxxFR
Hey Let’s go !!!
• We are Ok ?
• OK DEMO TIME, DUDE !!!!
• Well, at least, I made demos from here, last year…
35. @sebpertus#DevoxxFR
ESM: NodeJS Package mode
• Builds on the « In Defense on JS » proposal
• https://github.com/dherman/defense-of-dot-js/blob/master/proposal.md
• A directory containing a package.json with this flag will be considered as an ESM
• Any « .js » file will be considered as an ESM (otherwise as a CommonJS module)
• Benefits
• Enables « .js » to be used as ESM
• Transparent interop
• Easy upgrade path
• Cons
• Resolver performance
• If forget to mention « mode:esm » => Unexpected token export will be raised
38. @sebpertus#DevoxxFR
ESM: Interoperability
• ES modules can import CJS modules
• BUT They have only a default export (value of module.exports)
• ES modules does not allow using « require() »
• Path resolution does not work the same
• ESM are asynchronous
• CJS modules can’t require() ES modules
• You start with ESM, you are stick with it !
• ESM in older Node.JS version
• Are you serious ????
• Use @std/esm package