Skip to content

Latest commit

 

History

History
240 lines (161 loc) · 6.11 KB

File metadata and controls

240 lines (161 loc) · 6.11 KB

I’ll explain everything about “.mjs” files — what they are, why they exist, how to use them in Express.js, and how they differ from .js.


🧩 What is .mjs?

.mjs stands for “Module JavaScript”. It’s a file extension used to tell Node.js that the file uses ES Modules (ECMAScript Modules) syntax — i.e. import and export.

Before .mjs, Node.js traditionally used CommonJS (require, module.exports) syntax.


🆚 Difference Between .js and .mjs

Feature .js (Default in Node.js) .mjs
Module System CommonJS (CJS) ES Modules (ESM)
Import Syntax const express = require('express'); import express from 'express';
Export Syntax module.exports = app; export default app;
Node.js Recognition Default format for CJS Explicitly tells Node to use ESM
Interoperability Older system (used before ES6) New standard (modern JS, browser-compatible)

🧠 Why .mjs Exists

When Node.js first introduced ES Modules (ESM), .js files were already being used for CommonJS syntax. So to avoid confusion, Node needed a way to know which system a file uses.

Hence:

  • .js → interpreted as CommonJS (unless specified otherwise)
  • .mjs → interpreted as ES Module automatically

🧾 Example: Express.js with .mjs

Let’s say you want to write an Express.js app using ES Modules (modern JS syntax).

🔹 Step 1: Create package.json

npm init -y

This creates a basic package.json file.

Now you have two options to use ES Modules:


🧩 Option 1: Use .mjs file extension

📂 File structure:

project/
│
├── app.mjs
└── package.json

🧠 app.mjs content:

import express from 'express';

const app = express();
const port = 3000;

// Middleware
app.use(express.json());

// Route
app.get('/', (req, res) => {
  res.send('Hello, Express using ES Modules (.mjs)');
});

// Start server
app.listen(port, () => {
  console.log(`Server running at http://localhost:${port}`);
});

🏃 Run it:

node app.mjs

✅ Works because .mjs tells Node it’s using ES Module syntax.


🧩 Option 2: Use .js but enable "type": "module"

If you don’t want .mjs filenames, you can add this line to your package.json:

{
  "type": "module"
}

Now .js files are automatically treated as ES Modules.

Example: app.js

import express from 'express';

const app = express();
const port = 3000;

app.get('/', (req, res) => {
  res.send('Hello, Express using ES Modules (.js with type:module)');
});

app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});

Run it:

node app.js

✅ Works exactly like .mjs, but now with .js.


⚙️ Key ES Module Features (Enabled by .mjs)

  1. import and export — native JS syntax

    import express from 'express';
    export const router = express.Router();
  2. Top-level await — directly use await outside functions

    const data = await fetch('https://api.example.com');
  3. No require() or module.exports — replaced by ESM syntax

  4. File path resolution rules are stricter:

    • Must include file extensions in imports (e.g., import x from './file.js')
    • Cannot use bare require() for JSON or built-in modules the same way as CJS

💡 When to Use .mjs

Use .mjs when:

  • You mix both CommonJS and ES Modules in the same project.
  • You don’t want to modify the entire project’s package.json to "type": "module".
  • You want to clearly separate modern ESM files from legacy CJS files.

⚡ Real-world Example: Express + MongoDB (.mjs)

npm install express mongoose

📂 File structure:

project/
│
├── server.mjs
└── package.json

server.mjs:

import express from 'express';
import mongoose from 'mongoose';

const app = express();
const port = 3000;

// Connect to MongoDB
await mongoose.connect('mongodb://127.0.0.1:27017/testDB');
console.log('✅ Connected to MongoDB');

// Middleware
app.use(express.json());

// Route
app.get('/', (req, res) => {
  res.send('Hello from Express + MongoDB using .mjs');
});

app.listen(port, () => {
  console.log(`🚀 Server running on http://localhost:${port}`);
});

Run:

node server.mjs

⚠️ Common Errors and Fixes

Error Cause Fix
SyntaxError: Cannot use import statement outside a module Node doesn’t know it’s ESM Use .mjs or "type": "module"
Error: Must use import to load ES Module Trying to import ESM from CommonJS Convert file to .mjs or make entire project ESM
ERR_MODULE_NOT_FOUND Missing extension Add .js to import path (e.g., import x from './file.js')

✅ Summary

Concept .mjs
Meaning Module JavaScript
Purpose Enables ES Modules in Node.js
Syntax import / export
Best For Modern Express.js, React SSR, and TypeScript backends
Alternate "type": "module" in package.json
Typical Use Express.js + MongoDB / EJS / modern APIs