How to use ES6 modules with commonjs
Asked Answered
B

2

2

Going round in circles here, I'm using a module called get-folder-size https://www.npmjs.com/package/get-folder-size

This only works, it seems, inside an ES6 module. So I've found out how to do this, and created one. Now I need to import that into my commonjs app (node v14).

const mymod = require('mymod.js') now won't work because I can't require it

import mymod from 'mymod.js' won't work. Cannot use import outside a module

change to mymod.mjs doesn't help

add {"type": "module"} to package.json at my Node app's entry point as suggested by google, and now it's erroring about loads of stuff that it doesn't like.

So I started off with

index.js

const mymod = require('./mymod.js');

mymod.js

const getFolderSize = (await import('get-folder-size')).default;
const mymod = async (org) => {
    let size = await getFolderSize.loose('./');
    return size;
};
module.exports = { mymod };

and I've ended up (a dozen iterations later), with a still not working:

index.js

import mymod from './mymod.mjs';

mymod.mjs

import getFolderSize from 'get-folder-size';
const mymod = async (org) => {
    let size = await getFolderSize.loose('./');
    return size;
};
export default mymod;

I think that explains it at least.. it's late, and I don't really get what's going on - this used to all work so beautifully! Worse, everything that I can find to try and help solve this seems to be related to packaging front end apps :/

Brooklyn answered 6/7, 2021 at 21:51 Comment(0)
A
2

You can use an intermediary function to do all the process:


mid.js file:

async function loadModule(name) {
    const module = await import(name);
    return module.default;
}

module.exports = {
    loadModule
};

sample.js file:

const mid = require('./mid');

mid.loadModule('get-folder-size')
    .then(gfs => {
        gfs.loose('/Users/oscar.granada/development/personal/lit/tmp')
            .then(size => {
                console.log(size);
            });
    });
Aeroembolism answered 6/7, 2021 at 22:37 Comment(2)
I think I've following... just trying to work out how to export that as a usable function! Like, without importing the gfs module everytime I use it...Brooklyn
Maybe you can use a memoization pattern to cache the module, but internally the dependency engine does that.Aeroembolism
C
0

Just replace

const myModule = require('my-module')

by

let myModule;
(async () => {
  myModule = await import('my-module')
})()

Explanation

CommonJS require is always synchronous whereas import in Node is asynchronous and returns a Promise. You can hence use the await to wait for the promise to resolve. But you can only use await inside async functions, hence you create an Immediately Invoked Async Function Expression that waits for the module to load before doing anything else, thus having exactly the same behaviour as CommonJS require.

Beware that you have to use import(), that is, with brackets, to be able to import ES6 modules within a CommonJS project.

Concoff answered 12/6 at 16:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.