Frontend Engineering
JavaScript Module Systems
Quiz: What Gets Exported?
intermediate8 min read
Test Your Module Systems Knowledge
Time to stress-test your mental models. Each question presents a code snippet involving imports, exports, or module behavior. Predict the outcome before revealing the answer. Don't guess — trace through the module system step by step.
These are ordered by difficulty. The first few test fundamentals; the later ones test edge cases that catch even experienced developers.
Challenge 1: exports vs module.exports
Quiz
// counter.js
exports.count = 0;
exports = { increment: () => {} };
Challenge 2: CJS Caching Behavior
Quiz
// state.js
exports.value = 0;
exports.increment = function() { exports.value++; };
// main.js
const state = require('./state');
console.log(state.value); // ?
state.increment();
const state2 = require('./state');
console.log(state2.value); // ?
Challenge 3: ESM Live Bindings
Quiz
// counter.js
export let count = 1;
export function increment() { count++; }
// main.js
import { count, increment } from './counter.js';
console.log(count); // ?
increment();
console.log(count); // ?
Challenge 4: CJS Circular Dependency
Quiz
// a.js
exports.loaded = false;
const b = require('./b');
console.log('a:', b.loaded);
exports.loaded = true;
// b.js
exports.loaded = false;
const a = require('./a');
console.log('b:', a.loaded);
exports.loaded = true;
// Running: node a.js
// Output order: b: ?, then a: ?
Challenge 5: Default vs Namespace Import
Quiz
// utils.js — only named exports, NO default export
export function greet() { return 'hello'; }
export function farewell() { return 'bye'; }
// main.js — using DEFAULT import syntax (not namespace import)
import utils from './utils.js';
console.log(utils); // ?
// Hint: what's the difference between
// import utils from './utils.js'
// import * as utils from './utils.js'
Challenge 6: The Reassignment Trap
Quiz
// config.js
export let name = 'original';
// main.js
import { name } from './config.js';
console.log(name);
name = 'updated'; // ?
console.log(name);
Challenge 7: Tree Shaking and Side Effects
Quiz
// math.js (in a package with "sideEffects": false)
console.log('math module loaded');
export function add(a, b) { return a + b; }
export function multiply(a, b) { return a * b; }
function globalSetup() { /* registers something */ }
globalSetup();
Challenge 8: package.json exports Resolution
Quiz
{
"name": "my-ui",
"exports": {
"./button": {
"types": "./dist/types/button.d.ts",
"import": "./dist/esm/button.js",
"require": "./dist/cjs/button.cjs",
"default": "./dist/esm/button.js"
}
}
}
Challenge 9: Dynamic import() Return Value
Quiz
// worker.js
export default function process(data) { return data.toUpperCase(); }
export function helper() { return 'help'; }
// main.js
const mod = await import('./worker.js');
console.log(mod.default); // ?
console.log(mod.helper); // ?
Challenge 10: The Dual Module Hazard
Quiz
// Assume 'state-manager' has both CJS and ESM entry points
// in its package.json exports field
// legacy-plugin.cjs (loaded by main app)
const store = require('state-manager');
store.increment(); // Affects CJS instance
// modern-plugin.mjs (also loaded by main app)
import store from 'state-manager';
store.increment(); // Affects ESM instance
// main.cjs — later reads the CJS instance
const store = require('state-manager');
console.log(store.count); // ?
How Did You Do?
If you got 8+ right, you have a solid understanding of JavaScript module systems. The tricky parts — live bindings, circular deps, the dual module hazard — are the concepts that separate developers who use modules from developers who understand them.
If some caught you off guard, revisit the specific topics: