ES6 | Modules

Modules in JavaScript helps to modularize the code by partitioning the entire code into various modules which can be imported from anywhere and thus used. It makes it easy to reuse a piece of code, maintain code and debug code. Also, it prevents many problems linked with using global variables and functions. Earlier the modules were implemented through various external libraries and frameworks but with ECMAScript2015, it was made an implicit part of the JavaScript constructs.

Exporting Values: JavaScript because of its multi-paradigm nature allows us to export functions, objects, classes and primitive values using the keyword export. In JavaScript, exports can either be:

  • Named Exports: Any function, class or variable exported using the named export can only be imported using the same name. Multiple functions and variables can be exported and imported using named export.

    Example:
    products.mjs file:



    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // Module products.mjs
    var numberSale=0;
    var totalSale=0;
      
    // Export keyword can be specified individually
    // with functions and variables.
    export function buy(buyer, item)
    {
        buyer.total=buyer.total+item.price;
    }
    export function sell(item)
    {
        totalSale=totalSale+item.price;
        numberSale=numberSale+1;
        item.quantity=item.quantity-1;
        return 0;
    }
      
    // Export keyword can also be used
    // with multiple values.
    export { totalSale, numberSale};

    chevron_right

    
    

    index.mjs file:

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    import {total sale, numberSale, buy, sell } from './product.mjs';
    let buyer={
        name:"GeeksforGeeks",
        total:0
    };
    let item={
        name="butter",
        price:10,
        quantity:100
    };
    console.log("Total Sale till now = ",totalSale);
    buy(buyer, item);
    sell(item);
    console.log("Total expense of buyer = ",buyer.total);
    console.log("Quantity of item left = ",item.quantity);
    console.log("Total Sale till now = ",totalSale);

    chevron_right

    
    

    Output:

  • Default Exports: Anything exported as a default can be imported using any name. A maximum of 1 value can be exported using the default export. To export multiple values, one can combine them in an object and then use default export to export this object.
    Example:

    // Module secret_ingredient.mjs
    var secretIngredient="Salsa";
    export default secretIngredient;
    
  • Note: Both of these exports can be mixed within a module with a maximum of 1 default export and any number of named exports to make a hybrid export.

    Importing Values: Only the values exported from a module can be imported using the import keyword. The various syntax for importing the exports are given below.

    Examples:

    • Importing the named exports:
      import { buy, sell} from './modules/products.mjs';
    • Importing the named exports using aliases:
      import { buy as buyCustomer, sell as sellCustomer} from './modules/products.mjs';
    • Importing the default export:
      import productSecret from './modules/secret_ingredient.mjs';
    • Importing all the exports and creating a new object:
      import * as productModule from './modules/products.mjs';
    • Importing default as well as named exports:
      import defaultVal,* from './modules/hybrid.mjs';

    Cyclic Dependencies in ES6: ES6 provides strong support for handling cyclic dependencies. Cyclic dependencies occur when in the chain of dependencies some modules import one of its successor modules.

    • Example: Let U, V, X… are different modules and the chain of dependencies is U->V->X-> . . .->U-> . . . then there is a circular dependency involving U.
      CommonJS and other libraries provide some level of support for cyclic dependencies but face a problem with importing and using named exports from a cyclic dependent module.
      ES6 tackles this problem by sharing the bindings to the values instead of the values itself, in the exports. And, once the cyclic dependent module is parsed the binding is allocated a suitable value.

      Program:

      // producer.mjs
      import {consumeInc} from 'consumer.mjs';
      var countP=0;
      export function produceInc()
      {
              countP++;
      }
      
      // consumer.mjs
      import {produceInc} from 'producer.mjs';
      var countC=0;
      export function consumeInc()
      {
              countC++;
      }
      

    Modules in browsers: Modules can be included in the browser JavaScript by setting the type attribute for the script tag as module. The modules loaded from an external source using src attribute are deferred by default i.e. they are loaded in parallel with HTML. Each module is executed only the first time when it is loaded.

    <script type=”module” src=”product.mjs”></script>

    Note:

    • Modules imported in JavaScript are automatically in strict mode. You can read more about strict mode here.
    • JavaScript also allows dynamic loading of modules using the construct import().


    My Personal Notes arrow_drop_up

    Check out this Author's contributed articles.

    If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

    Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.