Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What is commonjs2 ? #1114

Closed
Sinewyk opened this issue May 25, 2015 · 9 comments
Closed

What is commonjs2 ? #1114

Sinewyk opened this issue May 25, 2015 · 9 comments
Labels

Comments

@Sinewyk
Copy link

Sinewyk commented May 25, 2015

Sorry if that's obvious but it's been eating me for multiple days and even greping commonjs2 through this repository I couldn't find any obvious information.
My google-fu on commonjs2 led me back to #864 ... which was not helpful.

Anyone could explicitely inform me what is commonjs2, the differences with commonjs, and what is the relation with webpack ?

Thanks ...

@sokra
Copy link
Member

sokra commented May 26, 2015

CommonJs spec defines only exports. But module.exports is used by node.js and many other CommonJs implementations.

commonjs mean pure CommonJs
commonjs2 also includes the module.exports stuff.

@Sinewyk
Copy link
Author

Sinewyk commented May 26, 2015

So ... the replacement of module.exports

module.exports = function(){};

instead of simply adding stuff to the exports object

exports.a = 'a';
exports.b = 'b;'

is not in the "initial" commonjs spec ? nodejs started it and everybody followed ?

@bebraw
Copy link
Contributor

bebraw commented Nov 14, 2015

@Sinewyk Yeah, pretty much. See https://nodejs.org/docs/latest/api/modules.html for reference.

@vamsiampolu
Copy link

Are there other commonjs implementations that do not use module.exports which need to be supported by webpack? Now that I understand what the two options commonjs and commonjs2 are, I would like to understand if there is a practical use case for commonjs.

@njleonzhang
Copy link

njleonzhang commented Feb 11, 2019

As described in the document, commonjs belongs to Expose Via Object Assignment, commonjs2 belongs to Module Definition Systems.

Although the output of this two build(exports['MyLibrary'] = _entry_return_; and module.exports = _entry_return_;) is so similar, it seems Webpack treat them differently in importing. For example,

I have a simple module:

// const.js
export let name = 'leon'
export default function print() { console.log('print: ' + name) }

I build this module as commonjs and commonjs2.

Then, in another project, I try to import both modules, then I found Webpack can only handle commonjs2 correctly.

import Const1, { name as name1 } from '../output/dist/index.cmd.js'
import Const4, { name as name4 } from '../output/dist/index.cmd2.js'

console.log(Const1, name1)
/*
  Const1 is {
    MyLibrary: {
        default: print(){...},
        name: 'leon'
    }
  }

  name1 is undefined
*/

console.log(Const4, name4)  // Const4 is print function, name4 is 'leon'

So it seems we should build the module as commonjs2 instead of commonjs, if we want to exports the moudle. This is why commonjs2 belongs to Module Definition Systems? 😂

@slavafomin
Copy link

I'm also curious. As @vamsiampolu asked, is there a real use case for commonjs export variant? Is it actually publicly used in practice?

@xgqfrms-GitHub
Copy link

xgqfrms-GitHub commented Dec 6, 2019

react & react-dom

also using commonjs2 module

image

image

@kwasimensah
Copy link

Note, if you you use an external that starts with "@" and you're webpacking for the server you need to use commonjs2 per https://stackoverflow.com/questions/58105364/add-dependency-to-externals-with-in-the-library-name

To make this googleable:
from Terser Unexpected character '@'

@dosentmatter
Copy link

dosentmatter commented Sep 30, 2021

Here are the commonjs module specs if anyone is interested. 1.1.1 is the latest spec.

I think the relevant parts are:

Require

  1. require is a Function
    1. The "require" function accepts a module identifier.
    2. "require" returns the exported API of the foreign module.

Module Context

  1. In a module, there is a free variable "require", which conforms to the above definition.
  2. In a module, there is a free variable called "exports", that is an object that the module may add its API to as it executes.
    1. modules must use the "exports" object as the only means of exporting.

Unspecified

This specification leaves the following important points of interoperability unspecified:

  1. Whether modules are stored with a database, file system, or factory functions, or are interchangeable with link libraries.

So in webpack's commonjs implementation, your module (the webpack entry point) and the dependent module both have require and exports available and satisfy the above requirements. Even if they are shared at the same scope and not scoped to a file like in Node.js, the spec says where the modules are stored are unspecified.


For practicality, I don't know if anyone actually uses this out in the wild. But you could use this in an old browser with no module system. If you load the bundle with a <script> tag, the exports are available globally. Then you can define a custom require function:

function require(moduleId) {
  return exports[moduleId];
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

9 participants