Search code examples
javascriptes6-modules

best aproach for importing same name functions in ES6 modules


I need to import same name function from two different modules in ES6. Should I rename each function with the as alias on the import or use the Reveal Module Pattern? Or perhaps there're better aproaches?

Solution with alias

projects.module.js

    function init() {
      console.log("projects module initiated!");
    }

    export { init };

projects_steps.module.js

    function init() {
      console.log("project steps module initiated!");
    }

    export { init };

index.js

    import { init as projectsInit } from "./projects.module.js";
    import { init as projectStepsInit } from "./project_steps.module.js";

    projectsInit();
    projectStepsInit();

Solution with Reveal Module Pattern

projects.module.js

var projects = (() => {
  function init() {
    console.log("projects module initiated!");
  }

  return {
    init: init
  };
})();

export { projects };

project_steps.module.js

var projectSteps = (() => {
  function init() {
    console.log("project steps module initiated!");
  }

  return {
    init: init
  };
})();
export { projectSteps };

index.js

import { projects } from "./projects.module.js";
import { projectSteps } from "./project_steps.module.js";

projects.init();
projectSteps.init();

Just to add, in the future will be added more functions to these modules.

Thanks in advance!


Solution

  • The Revealing Module Pattern is an older pattern that predates ES6 modules. It's purpose was to hide the details of a "module" in a private function scope and to prevent the pollution of the global scope.

    With ES6 modules this is completely unnecessary. Your question is really about the pros and cons of exporting individual functions versus a single interface.

    Consider using the following approach instead:

    projects.module.js

    function init() {
      console.log("projects module initiated!");
    }
    
    function foo() {
    }
    
    // export an object as the default, which will act as your interface
    export default { init, foo };
    

    projects_steps.module.js

    function init() {
      console.log("project steps module initiated!");
    }
    
    function foo() {
    }
    
    // you can still export individual functions where it makes sense
    export function projectStepsThing() {
    }
    
    // if you don't want to export a default, then just set an object like so:
    export const projectSteps = { init, foo };
    

    index.js

    import projects from "./projects.module.js";
    import { projectSteps, projectStepsThing } from "./project_steps.module.js";
    
    projects.init();
    projects.foo();
    projectSteps.init();
    projectSteps.foo();
    
    projectStepsThing();