punkish
punkish

Reputation: 15188

how to create a JS module that will work both as an ES and a CommonJS module

Update: more details to explain the problem clearly

I created an ES module (that works fine) and looks like so

//********** package.json ********
…
"type": "module",
…
//********************************


//********** index.js ************
import * as fs from 'fs';
…
class Foo { … }
…

export { Foo };
//********************************


//********** test.js *************
import { Foo } from './index.js';
…
//********************************

I want to convert the above so it can be used either of the following ways

// ES module
import { Foo } from 'myModule';

// CommonJS module
const Foo = require('myModule');

I can't figure out how to do that?

Update2: based on a similar question, I changed the code like so

//********** package.json ********
…
"type": "module",
…
//********************************


//********** index.js ************
import * as fs from 'fs';
…
class Foo { … }
…

// export { Foo };
module.exports = Foo;
//********************************


//********** test.js *************
// import { Foo } from './index.js';
import * as Foo from '../index.js';
…
//********************************

Now I get the following error

file:///Users/punkish/Projects/foo/index.js:138
module.exports = Foo;
^

ReferenceError: module is not defined in ES module scope
This file is being treated as an ES module because it has a '.js' file extension and '/Users/punkish/Projects/foo/package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.

Upvotes: 1

Views: 2633

Answers (2)

punkish
punkish

Reputation: 15188

if I want to make a module in ES6 syntax I can do the following

//********** package.json ********
…
"type": "module",
…
//********************************


//********** index.js ************
import * as fs from 'fs';
…
class Foo { … }
…

export { Foo };
//********************************

The above can be used in another ES6 script like so

//********** test.js *************
import { Foo } from './index.js';
…
//********************************

and in a CommonJS script like so

//********** test.js *************
const foo = async () => {
    const { Foo } = await import('../foo/index.js');

    …
}

foo();
//********************************

or like so (note the .mjs extension instead of the regular .js)

//********** test.mjs *************
import { Foo } from '../foo/index.js';
…
//********************************

Upvotes: 0

KeithRyanOrourke
KeithRyanOrourke

Reputation: 36

module.exports will work with import or require statements. I believe the issue that you are having may be that you are using destructuring in your ES module import statement but you are not exporting an object from your module.exports statement, at least from what I can see in your code. In other words,

module.exports = foo;

actually translate to something more like

export default foo;

as opposed to

export {foo};

Upvotes: 1

Related Questions