SlideShare a Scribd company logo
https://nicr.dev
JavaScript Modules:
Past, Present and Future
NICOLÒ RIBAUDO
@nicolo-ribaudo
@NicoloRibaudo https://nicr.dev
https://nicr.dev 2
NICOLÒ RIBAUDO
● Working at Igalia on web standards
● TC39 delegate
● Maintaining Babel, the JavaScript compiler
in collaboration with
https://nicr.dev
Welcome to your
History class!
3
https://nicr.dev
The original "modules" system
Back in the day, JavaScript was mostly used to add small bits of interactivity to
web pages. There were no "modules", and a few external libraries were loaded
installing properties directly on the window object.
<script src="https://code.jquery.com/jquery.min.js"></script>
<script>
$(document).ready(function() {
$("#hello").css("color", "red");
});
</script>
4
https://nicr.dev
2009: CommonJS
5
~ Kevin Dangoor
https://www.blueskyonmars.com/2009/01/29/what-server-side-javascript-needs/
https://nicr.dev
var chalk = require("chalk");
exports.error = function (message) {
console.log(chalk.red(message));
};
CommonJSImplementation(function (require, exports, module) {
var chalk = require("chalk");
exports.error = function (message) {
console.log(chalk.red(message));
};
});
2009: CommonJS
6
Import other
modules
Expose values
from this module
https://nicr.dev
2009: CommonJS
7
● An effort to standardize a modules system and a set of built-in APIs across
multiple server-side environments
CommonJS Modules/1.1
● Only define the "module interface", implementations must bring their own
runtime loader
● Implemented by Node.js, Narshall, SproutCore, and many others
https://arstechnica.com/information-technology/2009/12/commonjs-effort-sets-javascript-on-path-for-world-domination/
https://nicr.dev
CommonJS' require is synchronous: how to design a module system that
works in the browser?
2009: CommonJS
8
CommonJS' require is synchronous: how to design a module system that
works in the browser?
CommonJS Modules/Transport/C and Modules/AsynchronousDefinition
Pre-declare all the dependencies that need to be loaded, and only start
evaluating code once everything is ready.
https://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition
https://github.com/amdjs/amdjs-api/wiki/AMD
https://nicr.dev
2010: AMD
9
Pre-declare all the dependencies that need to be loaded, and only start
evaluating code once everything is ready.
define("alpha", ["require", "exports", "beta"], function (require, exports, beta) {
exports.verb = function() {
return beta.verb();
//Or:
return require("beta").verb();
}
});
https://github.com/amdjs/amdjs-api/wiki/AMD
https://nicr.dev
2010: AMD
10
Asynchronously load dependencies that cannot be statically declared.
define(function (require) {
require(['i18n/' + lang], function (i18n) {
// modules i18n is now available for use.
});
});
https://github.com/amdjs/amdjs-api/wiki/AMD
https://nicr.dev
2010: AMD
11
AMD supports plugins, to let developers customize how modules are resolved,
loaded and executed.
define(['text!../templates/start.html'], function (template) {
//do something with the template text string.
});
https://nicr.dev
2015: ECMAScript Modules
// math.js
export function sum() {
let s = 0;
for (let x of arguments) s =+ x;
return s;
}
// main.js
import { sum } from "./math.js";
console.log(sum(1, 2, 3)); // 6
12
https://nicr.dev
2015: ECMAScript Modules
● Statically analyzable: runtimes can preload all the
necessary dependencies before executing the code
● Minimal syntactic overhead (no boilerplate)
● Support for "named" and "default" exports
(no overlapping module.exports vs module.exports.name)
13
Like AMD!
Like CommonJS!
https://nicr.dev
2015: ECMAScript Modules
They are the result of multiple years of development, taking input from
different parties and exploring many possible designs and features.
14
https://nicr.dev
2015: ECMAScript Modules
They are the result of multiple years of development, taking input from
different parties and exploring many possible designs and features.
15
https://archives.ecma-international.org/1999/TC39WG/991115-futures.htm
https://nicr.dev
2015: ECMAScript Modules
They are the result of multiple years of development, taking input from
different parties and exploring many possible designs and features.
16
Modules Systems for ES-Harmony, Kris Kowal and Ihab Awad, 2009-11
http://archives.ecma-international.org/2009/TC39/tc39-2009-011.pdf
Simple Modules, Sam Tobin-Hochstadt and Dave Herman, 2010
http://archives.ecma-international.org/2010/TC39/tc39-2010-017.pdf
Modules, Dave Herman, Sam Tobin-Hochstadt and Yehuda Katz, 2013
http://archives.ecma-international.org/2013/misc/2013misc4.pdf
https://nicr.dev
2015 2016: ECMAScript Modules
ECMAScript 2015 defined part of the ECMAScript Modules semantics. It was
just in 2016, with the HTML integration, that modules had been fully specified
and implementable.
17
https://github.com/whatwg/html/pull/443
https://nicr.dev
2019: Dynamic import()
Both CommonJS and AMD provided ways to dynamically require a module,
but this capability was missing from the initial ECMAScript Modules version.
import('i18n/' + lang).then(function (i18n) {
// modules i18n is now available for use.
});
// Since 2021, with top-level await
let i18n = await import('i18n/' + lang);
18
https://nicr.dev 19
Today, 2023
🕦
https://nicr.dev
Today
20
● ECMAScript Modules are being used in production applications and as a
distribution format
● CommonJS and AMD are still widely used, both by legacy and new code
● There is no clear migration path from CommonJS/AMD to ECMAScript
Modules yet
https://nicr.dev
What's missing from ES Modules?
A way to synchronously import dependencies
only when they are actually needed.
// Supported by CommonJS!
exports.circ = function (radius) {
let PI = require("./heavy-computation-pi");
return 2 * PI * radius;
};
21
https://nicr.dev
What's missing from ES Modules?
A way to easily write multiple modules in a single file.
// Supported by AMD!
define("pi", function () { return 3.14; });
define("math", ["pi"], function (pi) {
return {
circ: (radius) => 2 * pi * radius,
};
});
22
https://nicr.dev
What's missing from ES Modules?
A way to customize the module loading process.
// Supported by AMD!
define("text!./doc.htm", function (docAsString) {
// ...
});
23
https://nicr.dev
What's missing from ES Modules?
A way to properly support resources other than JavaScript.
● JSON
● WebAssembly
● …
24
https://nicr.dev
Modules Harmony
25
https://nicr.dev
TC39: the JS standard committee
26
● TC39 designs the JavaScript language
● Made up of people from different companies, and the JS community
● Discusses and decides on new features through proposals
https://nicr.dev
Modules Harmony
27
● The open design space around ECMAScript Modules is huge
● ECMAScript proposals are usually self-contained and developed in isolation
○ Every proposal must be motivated on its own
○ Every proposal must be complete on its own
● Cross-proposal coordination is necessary, to ensure that the evolution of
ECMAScript Modules remains consistent
https://nicr.dev
September 2022 TC39 meeting
July 2022 TC39 meeting
March 2022 TC39 meeting
Modules Harmony
28
November 2022 TC39 meeting
January 2023 TC39 meeting
March 2023 TC39 meeting
May 2023 TC39 meeting
https://nicr.dev
Modules Harmony
29
https://nicr.dev
The future
30
(maybe!)
https://nicr.dev
Modules proposals under development
31
Import attributes
Source phase imports
(aka Import Reflection)
Deferred import
evaluation
Custom module
loading
(aka Compartments layer 0)
Module expressions Module declarations
https://nicr.dev
Stage 3:
Import attributes
https://github.com/tc39/proposal-import-attributes
32
https://nicr.dev
"Parameters for the underlying module loader"
Import attributes
33
Please load the module
./math.js
import {
add,
} from "./math.js";
��💻
The JavaScriot "engine" (such as V8) doesn't have
any I/O capabilities, and relies on a wrapper
"runtime" to communicate with the world.
https://nicr.dev
"Parameters for the underlying module loader"
Import attributes
34
Please load the module
./math.js
Here it is! 📦
It has the these exports:
- add
- sub
And you can execute it
running this:
Evaluate() { … }
��
Please load the script file
https://x.com/math.js
Here it is! It's an
application/javascript,
with these contents:
export let add =
(x, y) => x + y;
export let sub =
(x, y) => x - y;
https://nicr.dev
"Parameters for the underlying module loader"
Import attributes
35
Please load the module
./main.css, the
developer said that it
should have
● type: "css"
import {
styles,
} from "./main.css" with {
type: "css"
};
��💻
I want this
module do
be loaded as
a CSS file…
https://nicr.dev
"Parameters for the underlying module loader"
Import attributes
36
Please load the module
./main.css, the developer
said that it should have
● type: "css"
��
Please load the stylesheet
https://x.com/main.css
Here it is! It's a text/css,
with these contents:
.my-class {
color: red;
}
type: "css"
means that it
should be a CSS
stylesheet…
type/css: matches what I
expected for a CSS stylesheet ✓
Here it is! 📦
It has the these exports:
- styles
And you can execute it
running this:
Evaluate() { … }
https://nicr.dev
⚠ Import assertions
A previous version of the proposal only allowed asserting that the loaded
module matched a given property:
import styles from "./main.css" assert { type: "css" };
While implementing this feature, browsers realized that "assert-only"
semantics didn't match what was needed so the proposal was changed:
import styles from "./main.css" with { type: "css" };
37
https://nicr.dev
Stage 2:
Source phase
imports
https://github.com/tc39/proposal-import-reflection/
38
https://nicr.dev
The phases of importing a module
39
// https://x.com/main.js
import("./mod.js");
globalThis: { … }
baseURL:
"https://x.com/main.js"
Evaluate Execute all the loaded modules, according to the
dependencies order, and expose the exported values
Link
Load all the dependencies, and bind imports to exports
Attach context import { y } from "./dep.js";
export let x = 1 + y;
globalThis: { … }
baseURL:
"https://x.com/mod.js"
Fetch / compile import { y } from "./dep.js";
export let x = 1 + y;
Resolve "https://x.com/mod.js"
https://nicr.dev
Source phase imports
Exposing a module at an earlier phase
import source modSource from "./mod";
modSoure is an object representing "./mod"'s source,
unlinked and without any execution context attached.
40
Evaluate
Link
Attach context
Resolve
Fetch / compile
https://nicr.dev
WebAssembly Modules integration
41
Using fetch
const url = import.meta.resolve("./crypto.wasm");
const responseP = fetch(url);
const cryptoM =
await WebAssembly.compileStreaming(responseP);
cryptoM instanceof WebAssembly.Module;
const cryptoI = await
WebAssembly.instantiate(cryptoM, {
mathModule: { add: (x, y) => x + y },
});
const { md5 } = cryptoI.exports;
md5("Hello!");
// > 952d2c56d0485958336747bcdd98590d
Using source imports
import source cryptoM from "./crypto.wasm";
● Module is preloaded while loading all
the modules
● Easily statically analyzable for bundlers
● Goes through the existing module
loading content security policies (CSPs)
https://nicr.dev
Stage 1:
Deferred import
evaluation
https://github.com/tc39/proposal-defer-import-eval
42
https://nicr.dev
// ECMAScript Module
export function circ(radius) {
let PI = import("./computed-pi");
return 2 * PI * radius;
}
Deferred import evaluation
// CommonJS
exports.circ = function (radius) {
let PI = require("./computed-pi");
return 2 * PI * radius;
};
43
// ECMAScript Module
export async function circ(radius) {
let PI = await import("./computed-pi");
return 2 * PI * radius;
}
❓
async/await is "viral", it forces all the
callers to be asynchronous 😕
https://nicr.dev
Deferred import evaluation
Module loading must be asynchronous. Can we still avoid
some initialization cost?
import defer * as mod from "./computed-pi.js"
export function circ(radius) {
return 2 * mod.PI * radius;
}
mod is an import namespace object that triggers
the evaluation of the corresponding module only
when accessing its exports.
44
Evaluate
Link
Attach context
Resolve
Fetch / compile
https://nicr.dev
Blurring the line: top-level await
Due to top-level await, some modules cannot be
evaluated synchronously.
45
// a.js
import defer * as b from "./b.js";
console.log("Eval A");
// b.js
import "./c.js";
console.log("Eval B");
// c.js
await aPromise;
console.log("Eval C");
Evaluate
Link
Attach context
Resolve
Fetch / compile
● Since c.js is asynchronous, its
evaluation cannot be
optimized await and it's
evaluated eagerly.
● Later, when accessing
b.something, only b.js still
needs to be evaluated.
https://nicr.dev
Stage 1:
Custom module
loading
https://github.com/tc39/proposal-compartments
46
https://nicr.dev
Please load the module
./math.js
Here it is! 📦
It has the these exports:
- add
- sub
And you can execute it
running this:
Evaluate() { … }
��
Please load the script file
https://x.com/math.js
Here it is! It's an
application/javascrip
t, with these contents:
export let add =
(x, y) => x + y;
export let sub =
(x, y) => x - y;
Importing a module
47
Evaluate
Link
Attach context
Resolve
Fetch / compile
Can we allow
hooking into this?
https://nicr.dev 48
Browsers: Service Workers
�
Please load the script file
https://x.com/math.ts
⚙
⚙
Here it is! It's an
application/javascript,
with these contents:
export let add =
(x, y) => x + y;
export let sub =
(x, y) => x - y;
Please load the script file
https://x.com/math.ts
Here it is! It's an
application/typescript,
with these contents:
export let add =
(x: num, y: num) => x + y;
export let sub =
(x: num, y: num) => x - y;
Fetch / compile
The service worker receives the resolved URL…
… and returns the corresponding source.
https://nicr.dev 49
Browsers: Service Workers
// service-worker.js
addEventListener("fetch", function (event) {
if (event.request.url.endsWith(".ts")) {
event.respondWith(
fetch(event.request).then(async response => {
let { code } = await babel.transform(await response.text(), babelConfig).code;
return new Response(code, {
headers: { ...response.headers, "content-type": "text/javascript" }
});
})
);
} else {
event.respondWith(fetch(event.request));
}
});
https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope/fetch_event
https://nicr.dev 50
Node.js: --experimental-loader
�
⚙
⚙
Please resolve ./math.ts
from file:///proj/main.js
It resolves to
file:///proj/math.ts
function resolve(specifier, ctx, next) {
// ...
}
…
…
Please load the file
file:///proj/math.ts
Here it is! It's a module file, with
these contents:
// ...
⚙
⚙function load(url, ctx, next) {
// ...
}
…
…
Resolve
Fetch / compile
https://nodejs.org/api/esm.html#loaders
https://nicr.dev
Proposal: custom module loading
51
Please load the module
./math.js
async importHook(specifier) {
const url = resolveURL(specifier);
const source = await fetchSource(url);
return new Module(source, hooks);
}
new Module(source, {
async importHook(specifier) {
const url = resolveURL(specifier);
const source = await fetchSource(url);
return new Module(source, hooks);
},
});
Here it is! 📦
It has the these exports:
- add
- sub
And you can execute it
running this:
Evaluate() { … }
Attach context
Resolve Fetch / compile
https://nicr.dev
import module wasmM from "./mod.wasm";
wasmM instanceof Module;
import module jsM from "./mod.js";
jsM instanceof Module;
await import(jsM);
let module = new Module(source, {
async importHook() { /* ... */ },
importMeta: { /* ... */ },
// Any other context
baseURL: "https://...",
});
await import(module);
Module and ModuleSource
52
import source wasmS from "./mod.wasm";
wasmS instanceof WebAssembly.Module;
import source jsS from "./mod.js";
jsS instanceof ???;
let source = WebAssembly.compile(bytes);
let source = new ModuleSource(`
import { x } from "dep";
console.log(x);
`);
Evaluate
Link
Attach context
Resolve
Fetch / compile
https://nicr.dev
Stage 2:
Module
expressions
53
https://nicr.dev
Module expressions
54
Modules would now hava a
first-class representation in
the language (like functions):
fun instanceof Function;
mod instanceof Module;
… or with static syntax:
let fun = function (x) {
return x + 1;
};
let mod = module {
export default 7;
};
You can create them with the
respective constructors:
let fun = new Function(
"x",
"return x + 1;"
);
let mod = new Module(
new ModuleSource(`
export default 7;
`)
); Module expressions!
https://nicr.dev
Module expressions
55
And you can later execute
them:
fun();
await import(mod);
Module expressions!
… or with static syntax:
let fun = function (x) {
return x + 1;
};
let mod = module {
export default 7;
};
You can create them with the
respective constructors:
let fun = new Function(
"x",
"return x + 1;"
);
let mod = new Module(
new ModuleSource(`
export default 7;
`)
https://nicr.dev
Module expressions
56
Functions have a declaration
form:
function fun(x) {
return x + 1;
}
Module expressions!
… or with static syntax:
let fun = function (x) {
return x + 1;
};
let mod = module {
export default 7;
};
You can create them with the
respective constructors:
let fun = new Function(
"x",
"return x + 1;"
);
let mod = new Module(
new ModuleSource(`
export default 7;
`)
???
https://nicr.dev
Module expressions use cases
57
Co-locating code to be executed in
different threads
let worker = new Worker("/modules-runner");
worker.postMessage(module {
export default function () {
// Do some expensive work!
}
});
worker.addEventListener("message", ({ data }) => {
console.log("Result", data + 2);
});
Improved ergonomics for custom loaders
import source modSource from "./my-file.js";
// Mock access to the file system
async function importHook(specifier) {
if (specifier === "fs") {
return module {}
export const readFile = () => "Hello!";
};
}
return import(resolve(specifier));
}
import(new Module(modSource, { importHook }));
Logically linked code can
live in the same file
https://nicr.dev
Stage 2:
Module
declarations
58
https://nicr.dev
Module declarations
59
Functions and modules have
a declaration form:
function fun(x) {
return x + 1;
}
module Mod {
export default 7;
}
Module declarations!
… or with static syntax:
let fun = function (x) {
return x + 1;
};
let mod = module {
export default 7;
};
You can create them with the
respective constructors:
let fun = new Function(
"x",
"return x + 1;"
);
let mod = new Module(
new ModuleSource(`
export default 7;
`)
https://nicr.dev
Bundling primitives in ECMAScript
60
https://nicr.dev
Module declarations
61
// bundle.amd.js
define("pi", function () {
return 3.14;
});
define("math", ["pi"], function (pi) {
return {
circ(radius) {
return 2 * pi * radius;
}
};
});
// bundle.esm.js
module PI {
export default 3.14;
}
module Math {
import pi from PI;
export function circ(radius) {
return 2 * pi * radius;
}
}
https://nicr.dev
Module declarations
62
They can be imported, exported, nested, and passed around.
// vendor.bundle.js
export module lodash {
module Internal { /* ... */ }
module Get {
import { something } from Internal;
export function get(obj, path) { /* ... */ }
}
export { get } from Get;
// ...
}
// vendor.external.js
export module Preact from "https://example.com/preact@10.13.2";
// main.js
import { lodash } from "./vendor.bundle.js";
import { Preact } from "./vendor.external.js";
import { get, set } from lodash;
import { h } from Preact;
get({ a: 1 }, "a");
https://nicr.dev
Modules proposals under development
63
Import attributes
Source phase imports
(aka Import Reflection)
Deferred import
evaluation
Custom module
loading
(aka Compartments layer 0)
Module expressions Module declarations
https://nicr.dev
When is all of this coming?
64
When is all of this coming?

More Related Content

Similar to JavaScript Modules Past, Present and Future

Introduction to Grunt.js on Taiwan JavaScript Conference
Introduction to Grunt.js on Taiwan JavaScript ConferenceIntroduction to Grunt.js on Taiwan JavaScript Conference
Introduction to Grunt.js on Taiwan JavaScript ConferenceBo-Yi Wu
 
Comment développer une application mobile en 8 semaines - Meetup PAUG 24-01-2023
Comment développer une application mobile en 8 semaines - Meetup PAUG 24-01-2023Comment développer une application mobile en 8 semaines - Meetup PAUG 24-01-2023
Comment développer une application mobile en 8 semaines - Meetup PAUG 24-01-2023Nicolas HAAN
 
DevOps Workflow: A Tutorial on Linux Containers
DevOps Workflow: A Tutorial on Linux ContainersDevOps Workflow: A Tutorial on Linux Containers
DevOps Workflow: A Tutorial on Linux Containersinside-BigData.com
 
Burn your grass with react native
Burn your grass with react nativeBurn your grass with react native
Burn your grass with react nativeEugene Zharkov
 
Alberto Maria Angelo Paro - Isomorphic programming in Scala and WebDevelopmen...
Alberto Maria Angelo Paro - Isomorphic programming in Scala and WebDevelopmen...Alberto Maria Angelo Paro - Isomorphic programming in Scala and WebDevelopmen...
Alberto Maria Angelo Paro - Isomorphic programming in Scala and WebDevelopmen...Codemotion
 
Angular 2 for Java Developers
Angular 2 for Java DevelopersAngular 2 for Java Developers
Angular 2 for Java DevelopersYakov Fain
 
Intro To Node.js
Intro To Node.jsIntro To Node.js
Intro To Node.jsChris Cowan
 
Java programming concept
Java programming conceptJava programming concept
Java programming conceptSanjay Gunjal
 
Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...
Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...
Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...Codemotion
 
Universal JS Web Applications with React - Luciano Mammino - Codemotion Rome ...
Universal JS Web Applications with React - Luciano Mammino - Codemotion Rome ...Universal JS Web Applications with React - Luciano Mammino - Codemotion Rome ...
Universal JS Web Applications with React - Luciano Mammino - Codemotion Rome ...Luciano Mammino
 
JavaScript Modules Done Right
JavaScript Modules Done RightJavaScript Modules Done Right
JavaScript Modules Done RightMariusz Nowak
 
[Codelab 2017] Docker 기초 및 활용 방안
[Codelab 2017] Docker 기초 및 활용 방안[Codelab 2017] Docker 기초 및 활용 방안
[Codelab 2017] Docker 기초 및 활용 방안양재동 코드랩
 
Warsaw Frontend Meetup #1 - Webpack
Warsaw Frontend Meetup #1 - WebpackWarsaw Frontend Meetup #1 - Webpack
Warsaw Frontend Meetup #1 - WebpackRadosław Rosłaniec
 
Example Cosmos SDK Application Tutorial
Example Cosmos SDK Application TutorialExample Cosmos SDK Application Tutorial
Example Cosmos SDK Application TutorialJim Yang
 
Use Eclipse technologies to build a modern embedded IDE
Use Eclipse technologies to build a modern embedded IDEUse Eclipse technologies to build a modern embedded IDE
Use Eclipse technologies to build a modern embedded IDEBenjamin Cabé
 
"Micro frontends: Unbelievably true life story", Dmytro Pavlov
"Micro frontends: Unbelievably true life story", Dmytro Pavlov"Micro frontends: Unbelievably true life story", Dmytro Pavlov
"Micro frontends: Unbelievably true life story", Dmytro PavlovFwdays
 

Similar to JavaScript Modules Past, Present and Future (20)

Introduction to Grunt.js on Taiwan JavaScript Conference
Introduction to Grunt.js on Taiwan JavaScript ConferenceIntroduction to Grunt.js on Taiwan JavaScript Conference
Introduction to Grunt.js on Taiwan JavaScript Conference
 
Comment développer une application mobile en 8 semaines - Meetup PAUG 24-01-2023
Comment développer une application mobile en 8 semaines - Meetup PAUG 24-01-2023Comment développer une application mobile en 8 semaines - Meetup PAUG 24-01-2023
Comment développer une application mobile en 8 semaines - Meetup PAUG 24-01-2023
 
DevOps Workflow: A Tutorial on Linux Containers
DevOps Workflow: A Tutorial on Linux ContainersDevOps Workflow: A Tutorial on Linux Containers
DevOps Workflow: A Tutorial on Linux Containers
 
Burn your grass with react native
Burn your grass with react nativeBurn your grass with react native
Burn your grass with react native
 
Alberto Maria Angelo Paro - Isomorphic programming in Scala and WebDevelopmen...
Alberto Maria Angelo Paro - Isomorphic programming in Scala and WebDevelopmen...Alberto Maria Angelo Paro - Isomorphic programming in Scala and WebDevelopmen...
Alberto Maria Angelo Paro - Isomorphic programming in Scala and WebDevelopmen...
 
Angular 2 for Java Developers
Angular 2 for Java DevelopersAngular 2 for Java Developers
Angular 2 for Java Developers
 
Intro To Node.js
Intro To Node.jsIntro To Node.js
Intro To Node.js
 
Java programming concept
Java programming conceptJava programming concept
Java programming concept
 
Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...
Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...
Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...
 
Universal JS Web Applications with React - Luciano Mammino - Codemotion Rome ...
Universal JS Web Applications with React - Luciano Mammino - Codemotion Rome ...Universal JS Web Applications with React - Luciano Mammino - Codemotion Rome ...
Universal JS Web Applications with React - Luciano Mammino - Codemotion Rome ...
 
Lecture: Webpack 4
Lecture: Webpack 4Lecture: Webpack 4
Lecture: Webpack 4
 
JavaScript Modules Done Right
JavaScript Modules Done RightJavaScript Modules Done Right
JavaScript Modules Done Right
 
The MEAN stack
The MEAN stack The MEAN stack
The MEAN stack
 
RequireJS
RequireJSRequireJS
RequireJS
 
Backbone js-slides
Backbone js-slidesBackbone js-slides
Backbone js-slides
 
[Codelab 2017] Docker 기초 및 활용 방안
[Codelab 2017] Docker 기초 및 활용 방안[Codelab 2017] Docker 기초 및 활용 방안
[Codelab 2017] Docker 기초 및 활용 방안
 
Warsaw Frontend Meetup #1 - Webpack
Warsaw Frontend Meetup #1 - WebpackWarsaw Frontend Meetup #1 - Webpack
Warsaw Frontend Meetup #1 - Webpack
 
Example Cosmos SDK Application Tutorial
Example Cosmos SDK Application TutorialExample Cosmos SDK Application Tutorial
Example Cosmos SDK Application Tutorial
 
Use Eclipse technologies to build a modern embedded IDE
Use Eclipse technologies to build a modern embedded IDEUse Eclipse technologies to build a modern embedded IDE
Use Eclipse technologies to build a modern embedded IDE
 
"Micro frontends: Unbelievably true life story", Dmytro Pavlov
"Micro frontends: Unbelievably true life story", Dmytro Pavlov"Micro frontends: Unbelievably true life story", Dmytro Pavlov
"Micro frontends: Unbelievably true life story", Dmytro Pavlov
 

More from Igalia

A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Building End-user Applications on Embedded Devices with WPE
Building End-user Applications on Embedded Devices with WPEBuilding End-user Applications on Embedded Devices with WPE
Building End-user Applications on Embedded Devices with WPEIgalia
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Automated Testing for Web-based Systems on Embedded Devices
Automated Testing for Web-based Systems on Embedded DevicesAutomated Testing for Web-based Systems on Embedded Devices
Automated Testing for Web-based Systems on Embedded DevicesIgalia
 
Embedding WPE WebKit - from Bring-up to Maintenance
Embedding WPE WebKit - from Bring-up to MaintenanceEmbedding WPE WebKit - from Bring-up to Maintenance
Embedding WPE WebKit - from Bring-up to MaintenanceIgalia
 
Optimizing Scheduler for Linux Gaming.pdf
Optimizing Scheduler for Linux Gaming.pdfOptimizing Scheduler for Linux Gaming.pdf
Optimizing Scheduler for Linux Gaming.pdfIgalia
 
Running JS via WASM faster with JIT
Running JS via WASM      faster with JITRunning JS via WASM      faster with JIT
Running JS via WASM faster with JITIgalia
 
To crash or not to crash: if you do, at least recover fast!
To crash or not to crash: if you do, at least recover fast!To crash or not to crash: if you do, at least recover fast!
To crash or not to crash: if you do, at least recover fast!Igalia
 
Implementing a Vulkan Video Encoder From Mesa to GStreamer
Implementing a Vulkan Video Encoder From Mesa to GStreamerImplementing a Vulkan Video Encoder From Mesa to GStreamer
Implementing a Vulkan Video Encoder From Mesa to GStreamerIgalia
 
8 Years of Open Drivers, including the State of Vulkan in Mesa
8 Years of Open Drivers, including the State of Vulkan in Mesa8 Years of Open Drivers, including the State of Vulkan in Mesa
8 Years of Open Drivers, including the State of Vulkan in MesaIgalia
 
Introducción a Mesa. Caso específico dos dispositivos Raspberry Pi por Igalia
Introducción a Mesa. Caso específico dos dispositivos Raspberry Pi por IgaliaIntroducción a Mesa. Caso específico dos dispositivos Raspberry Pi por Igalia
Introducción a Mesa. Caso específico dos dispositivos Raspberry Pi por IgaliaIgalia
 
2023 in Chimera Linux
2023 in Chimera                    Linux2023 in Chimera                    Linux
2023 in Chimera LinuxIgalia
 
Building a Linux distro with LLVM
Building a Linux distro        with LLVMBuilding a Linux distro        with LLVM
Building a Linux distro with LLVMIgalia
 
turnip: Update on Open Source Vulkan Driver for Adreno GPUs
turnip: Update on Open Source Vulkan Driver for Adreno GPUsturnip: Update on Open Source Vulkan Driver for Adreno GPUs
turnip: Update on Open Source Vulkan Driver for Adreno GPUsIgalia
 
Graphics stack updates for Raspberry Pi devices
Graphics stack updates for Raspberry Pi devicesGraphics stack updates for Raspberry Pi devices
Graphics stack updates for Raspberry Pi devicesIgalia
 
Delegated Compositing - Utilizing Wayland Protocols for Chromium on ChromeOS
Delegated Compositing - Utilizing Wayland Protocols for Chromium on ChromeOSDelegated Compositing - Utilizing Wayland Protocols for Chromium on ChromeOS
Delegated Compositing - Utilizing Wayland Protocols for Chromium on ChromeOSIgalia
 
MessageFormat: The future of i18n on the web
MessageFormat: The future of i18n on the webMessageFormat: The future of i18n on the web
MessageFormat: The future of i18n on the webIgalia
 
Replacing the geometry pipeline with mesh shaders
Replacing the geometry pipeline with mesh shadersReplacing the geometry pipeline with mesh shaders
Replacing the geometry pipeline with mesh shadersIgalia
 
I'm not an AMD expert, but...
I'm not an AMD expert, but...I'm not an AMD expert, but...
I'm not an AMD expert, but...Igalia
 
Status of Vulkan on Raspberry
Status of Vulkan on RaspberryStatus of Vulkan on Raspberry
Status of Vulkan on RaspberryIgalia
 

More from Igalia (20)

A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Building End-user Applications on Embedded Devices with WPE
Building End-user Applications on Embedded Devices with WPEBuilding End-user Applications on Embedded Devices with WPE
Building End-user Applications on Embedded Devices with WPE
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Automated Testing for Web-based Systems on Embedded Devices
Automated Testing for Web-based Systems on Embedded DevicesAutomated Testing for Web-based Systems on Embedded Devices
Automated Testing for Web-based Systems on Embedded Devices
 
Embedding WPE WebKit - from Bring-up to Maintenance
Embedding WPE WebKit - from Bring-up to MaintenanceEmbedding WPE WebKit - from Bring-up to Maintenance
Embedding WPE WebKit - from Bring-up to Maintenance
 
Optimizing Scheduler for Linux Gaming.pdf
Optimizing Scheduler for Linux Gaming.pdfOptimizing Scheduler for Linux Gaming.pdf
Optimizing Scheduler for Linux Gaming.pdf
 
Running JS via WASM faster with JIT
Running JS via WASM      faster with JITRunning JS via WASM      faster with JIT
Running JS via WASM faster with JIT
 
To crash or not to crash: if you do, at least recover fast!
To crash or not to crash: if you do, at least recover fast!To crash or not to crash: if you do, at least recover fast!
To crash or not to crash: if you do, at least recover fast!
 
Implementing a Vulkan Video Encoder From Mesa to GStreamer
Implementing a Vulkan Video Encoder From Mesa to GStreamerImplementing a Vulkan Video Encoder From Mesa to GStreamer
Implementing a Vulkan Video Encoder From Mesa to GStreamer
 
8 Years of Open Drivers, including the State of Vulkan in Mesa
8 Years of Open Drivers, including the State of Vulkan in Mesa8 Years of Open Drivers, including the State of Vulkan in Mesa
8 Years of Open Drivers, including the State of Vulkan in Mesa
 
Introducción a Mesa. Caso específico dos dispositivos Raspberry Pi por Igalia
Introducción a Mesa. Caso específico dos dispositivos Raspberry Pi por IgaliaIntroducción a Mesa. Caso específico dos dispositivos Raspberry Pi por Igalia
Introducción a Mesa. Caso específico dos dispositivos Raspberry Pi por Igalia
 
2023 in Chimera Linux
2023 in Chimera                    Linux2023 in Chimera                    Linux
2023 in Chimera Linux
 
Building a Linux distro with LLVM
Building a Linux distro        with LLVMBuilding a Linux distro        with LLVM
Building a Linux distro with LLVM
 
turnip: Update on Open Source Vulkan Driver for Adreno GPUs
turnip: Update on Open Source Vulkan Driver for Adreno GPUsturnip: Update on Open Source Vulkan Driver for Adreno GPUs
turnip: Update on Open Source Vulkan Driver for Adreno GPUs
 
Graphics stack updates for Raspberry Pi devices
Graphics stack updates for Raspberry Pi devicesGraphics stack updates for Raspberry Pi devices
Graphics stack updates for Raspberry Pi devices
 
Delegated Compositing - Utilizing Wayland Protocols for Chromium on ChromeOS
Delegated Compositing - Utilizing Wayland Protocols for Chromium on ChromeOSDelegated Compositing - Utilizing Wayland Protocols for Chromium on ChromeOS
Delegated Compositing - Utilizing Wayland Protocols for Chromium on ChromeOS
 
MessageFormat: The future of i18n on the web
MessageFormat: The future of i18n on the webMessageFormat: The future of i18n on the web
MessageFormat: The future of i18n on the web
 
Replacing the geometry pipeline with mesh shaders
Replacing the geometry pipeline with mesh shadersReplacing the geometry pipeline with mesh shaders
Replacing the geometry pipeline with mesh shaders
 
I'm not an AMD expert, but...
I'm not an AMD expert, but...I'm not an AMD expert, but...
I'm not an AMD expert, but...
 
Status of Vulkan on Raspberry
Status of Vulkan on RaspberryStatus of Vulkan on Raspberry
Status of Vulkan on Raspberry
 

Recently uploaded

How Do I Begin the Linksys Velop Setup Process?
How Do I Begin the Linksys Velop Setup Process?How Do I Begin the Linksys Velop Setup Process?
How Do I Begin the Linksys Velop Setup Process?Linksys Velop Login
 
Multi-cluster Kubernetes Networking- Patterns, Projects and Guidelines
Multi-cluster Kubernetes Networking- Patterns, Projects and GuidelinesMulti-cluster Kubernetes Networking- Patterns, Projects and Guidelines
Multi-cluster Kubernetes Networking- Patterns, Projects and GuidelinesSanjeev Rampal
 
Pvtaan Social media marketing proposal.pdf
Pvtaan Social media marketing proposal.pdfPvtaan Social media marketing proposal.pdf
Pvtaan Social media marketing proposal.pdfPvtaan
 
The AI Powered Organization-Intro to AI-LAN.pdf
The AI Powered Organization-Intro to AI-LAN.pdfThe AI Powered Organization-Intro to AI-LAN.pdf
The AI Powered Organization-Intro to AI-LAN.pdfSiskaFitrianingrum
 
The+Prospects+of+E-Commerce+in+China.pptx
The+Prospects+of+E-Commerce+in+China.pptxThe+Prospects+of+E-Commerce+in+China.pptx
The+Prospects+of+E-Commerce+in+China.pptxlaozhuseo02
 
History+of+E-commerce+Development+in+China-www.cfye-commerce.shop
History+of+E-commerce+Development+in+China-www.cfye-commerce.shopHistory+of+E-commerce+Development+in+China-www.cfye-commerce.shop
History+of+E-commerce+Development+in+China-www.cfye-commerce.shoplaozhuseo02
 
How to Use Contact Form 7 Like a Pro.pptx
How to Use Contact Form 7 Like a Pro.pptxHow to Use Contact Form 7 Like a Pro.pptx
How to Use Contact Form 7 Like a Pro.pptxGal Baras
 
Article writing on excessive use of internet.pptx
Article writing on excessive use of internet.pptxArticle writing on excessive use of internet.pptx
Article writing on excessive use of internet.pptxabhinandnam9997
 
ER(Entity Relationship) Diagram for online shopping - TAE
ER(Entity Relationship) Diagram for online shopping - TAEER(Entity Relationship) Diagram for online shopping - TAE
ER(Entity Relationship) Diagram for online shopping - TAEHimani415946
 
一比一原版UTS毕业证悉尼科技大学毕业证成绩单如何办理
一比一原版UTS毕业证悉尼科技大学毕业证成绩单如何办理一比一原版UTS毕业证悉尼科技大学毕业证成绩单如何办理
一比一原版UTS毕业证悉尼科技大学毕业证成绩单如何办理aagad
 
The Use of AI in Indonesia Election 2024: A Case Study
The Use of AI in Indonesia Election 2024: A Case StudyThe Use of AI in Indonesia Election 2024: A Case Study
The Use of AI in Indonesia Election 2024: A Case StudyDamar Juniarto
 

Recently uploaded (12)

How Do I Begin the Linksys Velop Setup Process?
How Do I Begin the Linksys Velop Setup Process?How Do I Begin the Linksys Velop Setup Process?
How Do I Begin the Linksys Velop Setup Process?
 
Multi-cluster Kubernetes Networking- Patterns, Projects and Guidelines
Multi-cluster Kubernetes Networking- Patterns, Projects and GuidelinesMulti-cluster Kubernetes Networking- Patterns, Projects and Guidelines
Multi-cluster Kubernetes Networking- Patterns, Projects and Guidelines
 
Pvtaan Social media marketing proposal.pdf
Pvtaan Social media marketing proposal.pdfPvtaan Social media marketing proposal.pdf
Pvtaan Social media marketing proposal.pdf
 
The AI Powered Organization-Intro to AI-LAN.pdf
The AI Powered Organization-Intro to AI-LAN.pdfThe AI Powered Organization-Intro to AI-LAN.pdf
The AI Powered Organization-Intro to AI-LAN.pdf
 
The+Prospects+of+E-Commerce+in+China.pptx
The+Prospects+of+E-Commerce+in+China.pptxThe+Prospects+of+E-Commerce+in+China.pptx
The+Prospects+of+E-Commerce+in+China.pptx
 
History+of+E-commerce+Development+in+China-www.cfye-commerce.shop
History+of+E-commerce+Development+in+China-www.cfye-commerce.shopHistory+of+E-commerce+Development+in+China-www.cfye-commerce.shop
History+of+E-commerce+Development+in+China-www.cfye-commerce.shop
 
How to Use Contact Form 7 Like a Pro.pptx
How to Use Contact Form 7 Like a Pro.pptxHow to Use Contact Form 7 Like a Pro.pptx
How to Use Contact Form 7 Like a Pro.pptx
 
Article writing on excessive use of internet.pptx
Article writing on excessive use of internet.pptxArticle writing on excessive use of internet.pptx
Article writing on excessive use of internet.pptx
 
ER(Entity Relationship) Diagram for online shopping - TAE
ER(Entity Relationship) Diagram for online shopping - TAEER(Entity Relationship) Diagram for online shopping - TAE
ER(Entity Relationship) Diagram for online shopping - TAE
 
一比一原版UTS毕业证悉尼科技大学毕业证成绩单如何办理
一比一原版UTS毕业证悉尼科技大学毕业证成绩单如何办理一比一原版UTS毕业证悉尼科技大学毕业证成绩单如何办理
一比一原版UTS毕业证悉尼科技大学毕业证成绩单如何办理
 
The Best AI Powered Software - Intellivid AI Studio
The Best AI Powered Software - Intellivid AI StudioThe Best AI Powered Software - Intellivid AI Studio
The Best AI Powered Software - Intellivid AI Studio
 
The Use of AI in Indonesia Election 2024: A Case Study
The Use of AI in Indonesia Election 2024: A Case StudyThe Use of AI in Indonesia Election 2024: A Case Study
The Use of AI in Indonesia Election 2024: A Case Study
 

JavaScript Modules Past, Present and Future

  • 1. https://nicr.dev JavaScript Modules: Past, Present and Future NICOLÒ RIBAUDO @nicolo-ribaudo @NicoloRibaudo https://nicr.dev
  • 2. https://nicr.dev 2 NICOLÒ RIBAUDO ● Working at Igalia on web standards ● TC39 delegate ● Maintaining Babel, the JavaScript compiler in collaboration with
  • 4. https://nicr.dev The original "modules" system Back in the day, JavaScript was mostly used to add small bits of interactivity to web pages. There were no "modules", and a few external libraries were loaded installing properties directly on the window object. <script src="https://code.jquery.com/jquery.min.js"></script> <script> $(document).ready(function() { $("#hello").css("color", "red"); }); </script> 4
  • 5. https://nicr.dev 2009: CommonJS 5 ~ Kevin Dangoor https://www.blueskyonmars.com/2009/01/29/what-server-side-javascript-needs/
  • 6. https://nicr.dev var chalk = require("chalk"); exports.error = function (message) { console.log(chalk.red(message)); }; CommonJSImplementation(function (require, exports, module) { var chalk = require("chalk"); exports.error = function (message) { console.log(chalk.red(message)); }; }); 2009: CommonJS 6 Import other modules Expose values from this module
  • 7. https://nicr.dev 2009: CommonJS 7 ● An effort to standardize a modules system and a set of built-in APIs across multiple server-side environments CommonJS Modules/1.1 ● Only define the "module interface", implementations must bring their own runtime loader ● Implemented by Node.js, Narshall, SproutCore, and many others https://arstechnica.com/information-technology/2009/12/commonjs-effort-sets-javascript-on-path-for-world-domination/
  • 8. https://nicr.dev CommonJS' require is synchronous: how to design a module system that works in the browser? 2009: CommonJS 8 CommonJS' require is synchronous: how to design a module system that works in the browser? CommonJS Modules/Transport/C and Modules/AsynchronousDefinition Pre-declare all the dependencies that need to be loaded, and only start evaluating code once everything is ready. https://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition https://github.com/amdjs/amdjs-api/wiki/AMD
  • 9. https://nicr.dev 2010: AMD 9 Pre-declare all the dependencies that need to be loaded, and only start evaluating code once everything is ready. define("alpha", ["require", "exports", "beta"], function (require, exports, beta) { exports.verb = function() { return beta.verb(); //Or: return require("beta").verb(); } }); https://github.com/amdjs/amdjs-api/wiki/AMD
  • 10. https://nicr.dev 2010: AMD 10 Asynchronously load dependencies that cannot be statically declared. define(function (require) { require(['i18n/' + lang], function (i18n) { // modules i18n is now available for use. }); }); https://github.com/amdjs/amdjs-api/wiki/AMD
  • 11. https://nicr.dev 2010: AMD 11 AMD supports plugins, to let developers customize how modules are resolved, loaded and executed. define(['text!../templates/start.html'], function (template) { //do something with the template text string. });
  • 12. https://nicr.dev 2015: ECMAScript Modules // math.js export function sum() { let s = 0; for (let x of arguments) s =+ x; return s; } // main.js import { sum } from "./math.js"; console.log(sum(1, 2, 3)); // 6 12
  • 13. https://nicr.dev 2015: ECMAScript Modules ● Statically analyzable: runtimes can preload all the necessary dependencies before executing the code ● Minimal syntactic overhead (no boilerplate) ● Support for "named" and "default" exports (no overlapping module.exports vs module.exports.name) 13 Like AMD! Like CommonJS!
  • 14. https://nicr.dev 2015: ECMAScript Modules They are the result of multiple years of development, taking input from different parties and exploring many possible designs and features. 14
  • 15. https://nicr.dev 2015: ECMAScript Modules They are the result of multiple years of development, taking input from different parties and exploring many possible designs and features. 15 https://archives.ecma-international.org/1999/TC39WG/991115-futures.htm
  • 16. https://nicr.dev 2015: ECMAScript Modules They are the result of multiple years of development, taking input from different parties and exploring many possible designs and features. 16 Modules Systems for ES-Harmony, Kris Kowal and Ihab Awad, 2009-11 http://archives.ecma-international.org/2009/TC39/tc39-2009-011.pdf Simple Modules, Sam Tobin-Hochstadt and Dave Herman, 2010 http://archives.ecma-international.org/2010/TC39/tc39-2010-017.pdf Modules, Dave Herman, Sam Tobin-Hochstadt and Yehuda Katz, 2013 http://archives.ecma-international.org/2013/misc/2013misc4.pdf
  • 17. https://nicr.dev 2015 2016: ECMAScript Modules ECMAScript 2015 defined part of the ECMAScript Modules semantics. It was just in 2016, with the HTML integration, that modules had been fully specified and implementable. 17 https://github.com/whatwg/html/pull/443
  • 18. https://nicr.dev 2019: Dynamic import() Both CommonJS and AMD provided ways to dynamically require a module, but this capability was missing from the initial ECMAScript Modules version. import('i18n/' + lang).then(function (i18n) { // modules i18n is now available for use. }); // Since 2021, with top-level await let i18n = await import('i18n/' + lang); 18
  • 20. https://nicr.dev Today 20 ● ECMAScript Modules are being used in production applications and as a distribution format ● CommonJS and AMD are still widely used, both by legacy and new code ● There is no clear migration path from CommonJS/AMD to ECMAScript Modules yet
  • 21. https://nicr.dev What's missing from ES Modules? A way to synchronously import dependencies only when they are actually needed. // Supported by CommonJS! exports.circ = function (radius) { let PI = require("./heavy-computation-pi"); return 2 * PI * radius; }; 21
  • 22. https://nicr.dev What's missing from ES Modules? A way to easily write multiple modules in a single file. // Supported by AMD! define("pi", function () { return 3.14; }); define("math", ["pi"], function (pi) { return { circ: (radius) => 2 * pi * radius, }; }); 22
  • 23. https://nicr.dev What's missing from ES Modules? A way to customize the module loading process. // Supported by AMD! define("text!./doc.htm", function (docAsString) { // ... }); 23
  • 24. https://nicr.dev What's missing from ES Modules? A way to properly support resources other than JavaScript. ● JSON ● WebAssembly ● … 24
  • 26. https://nicr.dev TC39: the JS standard committee 26 ● TC39 designs the JavaScript language ● Made up of people from different companies, and the JS community ● Discusses and decides on new features through proposals
  • 27. https://nicr.dev Modules Harmony 27 ● The open design space around ECMAScript Modules is huge ● ECMAScript proposals are usually self-contained and developed in isolation ○ Every proposal must be motivated on its own ○ Every proposal must be complete on its own ● Cross-proposal coordination is necessary, to ensure that the evolution of ECMAScript Modules remains consistent
  • 28. https://nicr.dev September 2022 TC39 meeting July 2022 TC39 meeting March 2022 TC39 meeting Modules Harmony 28 November 2022 TC39 meeting January 2023 TC39 meeting March 2023 TC39 meeting May 2023 TC39 meeting
  • 31. https://nicr.dev Modules proposals under development 31 Import attributes Source phase imports (aka Import Reflection) Deferred import evaluation Custom module loading (aka Compartments layer 0) Module expressions Module declarations
  • 33. https://nicr.dev "Parameters for the underlying module loader" Import attributes 33 Please load the module ./math.js import { add, } from "./math.js"; ��💻 The JavaScriot "engine" (such as V8) doesn't have any I/O capabilities, and relies on a wrapper "runtime" to communicate with the world.
  • 34. https://nicr.dev "Parameters for the underlying module loader" Import attributes 34 Please load the module ./math.js Here it is! 📦 It has the these exports: - add - sub And you can execute it running this: Evaluate() { … } �� Please load the script file https://x.com/math.js Here it is! It's an application/javascript, with these contents: export let add = (x, y) => x + y; export let sub = (x, y) => x - y;
  • 35. https://nicr.dev "Parameters for the underlying module loader" Import attributes 35 Please load the module ./main.css, the developer said that it should have ● type: "css" import { styles, } from "./main.css" with { type: "css" }; ��💻 I want this module do be loaded as a CSS file…
  • 36. https://nicr.dev "Parameters for the underlying module loader" Import attributes 36 Please load the module ./main.css, the developer said that it should have ● type: "css" �� Please load the stylesheet https://x.com/main.css Here it is! It's a text/css, with these contents: .my-class { color: red; } type: "css" means that it should be a CSS stylesheet… type/css: matches what I expected for a CSS stylesheet ✓ Here it is! 📦 It has the these exports: - styles And you can execute it running this: Evaluate() { … }
  • 37. https://nicr.dev ⚠ Import assertions A previous version of the proposal only allowed asserting that the loaded module matched a given property: import styles from "./main.css" assert { type: "css" }; While implementing this feature, browsers realized that "assert-only" semantics didn't match what was needed so the proposal was changed: import styles from "./main.css" with { type: "css" }; 37
  • 39. https://nicr.dev The phases of importing a module 39 // https://x.com/main.js import("./mod.js"); globalThis: { … } baseURL: "https://x.com/main.js" Evaluate Execute all the loaded modules, according to the dependencies order, and expose the exported values Link Load all the dependencies, and bind imports to exports Attach context import { y } from "./dep.js"; export let x = 1 + y; globalThis: { … } baseURL: "https://x.com/mod.js" Fetch / compile import { y } from "./dep.js"; export let x = 1 + y; Resolve "https://x.com/mod.js"
  • 40. https://nicr.dev Source phase imports Exposing a module at an earlier phase import source modSource from "./mod"; modSoure is an object representing "./mod"'s source, unlinked and without any execution context attached. 40 Evaluate Link Attach context Resolve Fetch / compile
  • 41. https://nicr.dev WebAssembly Modules integration 41 Using fetch const url = import.meta.resolve("./crypto.wasm"); const responseP = fetch(url); const cryptoM = await WebAssembly.compileStreaming(responseP); cryptoM instanceof WebAssembly.Module; const cryptoI = await WebAssembly.instantiate(cryptoM, { mathModule: { add: (x, y) => x + y }, }); const { md5 } = cryptoI.exports; md5("Hello!"); // > 952d2c56d0485958336747bcdd98590d Using source imports import source cryptoM from "./crypto.wasm"; ● Module is preloaded while loading all the modules ● Easily statically analyzable for bundlers ● Goes through the existing module loading content security policies (CSPs)
  • 43. https://nicr.dev // ECMAScript Module export function circ(radius) { let PI = import("./computed-pi"); return 2 * PI * radius; } Deferred import evaluation // CommonJS exports.circ = function (radius) { let PI = require("./computed-pi"); return 2 * PI * radius; }; 43 // ECMAScript Module export async function circ(radius) { let PI = await import("./computed-pi"); return 2 * PI * radius; } ❓ async/await is "viral", it forces all the callers to be asynchronous 😕
  • 44. https://nicr.dev Deferred import evaluation Module loading must be asynchronous. Can we still avoid some initialization cost? import defer * as mod from "./computed-pi.js" export function circ(radius) { return 2 * mod.PI * radius; } mod is an import namespace object that triggers the evaluation of the corresponding module only when accessing its exports. 44 Evaluate Link Attach context Resolve Fetch / compile
  • 45. https://nicr.dev Blurring the line: top-level await Due to top-level await, some modules cannot be evaluated synchronously. 45 // a.js import defer * as b from "./b.js"; console.log("Eval A"); // b.js import "./c.js"; console.log("Eval B"); // c.js await aPromise; console.log("Eval C"); Evaluate Link Attach context Resolve Fetch / compile ● Since c.js is asynchronous, its evaluation cannot be optimized await and it's evaluated eagerly. ● Later, when accessing b.something, only b.js still needs to be evaluated.
  • 47. https://nicr.dev Please load the module ./math.js Here it is! 📦 It has the these exports: - add - sub And you can execute it running this: Evaluate() { … } �� Please load the script file https://x.com/math.js Here it is! It's an application/javascrip t, with these contents: export let add = (x, y) => x + y; export let sub = (x, y) => x - y; Importing a module 47 Evaluate Link Attach context Resolve Fetch / compile Can we allow hooking into this?
  • 48. https://nicr.dev 48 Browsers: Service Workers � Please load the script file https://x.com/math.ts ⚙ ⚙ Here it is! It's an application/javascript, with these contents: export let add = (x, y) => x + y; export let sub = (x, y) => x - y; Please load the script file https://x.com/math.ts Here it is! It's an application/typescript, with these contents: export let add = (x: num, y: num) => x + y; export let sub = (x: num, y: num) => x - y; Fetch / compile The service worker receives the resolved URL… … and returns the corresponding source.
  • 49. https://nicr.dev 49 Browsers: Service Workers // service-worker.js addEventListener("fetch", function (event) { if (event.request.url.endsWith(".ts")) { event.respondWith( fetch(event.request).then(async response => { let { code } = await babel.transform(await response.text(), babelConfig).code; return new Response(code, { headers: { ...response.headers, "content-type": "text/javascript" } }); }) ); } else { event.respondWith(fetch(event.request)); } }); https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope/fetch_event
  • 50. https://nicr.dev 50 Node.js: --experimental-loader � ⚙ ⚙ Please resolve ./math.ts from file:///proj/main.js It resolves to file:///proj/math.ts function resolve(specifier, ctx, next) { // ... } … … Please load the file file:///proj/math.ts Here it is! It's a module file, with these contents: // ... ⚙ ⚙function load(url, ctx, next) { // ... } … … Resolve Fetch / compile https://nodejs.org/api/esm.html#loaders
  • 51. https://nicr.dev Proposal: custom module loading 51 Please load the module ./math.js async importHook(specifier) { const url = resolveURL(specifier); const source = await fetchSource(url); return new Module(source, hooks); } new Module(source, { async importHook(specifier) { const url = resolveURL(specifier); const source = await fetchSource(url); return new Module(source, hooks); }, }); Here it is! 📦 It has the these exports: - add - sub And you can execute it running this: Evaluate() { … } Attach context Resolve Fetch / compile
  • 52. https://nicr.dev import module wasmM from "./mod.wasm"; wasmM instanceof Module; import module jsM from "./mod.js"; jsM instanceof Module; await import(jsM); let module = new Module(source, { async importHook() { /* ... */ }, importMeta: { /* ... */ }, // Any other context baseURL: "https://...", }); await import(module); Module and ModuleSource 52 import source wasmS from "./mod.wasm"; wasmS instanceof WebAssembly.Module; import source jsS from "./mod.js"; jsS instanceof ???; let source = WebAssembly.compile(bytes); let source = new ModuleSource(` import { x } from "dep"; console.log(x); `); Evaluate Link Attach context Resolve Fetch / compile
  • 54. https://nicr.dev Module expressions 54 Modules would now hava a first-class representation in the language (like functions): fun instanceof Function; mod instanceof Module; … or with static syntax: let fun = function (x) { return x + 1; }; let mod = module { export default 7; }; You can create them with the respective constructors: let fun = new Function( "x", "return x + 1;" ); let mod = new Module( new ModuleSource(` export default 7; `) ); Module expressions!
  • 55. https://nicr.dev Module expressions 55 And you can later execute them: fun(); await import(mod); Module expressions! … or with static syntax: let fun = function (x) { return x + 1; }; let mod = module { export default 7; }; You can create them with the respective constructors: let fun = new Function( "x", "return x + 1;" ); let mod = new Module( new ModuleSource(` export default 7; `)
  • 56. https://nicr.dev Module expressions 56 Functions have a declaration form: function fun(x) { return x + 1; } Module expressions! … or with static syntax: let fun = function (x) { return x + 1; }; let mod = module { export default 7; }; You can create them with the respective constructors: let fun = new Function( "x", "return x + 1;" ); let mod = new Module( new ModuleSource(` export default 7; `) ???
  • 57. https://nicr.dev Module expressions use cases 57 Co-locating code to be executed in different threads let worker = new Worker("/modules-runner"); worker.postMessage(module { export default function () { // Do some expensive work! } }); worker.addEventListener("message", ({ data }) => { console.log("Result", data + 2); }); Improved ergonomics for custom loaders import source modSource from "./my-file.js"; // Mock access to the file system async function importHook(specifier) { if (specifier === "fs") { return module {} export const readFile = () => "Hello!"; }; } return import(resolve(specifier)); } import(new Module(modSource, { importHook })); Logically linked code can live in the same file
  • 59. https://nicr.dev Module declarations 59 Functions and modules have a declaration form: function fun(x) { return x + 1; } module Mod { export default 7; } Module declarations! … or with static syntax: let fun = function (x) { return x + 1; }; let mod = module { export default 7; }; You can create them with the respective constructors: let fun = new Function( "x", "return x + 1;" ); let mod = new Module( new ModuleSource(` export default 7; `)
  • 61. https://nicr.dev Module declarations 61 // bundle.amd.js define("pi", function () { return 3.14; }); define("math", ["pi"], function (pi) { return { circ(radius) { return 2 * pi * radius; } }; }); // bundle.esm.js module PI { export default 3.14; } module Math { import pi from PI; export function circ(radius) { return 2 * pi * radius; } }
  • 62. https://nicr.dev Module declarations 62 They can be imported, exported, nested, and passed around. // vendor.bundle.js export module lodash { module Internal { /* ... */ } module Get { import { something } from Internal; export function get(obj, path) { /* ... */ } } export { get } from Get; // ... } // vendor.external.js export module Preact from "https://example.com/preact@10.13.2"; // main.js import { lodash } from "./vendor.bundle.js"; import { Preact } from "./vendor.external.js"; import { get, set } from lodash; import { h } from Preact; get({ a: 1 }, "a");
  • 63. https://nicr.dev Modules proposals under development 63 Import attributes Source phase imports (aka Import Reflection) Deferred import evaluation Custom module loading (aka Compartments layer 0) Module expressions Module declarations
  • 64. https://nicr.dev When is all of this coming? 64 When is all of this coming?