ES Modules are singletons by default - they're only executed once:
// database.js
const connection = await connectToDatabase();
export { connection };
// Multiple imports get the same instance
import { connection } from './database.js'; // Same connection
// features.js
export const ENABLE_DARK_MODE = true;
export const ENABLE_ANALYTICS = false;
// app.js
import { ENABLE_ANALYTICS } from './features.js';
if (ENABLE_ANALYTICS) {
await import('./analytics.js');
}
// plugin-manager.js
const plugins = [];
export function registerPlugin(plugin) {
plugins.push(plugin);
}
export function getPlugins() {
return plugins;
}
// plugins/logger.js
import { registerPlugin } from '../plugin-manager.js';
registerPlugin({ name: 'logger', init() { /* ... */ } });
// router.js
const routes = {
'/': () => import('./pages/home.js'),
'/about': () => import('./pages/about.js'),
'/contact': () => import('./pages/contact.js')
};
async function navigate(path) {
const module = await routes[path]();
module.render();
}
Create a barrel file to simplify imports:
// utils/index.js
export { add, subtract } from './math.js';
export { formatDate } from './date.js';
export { validateEmail } from './validation.js';
// Now consumers can import everything from one place
import { add, formatDate } from './utils/index.js';