Hone logo
Hone
Problems

Building a Basic JavaScript Module System

Creating a module system in JavaScript allows you to organize your code into reusable and maintainable units. This challenge asks you to implement a simplified module system that enables you to define, load, and use modules, promoting code organization and preventing namespace collisions. This is a fundamental concept in modern JavaScript development, especially when working with larger projects.

Problem Description

You are tasked with creating a rudimentary module system in JavaScript. The system should allow you to:

  1. Define Modules: Modules should be defined using a specific function (e.g., defineModule). This function should accept a module name and an object containing the module's exports.
  2. Load Modules: A function (loadModule) should be provided to retrieve a module by its name. This function should return the module's exports.
  3. Module Storage: The module system should maintain a registry of defined modules, accessible internally.
  4. Error Handling: The loadModule function should handle cases where a module has not been defined, returning an appropriate error message or undefined.

Key Requirements:

  • The module system should not rely on any external libraries or frameworks.
  • Modules should be encapsulated; their internal state should not be directly accessible from outside the module.
  • The module system should prevent naming conflicts between modules.

Expected Behavior:

  • When a module is defined, it should be stored in the module registry.
  • When a module is loaded, the loadModule function should return the module's exports.
  • Attempting to load a non-existent module should result in an error or undefined being returned.

Edge Cases to Consider:

  • What happens if you try to define a module with the same name twice? (Should it overwrite the previous definition?)
  • How should the module system handle circular dependencies (Module A depends on Module B, and Module B depends on Module A)? (For simplicity, you can assume circular dependencies won't be explicitly tested, but consider how your design might handle them.)
  • What happens if the defineModule function is called with invalid input (e.g., a module name that is not a string)?

Examples

Example 1:

Input:
defineModule('math', {
  add: (a, b) => a + b,
  subtract: (a, b) => a - b
});

Output:
{ add: [Function: add], subtract: [Function: subtract] }
Explanation: A module named 'math' is defined with two functions, 'add' and 'subtract'. The output is the exported object.

Example 2:

Input:
loadModule('math');

Output:
{ add: [Function: add], subtract: [Function: subtract] }
Explanation: The 'math' module is loaded, and its exports are returned.

Example 3:

Input:
loadModule('nonExistentModule');

Output:
undefined
Explanation: The 'nonExistentModule' has not been defined, so the function returns undefined.

Constraints

  • The module system should be implemented using plain JavaScript (no external libraries).
  • Module names should be strings.
  • The defineModule function should accept a module name and an object containing the module's exports.
  • The loadModule function should accept a module name and return the module's exports or undefined if the module is not found.
  • The module system should be reasonably efficient for a small number of modules (e.g., up to 100). Performance is not a primary concern for this challenge.

Notes

Consider using a simple object or Map to store the modules. Think about how to encapsulate the module registry to prevent external access. The goal is to create a basic, functional module system that demonstrates the core principles of modularity in JavaScript. You don't need to implement advanced features like dependency injection or asynchronous loading. Focus on the fundamental definition, storage, and retrieval of modules.

Loading editor...
javascript