Module fragments:
For stage 1
Daniel Ehrenberg
Igalia in partnership with
March 2021 TC39 meeting
@littledan
My hope:�Load ES modules�natively and efficiently
@littledan
Will module blocks solve this problem?
@littledan
No, because module blocks can't import each other
const countBlock = module {
let i = 0;
export function count() {
i++;
return i;
}
};
const uppercaseBlock = module {
export function uppercase(string) {
return string.toUpperCase();
}
};
const combinedBlock = module {
const { count } = await import(countBlock);
const { uppercase } =� await import(uppercaseBlock);
console.log(count()); // 1
console.log(uppercase("daniel")); // "DANIEL"
};
// ReferenceError as we can't close over count or uppercase!!
@littledan
Instead, we need to statically bind module map entries
module "#count" {
let i = 0;
export function count() {
i++;
return i;
}
}
module "#uppercase" {
export function uppercase(string) {
return string.toUpperCase();
}
}
module "#combined" {
import { count } from "#count";
import { uppercase } from "#uppercase";
console.log(count()); // 1
console.log(uppercase("daniel")); // "DANIEL"
};
@littledan
Isn't it better to use more general resource bundles?
@littledan
Relevance for content blocking
@littledan
| | | | | | | | | |
Individual resources | | | | | | | | | |
Bundling | | | | | | | | | |
JS module fragments | | | | | | | | | |
Resource bundles | | | | | | | | | |
🌊 Waterfall
🗐Per-resource overhead
🕹️Emulation cost
⇆ Inter-process communication
🗜️Compression
≡ Parallel processing
🚿 Streaming
🪓 Code splitting/chunking
💰 Caching
BROAD INACCURATE BRUSH, sorry
@littledan
Testing use case
// math.js
export function add(a, b) {
return a + b
}
export module "#test" {
import { add } from "#"
export function addTest() {
assert(add(35, 7) === 42)
}
}
@littledan
Do module fragments subsume module blocks?
@littledan
Why fragments? Why # ?
@littledan
Exported vs local module fragments (#4)
// lib.js
// Only accessible within this file
module '#private' {
export function doSomethingPrivate() {}
}
// Accessible from outside the file.
export module '#public' {
import {doSomethingPrivate} from '#private';
export function publicFunction() {
doSomethingPrivate();
}
}
// usage.js
import {publicFunction} from "./lib.js#public";
@littledan
Concerns about using #
@littledan
HTML integration
@littledan
tl;dr
@littledan