TIL how Node/V8 works with imports/exports
POSTED ON:
TAGS: node advanced-js javascript
This post is crazy. Not like, crazy in a "Don't do this!" but crazy in a "Why Javascript do that?"
The post is Jake Archibald's `export default thing` is different to `export { thing as default }
Something to point out -- this isn't about Javascript, but more about the way Javascript is interpreted through the V8 engine, Google's high-performance JS and WebAssembly Engine.
This is accurate only up to how JS works in Chrome-based browsers, and NodeJS, as Node uses V8 under the hood.
how imports work #
Imports are 'live bindings' or what some other languages call a 'reference'. This means when a different value is assigned to siameseCat
in cats.js
, that change is reflected in the import in main.js
.
They're pointing to the same thing.
// in main.js
// references the original
import { siameseCat } from "./cats.js";
// references the original
const cats = await import("./cats.js");
// Destructuring assigns the current value (rather than a live reference) to a new identifier.
const { cats.siameseCat } = await import("./cats.js");
The GOTCHA is that it looks like destructuring, but it's not.
// not destructuring! This is still a reference!
import { siameseCat } from "./cats.js";
// This is destructuring, and a new identifier
const { cats.siameseCat } = await import("./cats.js");
how exports work #
There's two ways to export functions.
// cats-export.js
let cat = () => {
return ['black', 'tuxedo', 'fluffy'];
};
let specificCat = 'saimese';
// Method 1: These export a live reference
export { specificCat, cat, cat as default}; // takes live changes
// Method 2: These export the current value
export default cat; // ['black', 'tuxedo', 'fluffy']
export specificCat; // saimese
export 'cat'; // you can export pure values!
As a wrap-up and shortcut list (taken directly from the blog):
// These give you a live reference to the exported thing(s):
import { thing } from './module.js';
import { thing as otherName } from './module.js';
import * as module from './module.js';
const module = await import('./module.js');
// This assigns the current value of the export to a new identifier:
let { thing } = await import('./module.js');
// These export a live reference:
export { thing };
export { thing as otherName };
export { thing as default };
// These export the current value:
export default thing;
export default 'hello!';
Related TILs
Tagged: node