Senior Software Developer
8x8 Inc.
I. Pre-transpilers era
What do we want to achieve?
What do I mean by this?
So how did client-side code looked before tools?
// counter.js
const counterModule = (() => {
let counter = 0;
const increaseCounter = () => counter++;
const decreaseCounter = () => counter--;
const resetCounter = () => counter = 0;
return {
increaseCounter,
decreaseCounter,
resetCounter,
get counter() {
return counter;
}
};
})();
... a module format to solve JavaScript scope issues by making sure each module is executed in its own namespace
webpack docs
Syntax
Implementations
Main characteristics
Data passed by value or reference
// counter.js
let counter = 0;
const increaseCounter = () => counter++;
const decreaseCounter = () => counter--;
const resetCounter = () => counter = 0;
module.exports = {
increaseCounter,
decreaseCounter,
resetCounter,
get counter() {
return counter;
}
};
console.log(3);
console.log(2);
console.log(1);
setTimeout(() => require('./module2'), 3000);
if (false) {
require('./module3');
}
require('./module');
index.js
module.js
module2.js
module3.js
$ node index.js
module.js
node.js runtime
index.js
module2.js
console.log(3);
console.log(2);
console.log(1);
setTimeout(() => require('./module2'), 3000);
if (false) {
require('./module3');
}
require('./module');
index.js
module2.js
module3.js
module.js
Same result with Webpack
I. Pre-transpilers era
II. Post-transpilers era
import defaultMember from "module-name";
import * as name from "module-name";
import { member } from "module-name";
import { member as alias } from "module-name";
import { member1 , member2 } from "module-name";
import { member1 , member2 as alias2 , [...] } from "module-name";
import defaultMember, { member [ , [...] ] } from "module-name";
import defaultMember, * as name from "module-name"
import "module-name";
export { name1, name2, …, nameN };
export { variable1 as name1, variable2 as name2, …, nameN };
export let name1, name2, …, nameN; // also var
export let name1 = …, name2 = …, …, nameN; // also var, const
export default expression;
export default function (…) { … } // also class, function*
export default function name1(…) { … } // also class, function*
export { name1 as default, … };
// Stage 1 proposal - Lee Byron
export * from …;
export { name1, name2, …, nameN } from …;
export { import1 as name1, import2 as name2, …, nameN } from …;
export default from ...;
export { default } from ...;
Implementations
Main characteristics
Live bindings
let counter = 0;
const incrementCounter = () => counter++;
export { counter, incrementCounter };
counter.js
import { counter, incrementCounter } from './counter';
console.log(counter);
incrementCounter();
console.log(counter);
import { counter, incrementCounter } from './counter';
console.log(counter); // 0
incrementCounter();
console.log(counter); // 1
Static module structure
Read only imports
export default 1+1;
export const a = { b: 2 };
import * as module from './module';
module.a.b = 3;
module.js
import { a } from './module';
a = 2
import * as module from './module';
module.a.b = 3; //SyntaxError: Cannot assign to read-only object
import { a } from './module';
a = 2 // 'a' is read-only
I. Pre-transpilers era
II. Post-transpilers era
III. Native era
Implementations
Syntax I
<script type="module">
import { counter, incrementCounter } from './counter.js';
document.body.append(`${counter}\n`);
incrementCounter();
document.body.append(`${counter}\n`);
</script>
import keyword for static parsing
Syntax II
import('./counter.js').then(counterModule => {
console.log(counterModule.counter); // 0
counterModule.incrementCounter();
console.log(counterModule.counter); // 1
});
* stage 3 proposal (ES2018?)
import function for dynamic parsing
Main characteristics
OK but ... the ECMAScript spec (ecma-262) only talks about syntax ...
The Web Hypertext Application Technology Working Group
How the module graph gets processed by the browser
credits: Domenic Denicola
construction
instantiation
evaluation
I. Pre-transpilers era
II. Post-transpilers era
III. Native era
IV. ...
IV. Web Assembly Era
WASM Modules
Resources and references:
https://github.com/andrei-cacio/es-modules