What is the difference betwen .mjs vs .cjs vs .js (Are these used in JavaScript or in node?)

Hello, can someone explain what is the difference between the file extensions used in node/js, .mjs, .cjs and .js please. I always sticked to .js so is there any use case of the other file extensions? I know that .mjs stands for module javascript or something like that, so naming a file as .js means we don't necessarily need to modify our package.json to include type as module ? What about .cjs please, I just know it stands for common javascript. Do the import and export statement differs between these extensions? Why do we have 3 type of extensions? Does the compiler or interpreter or whatever run the code interpret the scripts differently based on the extensions?
10 Replies
13eck
13eck2w ago
* .js is a vanilla JS file. Nothing special * .mjs is a JS module file * .cjs is specific to Node.js and uses the outdated CommonJS require syntax What does this mean? Well, due to backwards compatibility requirements all .js files are expected to be JavaScript files, not modules and not commonjs modules. That means you need to tell the browser that you're importing a module (<script type="module">) or Node js that you're using module type importing (type: module). If you use .mjs the broser/Node knows it's a module and will do all the module-type stuff for you. Also, JS modules are automatically run in strict mode so you don't have to type "use strict"; at the top of all JS files you write.
Do the import and export statement differs between these extensions?
Yes, modules use the import and export syntax. JS files rely on you loading each JS file in the correct order in the browser (using script tags). CJS uses module.exports and require to import/export modules.
Why do we have 3 type of extensions?
Because of progress. When JS first came about there wasn't a need for modules b/c the scripts were tiny and simple. But as JS grew there needed to be a way to do. There was no standard way to import/export code from one file to another. In 2009 Nodejs needed a way to do this, so they made CJS. Fast forward 6 years and ES2015 came out with the ESM standard. And that's what every JS runtime uses now, even if (like Nodejs) they also allow for non-ESM systems. Remember that the promise of web tech is backward compatibility. Something written in 1998 needs to run now just like it did back then. So you can't just remove parts of the JS, that would literally break the web! Instead, we have non-versioned ways of doing things.
Does the compiler or interpreter or whatever run the code interpret the scripts differently based on the extensions?
Yes. See also: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules
Faker
FakerOP2w ago
Yep I see, it's lot clearer now, thanks ! One question though hmm I don't think I have use import statement or .mjs file extension for JavaScript yet, like scripts that browser run. I did it on node though, I should try on the browser but say I have script 1 and script 2. Basically say script 2 is a module we want to import. We must explicitly use .mjs for the browser? (Like in node, the type: module means the JS are interpreted as a module) say script 2 was imported, should we have a script tag for it as well in our HTML?
13eck
13eck2w ago
either script2.mjs or <script type="module" src="script2.js"> No, that's what modules are made to prevent
Faker
FakerOP2w ago
when we say something is a module, like <script type="module" src="script2.js">, what that mean is: Treat this as a module (a module is just a piece of code that can be imported/export so that we don't have to repeat ourself again an again right?), so we can import things in it and export things from it?
13eck
13eck2w ago
Yes
Ganesh
Ganesh2w ago
Note that type field of package json isn't mandatory for node. https://nodejs.org/api/packages.html#introduction_1
No description
Ganesh
Ganesh2w ago
Though it will throw a warning in console if you don't specify type and try to run js file containing import export syntax
Faker
FakerOP2w ago
one thing is confusing me (it's more about syntax really but that's annoying me :c), say I have 2 scripts, script1.js and script2.js. My question is: script2.js is a module, I have written a function that we are going to import and call in script1.js. My question is in the script tag in our index.html, should we mark module as type? If yes, why pls. The thing is, for script1 why is it called a "module"? I mean normally, we don't run a module, we call it, no?
Ganesh
Ganesh2w ago
Even if script1 is using only import it's still a module. Modules is just a term for splitting code across multiple files. Your script1 falls into this too since it also just another file that contains part of the larger code Also I don't understand what you mean by run vs call a module
13eck
13eck2w ago
"Module" means it can import and export code for other scripts to use. It's modular code. You need to do something to tell the browser that you're using modular script and not a non-modular script—either using the .mjs extension or type="module" for the script tag.
An error will be thrown if your <script> element doesn't have the type="module" attribute and attempts to import other modules.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules#applying_the_module_to_your_html

Did you find this page helpful?