Konubinix' opinionated web of thoughts

ECMAScript

Fleeting

Created by TC39

document at https://tc39.es/ecma262/ is the most accurate and up-to-date ECMAScript specification

https://tc39.es/ecma262/

Realm

Before it is evaluated, all ECMAScriptV code must be associated with a realm. Conceptually, a realm consists of a set of intrinsic objects, an ECMAScript global environment, all of the ECMAScript code that is loaded within the scope of that global environment, and other associated state and resources

https://tc39.es/ecma262/#realm

.mjs extension

ESM

Before ES6 we really went out of our ways to obtain modules in JavaScript. Systems like RequireJS, Angular’s dependency injection mechanism, and CommonJS have been catering to our modular needs for a long time now – alongside with helpful tools such as Browserify and Webpack

https://ponyfoo.com/articles/es6-modules-in-depth

ES6 modules have been heavily influenced by CommonJS

https://ponyfoo.com/articles/es6-modules-in-depth

ES6 module system, strict mode is turned on by default. In case you don’t know what strict mode is, it’s just a stricter version of the language that disallows lots of bad parts of the language

https://ponyfoo.com/articles/es6-modules-in-depth

CommonJS, you export values by exposing them on module.exports

https://ponyfoo.com/articles/es6-modules-in-depth

could expose anything from a value type to an object, an array, or a function. module.exports = 1 module.exports = NaN module.exports = ‘foo’ module.exports = { foo: ‘bar’ } module.exports = [‘foo’, ‘bar’] module.exports = function foo () {}

https://ponyfoo.com/articles/es6-modules-in-depth

mimic the CommonJS code we just saw by changing module.exports = into export default. export default 1 export default NaN export default ‘foo’ export default { foo: ‘bar’ } export default [‘foo’, ‘bar’] export default function foo () {}

https://ponyfoo.com/articles/es6-modules-in-depth

export statements can only be placed at the top level in ES6 modules

https://ponyfoo.com/articles/es6-modules-in-depth

CommonJS you don’t even have to assign an object to module.exports first. You could just tack properties onto it

https://ponyfoo.com/articles/es6-modules-in-depth

module.exports.foo = ‘bar’ module.exports.baz = ‘ponyfoo’

https://ponyfoo.com/articles/es6-modules-in-depth

export var foo = ‘bar’ export var baz = ‘ponyfoo’

https://ponyfoo.com/articles/es6-modules-in-depth

ES6 modules export bindings, not values or references

https://ponyfoo.com/articles/es6-modules-in-depth

ES6 modules let you export lists of named top-level members. var foo = ‘ponyfoo’ var bar = ‘baz’ export { foo, bar }

https://ponyfoo.com/articles/es6-modules-in-depth

export something with a different name, you can use the export { foo as bar } syntax, as shown below. export { foo as ponyfoo }

https://ponyfoo.com/articles/es6-modules-in-depth

for the most part I’d encourage you to use export default

https://ponyfoo.com/articles/es6-modules-in-depth

will execute any code in the top level of the lodash module, though. import ’lodash’

https://ponyfoo.com/articles/es6-modules-in-depth

CommonJS you’d import something using a require statement, like so. var _ = require(’lodash’)

https://ponyfoo.com/articles/es6-modules-in-depth

import the default exported binding from an ES6 module, you just have to pick a name for it. The syntax is a bit different than declaring a variable because you’re importing a binding, and also to make it easier on static analysis tools. import _ from ’lodash’

https://ponyfoo.com/articles/es6-modules-in-depth

add some braces and pick any named exports you want

https://ponyfoo.com/articles/es6-modules-in-depth

import {map, reduce} from ’lodash’

https://ponyfoo.com/articles/es6-modules-in-depth

By default, it is deferred, even when written inline. So, for example, these will run in the opposite order:

<script type=“module”>console.log(“module”);</script>

<script>console.log(“classic script”);</script>

https://jameshfisher.com/2020/09/25/javascript-modules-for-grumpy-developers-from-2005/

import to load new modules

<script> const url = ‘/myModule.js’; import(url).then(module => { console.log(Object.keys(module)); console.log(module.x); }); </script>

https://jameshfisher.com/2020/09/25/javascript-modules-for-grumpy-developers-from-2005/

oddly, conventional relative URLs like dependency.js are banned. If you try to import(“dependency.js”), you’ll get an obscure error like “Failed to resolve module specifier ‘dependency.js’”. The reason is that relative URLs are forced to start with ./ or ../. Any other forms (called “bare imports”) are reserved for mysterious future uses (such as this “import maps” feature).

https://jameshfisher.com/2020/09/25/javascript-modules-for-grumpy-developers-from-2005/

dynamic import

import() call, which returns a promise of a module. This is actually known as a “dynamic import” expression

https://jameshfisher.com/2020/09/25/javascript-modules-for-grumpy-developers-from-2005/

static import

most general form of static import statement is import * as myModule from ‘./myModule.js’. This is mostly equivalent to the dynamic statement const myModule = await import(’./myModule.js’), except that you can’t use await at the top-level in JS modules. The static form can magically import the module synchronously, because the browser has fetched and executed all static dependencies before it runs the module.

https://jameshfisher.com/2020/09/25/javascript-modules-for-grumpy-developers-from-2005/

ES6

Notes linking here