JavaScript Modules - Exercise 3

Move shared values or operations into a third module so the original modules no longer import each other directly.

javascript

// shared.js
export const roles = { admin: 'Admin' };
// user.js and format.js can both import roles.js.

Each module may be evaluated before the other has finished initializing its exports. Move work behind a function or remove the cycle.

javascript

// Prefer calling after initialization:
export function getLabel() {
  return formatUser(user);
}

Use the module system required by the runtime and project configuration. ESM uses static import/export; CommonJS uses require/module.exports.

javascript

// ESM
export { add };
import { add } from './math.js';

// CommonJS
module.exports = { add };
const { add } = require('./math');

Use a dynamic import inside the event or condition that needs the feature.

javascript

button.addEventListener('click', async () => {
  const { openEditor } = await import('./editor.js');
  openEditor();
});

Dynamic imports return Promises, so a missing module or evaluation error rejects that Promise. Use try...catch with await, or attach .catch(), to show a fallback or recover gracefully.

javascript

try {
  const feature = await import('./optional-feature.js');
  feature.start();
} catch (error) {
  showUnavailableMessage(error);
}

A regular top-level import has a literal module path, allowing tools to build the dependency graph before execution.

javascript

import { format } from './format.js';
// The path is known during build analysis.

Re-export only the public API from an entry module and keep internal files private to the feature.

javascript

// users/index.js
export { createUser } from './create-user.js';
export { findUser } from './find-user.js';

Keep modules focused, export pure functions where possible, and inject external dependencies instead of hiding them in module-level state.

javascript

export function total(items, taxRate) {
  return items.reduce((sum, item) => sum + item.price, 0) * (1 + taxRate);
}

In an ES module, await can appear at the top level and pauses dependent modules until the Promise settles.

javascript

const config = await fetch('/config.json').then(response => response.json());
export default config;

Export only stable operations that other modules need, and keep implementation helpers unexported.

javascript

function normalize(input) {
  return input.trim().toLowerCase();
}
export function createKey(input) {
  return normalize(input);
}
All sections expanded. Activate the control to collapse all sections.