quibble icon indicating copy to clipboard operation
quibble copied to clipboard

exports are empty when ESM loader loads a cjs package which uses a quibbled module

Open stixx200 opened this issue 1 year ago • 0 comments

I want to fake the fs package using memfs. My production code uses fs-extra.

The require-stack looks like: app.js (ESM) -> fs-extra (CJS) -> graceful-fs (CJS) -> fs (Built-In)

Reproduction

Example:

import quibble from "quibble";
import { vol, fs as fsm } from "memfs";

vol.fromJSON({
    "foo.txt": "foo",
});

quibble("fs", { ...fsm });

const fse = (await import("fs-extra")).default;
await fse.stat("foo.txt");

In this use case, the ESM-Loader loads the fs-extra module with it's internal cjs loader. Because quibble restores the Module._cache entry, the cjs loader only returns an empty object for the exports: TypeError: fse.stat is not a function

Hint:

If I remove the line delete Module._cache[filename] (in doAndRestoreCache) my use-case works. I think the ESM Loader reads the exports from the cached value after quibble deleted it.

If I use require to load fs-extra, there is no problem:

const require = createRequire(import.meta.url);
const fse = require("fs-extra");
// ...

stixx200 avatar Apr 15 '24 13:04 stixx200