ES Module
Tags: javascript, node, webdev, programming
Published: 2024-05-27 17:22:16

This blog is continuation with previous, [The Module System commonJS](https://dev.to/srishtikprasad/the-module-system-in-javascript-27oc) module. In this blog post I'll be covering ES Module and difference between ESM and CommonJS Module.

### ES Module System 
How to tell Node js interpreter to consider a given module as ES module rather than CommonJs module:

1. keeping file the extension as `.mjs` instead of `.js`
2. adding `"type":"module"` a field in nearest parent package.json

Named exports & imports

> Note - the ES module uses the singular word export as opposed to the plural (exports and module.exports) used by commonJS module.

In an ES module everything is private by-default and only exported entities are publicly accessible from other modules.

The export keyword can be used in front of the entities that we want to make available to the module users.

```javascript
//export a function
export function log(message){
    console.log(message);
}

//export a constant 
export const DEFAULT_LEVEL='info'

//export an object as 'LEVELS'
export const LEVELS={
error:0,
debug:1,
warn:2,
data:3,
info:4
}

//export class as logger

export class logger{
    constructor(name){
        this.name=name;
    }

    log(message){
        console.log(`${this.name} ${message}`);
    }
}
```
If we want to import entities from a module we can use the import keyword

```javascript
import * as loggerModule from './logger.js'
console.log(loggerModule)
```

> PS: We can use ES module syntax (i.e., import and export statements) in Node.js with files that have a `.js` extension, but you need to make sure Node.js is configured to support ES modules. 

In ES module , it is important to specify extension of imported modules unlike CommonJS module.

If we are using a large module,most often we don't want to import all of its functionality,but only one or few entities.

```javascript
import {log} from './logger.js'
```
If we want to import more than one entity, this is how we would do that:

```javascript
import {log,logger} from './logger.js'
console.log('hello world')
```

**gives error** :
SyntaxError: Identifier 'log' has already been declared
if this type of import statement, the entities imported into the current scope, so there is a risk of a name clash.
We can tackle in this way

```javascript
import {log as log2} from './logger.js'
```
here we are changing the original name and then using this in module.

### Named Export
Named exports allow you to export multiple values from a module. Each value is exported with a specific name, and these names must be used when importing.

```javascript
export const greeting = "Hello, World!";
export function greet(name) {
    return `${greeting}, ${name}`;
}
export const farewell = "Goodbye!";
```
Import specific named exports from the module

```javascript
import { greet, farewell } from './myModule.js';
```
**Key Points**
- Multiple exports can be defined.
- Import statements must use the exact names of the exported values.
- Named exports can be imported selectively.

## Default Exports
Default exports are used to export a single primary value or functionality from a module. This value is considered the default export and does not need to be imported with a specific name.

```javascript
// Define a function
function greet(name) {
    return `Hello, ${name}`;
}

// Export the function as the default export
export default greet;
```
Import the default export from the module

```javascript
import greet from './myDefaultModule.js';
```
**Key Points**:
- Only one default export is allowed per module.
- The imported name can be chosen freely by the importer.
- Simplifies importing when the module has a single primary export.

## Mixed export
A module can have both named exports and a default export.

```javascript
// Define variables and functions
const greeting = "Hello, World!";
function greet(name) {
    return `${greeting}, ${name}`;
}
const farewell = "Goodbye!";

// Export named and default exports
export { greeting, farewell };
export default greet;
```
Import the default export and named exports

```javascript
import greet, { greeting, farewell } from './myCombinedModule.js';
```

> Although, I have explained various methods to import & export in order to explain various way but a good practice is exporting a single object that encapsulates all exports, it improve maintainability and readability. This method allows developers to see all available exports in one place, reducing the risk of incorrect usage and making the module's API more predictable.

## ES Module & commonJS diffrence

#### ESM runs in strict mode 
- ES Module uses strict mode implicitly in strict mode, meaning we don't have to explicitly add the `"use strict"` statement at beginning of every file. So, we have only two options either strict mode or non-strict mode.
But using strict mode is definitely safer execution as it doesn't allow developer to use undeclared variable.

There are yet many things to learn application of "use strict", will cover in separate blog.

That's it for now! Thanks for reading till here. Hope you enjoy learning this and cleared some common doubts.
Let me know in comment , what did you liked in this blog any suggestion is welcome.
If you have any query don't hesitate to ask me in comments, I'll try my best to answer to the best of my knowledge ❤️.