Learn the key differences between .js and .mjs files in Node.js and how they impact module resolution and code execution.
JavaScript initially lacked a formal module system, leading developers to use various workarounds. Node.js introduced CommonJS modules using the .cjs extension, while ECMAScript, the language standard, later established its own module system with the .mjs extension. This article clarifies the differences between .js, .mjs, and .cjs files in JavaScript, explaining their historical context, syntax, and how they are treated in Node.js and browsers. It also discusses the reasons behind the confusion surrounding these extensions and provides insights into when to use each one.
JavaScript has seen the rise of different module systems, leading to different file extensions like .js, .mjs, and .cjs. Here's a breakdown:
1. The Era Before Modules:
.js files.2. CommonJS (.cjs): The Node.js Way
.cjs files explicitly signal that they use CommonJS modules.// module1.cjs
module.exports = {
sayHello: function() {
console.log("Hello from module1!");
}
};
// app.cjs
const module1 = require('./module1.cjs');
module1.sayHello(); 3. ECMAScript Modules (.mjs): The Standard
.mjs files clearly indicate the use of ECMAScript modules.// module2.mjs
export function sayHi() {
console.log("Hi from module2!");
}
// app.mjs
import { sayHi } from './module2.mjs';
sayHi();4. The Role of .js
.js was the default for all JavaScript files..js files based on your project's configuration:
"type": "module" is set in your package.json, .js files are treated as ECMAScript modules.<script> tag's type="module" attribute.Why Use .mjs?
.mjs removes ambiguity, making it instantly clear that a file uses ECMAScript modules..mjs files.Why the Confusion?
.js, can lead to confusion.In Summary:
.cjs: CommonJS modules (primarily Node.js)..mjs: ECMAScript modules (the standard, supported in modern environments)..js: Can be either CommonJS or ESM in Node.js, depending on configuration. In browsers, the <script> tag's type attribute is more relevant.While .mjs promotes clarity, the best practice for your project depends on your environment, dependencies, and whether you prioritize explicitness or maintaining compatibility.
This code provides examples of using both CommonJS and ECMAScript modules in a JavaScript project. It showcases how to export and import functions using module.exports and require for CommonJS, and export and import for ECMAScript modules. The project is structured with separate files for each module system and a package.json file that defines the entry points and module type for Node.js. The code includes examples of running both CommonJS and ECMAScript modules using npm scripts.
This example demonstrates the different module systems in JavaScript.
Project Structure:
module-example/
โโโ module1.cjs
โโโ module2.mjs
โโโ app.cjs
โโโ app.mjs
โโโ package.json
1. CommonJS (module1.cjs, app.cjs):
// module1.cjs
module.exports = {
sayHello: function() {
console.log("Hello from module1.cjs!");
}
};// app.cjs
const module1 = require('./module1.cjs');
module1.sayHello(); // Output: Hello from module1.cjs!2. ECMAScript Modules (module2.mjs, app.mjs):
// module2.mjs
export function sayHi() {
console.log("Hi from module2.mjs!");
}// app.mjs
import { sayHi } from './module2.mjs';
sayHi(); // Output: Hi from module2.mjs!3. package.json (for Node.js):
{
"name": "module-example",
"version": "1.0.0",
"description": "Example of different JavaScript module systems",
"main": "app.cjs",
"type": "module", // This line makes .js files ESM by default
"scripts": {
"start": "node app.cjs",
"start-esm": "node app.mjs"
}
}Explanation:
module.exports exports functionality, and require imports it.export keywords export functionality, and import keywords import it."type": "module" signifies that .js files in this project are treated as ECMAScript modules.npm start for CommonJS and npm run start-esm for ESM.Important Notes:
<script type="module"> tag for ESM.General:
.mjs offers clarity, using it might require adjustments in your build process or configuration, especially if you rely on tools that are not fully ESM-aware.CommonJS:
ECMAScript Modules:
Choosing a Module System:
<script type="module"> tag is the standard approach for working with modules.Beyond File Extensions:
Future:
This table summarizes the different JavaScript module file extensions and their uses:
| File Extension | Module System | Description | Used In |
|---|---|---|---|
.js |
None (Historically) | Original extension for all JavaScript files, before modules. | Everywhere |
.js |
CommonJS or ESM | Can be either module system in Node.js, depending on package.json configuration. |
Node.js |
.js |
N/A | Module type determined by <script type="module"> in browsers. |
Browsers |
.cjs |
CommonJS | Explicitly indicates a CommonJS module. | Node.js |
.mjs |
ECMAScript Modules (ESM) | Explicitly indicates an ECMAScript module. | Node.js, Modern Browsers |
Key Takeaways:
.cjs and .mjs offer clarity by explicitly signaling the module system used..js remains flexible but can lead to confusion due to its context-dependent interpretation in Node.js.The evolution of JavaScript modules brought both progress and confusion. While the initial lack of a module system led to workarounds, Node.js introduced CommonJS (.cjs) and later, ECMAScript standardized modules (.mjs). This dual system, along with the flexible role of .js, often causes uncertainty. Choosing between .cjs and .mjs depends on your project's environment and priorities. While .mjs offers clarity and aligns with modern practices, .cjs remains relevant in Node.js. Ultimately, understanding these module systems is crucial for navigating the JavaScript landscape. As the language continues to evolve, embracing the standardized module system will lead to more maintainable and scalable JavaScript applications.
Difference between .js and .mjs Extensions | by Mohit Gadhavi ... | Introduction: JavaScript has evolved significantly over the years, and with the introduction of different module systems, developers nowโฆ
How to Differentiate Between Js and Mjs Files in Javascript | A basic guide to distinguish between .js and .mjs files in the context of Javascript.
.js, .cjs and .mjs defference - DEV Community | CJS, MJS, and .JS are file extensions used to denote different types of JavaScript files. Here's the...
The Difference Between MJS, CJS, and JS Files in Node.js | Coding ... | ๐ Here are some quick basics about the difference between .mjs, .cjs, and .js file extensions in Node.js.
MJS - Node.js ES Module Javascript File | Learn about what is a MJS file and APIs that can create and open MJS file.
From CommonJS to ES Modules: How to modernize your Node.js app | Modernize your Node.js project step by step and take advantage of ES ModulesโโโThe module system of the future.