ECMAScript
Fleeting- External reference: https://tc39.es/ecma262/#realm
- External reference: https://tc39.es/ecma262/
Created by TC39
document at https://tc39.es/ecma262/ is the most accurate and up-to-date ECMAScript specification
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
.mjs extension
- External reference: https://tc39.es/ecma262/#sec-modules
ESM
-
External reference: https://tc39.es/ecma262/#sec-modules
-
External reference: https://jameshfisher.com/2020/09/25/javascript-modules-for-grumpy-developers-from-2005/
things like <script type=“module”> or import/export keywords or files with the extension .mjs
— https://jameshfisher.com/2020/09/25/javascript-modules-for-grumpy-developers-from-2005/
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
ES6 modules have been heavily influenced by CommonJS
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
CommonJS, you export values by exposing them on module.exports
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 () {}
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 () {}
export statements can only be placed at the top level in ES6 modules
CommonJS you don’t even have to assign an object to module.exports first. You could just tack properties onto it
module.exports.foo = ‘bar’ module.exports.baz = ‘ponyfoo’
export var foo = ‘bar’ export var baz = ‘ponyfoo’
ES6 modules export bindings, not values or references
ES6 modules let you export lists of named top-level members. var foo = ‘ponyfoo’ var bar = ‘baz’ export { foo, bar }
export something with a different name, you can use the export { foo as bar } syntax, as shown below. export { foo as ponyfoo }
for the most part I’d encourage you to use export default
will execute any code in the top level of the lodash module, though. import ’lodash’
CommonJS you’d import something using a require statement, like so. var _ = require(’lodash’)
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’
add some braces and pick any named exports you want
import {map, reduce} from ’lodash’
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
- deno
- determining module system
- modules loaders
- TC39
- Universal Module Definition
- What are CJS, AMD, UMD, and ESM in Javascript?