Skip to content

Commit

Permalink
Merge pull request #13 from gadget-inc/file-alias-changing-resolve-pa…
Browse files Browse the repository at this point in the history
…ckage-2

Dodge node's require cache
  • Loading branch information
airhorns authored Sep 26, 2023
2 parents 3745fe2 + 2b47171 commit 638a406
Show file tree
Hide file tree
Showing 18 changed files with 486 additions and 67 deletions.
8 changes: 8 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,21 @@
"@gadgetinc/prettier-config": "^0.4.0",
"@swc/core": "^1.3.85",
"@swc/jest": "^0.2.29",
"@types/fs-extra": "^11.0.2",
"@types/jest": "^29.5.4",
"@types/node": "^18.15.3",
"eslint": "^7.32.0",
"execa": "^5.1.1",
"fs-extra": "^11.1.1",
"jest": "^29.7.0",
"linked_module": "link:./spec/fixtures/linked_module",
"lodash": "*",
"npm": "^10.1.0",
"prettier": "^2.8.8",
"typescript": "^5.2.2"
},
"dependencies": {
"enhanced-resolve": "^5.15.0",
"is-builtin-module": "^3.2.1"
}
}
156 changes: 155 additions & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

115 changes: 115 additions & 0 deletions spec/behaviour-matching.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import execa from "execa";
import fs from "fs-extra";
import os from "os";
import path from "path";
import requirefire from "../src";

describe("requirefire vs require behaviour matching", () => {
describe.each([
["require", require],
["requirefire", requirefire()],
])("%s", (name, _require) => {
test("should require modules", () => {
const a = _require("./fixtures/mod_a");
const b = _require("./fixtures/mod_b");
expect(a.name).toEqual("a");
expect(b.name).toEqual("b");
});

test("the same instance return cached versions of the same module when required twice", () => {
const one = _require("./fixtures/mod_a");
const two = _require("./fixtures/mod_a");
expect(one).toBe(two);
});

test("transitive requires are required through requirefire", () => {
jest.isolateModules(() => {
const outer = _require("./fixtures/outer_transitive");
const inner = _require("./fixtures/inner_transitive");
expect(outer.inner.random).toEqual(inner.random);
});
});

test("transitive requires have require extensions and resolve", () => {
const outer = _require("./fixtures/outer_transitive");
expect(outer.inner.requireKeys).toContain("cache");
expect(outer.inner.requireKeys).toContain("extensions");
expect(outer.inner.requireKeys).toContain("resolve");
});

test("transitive requires can resolve correctly", () => {
const outer = _require("./fixtures/outer_transitive");
expect(outer.inner.outerTransitiveResolve).toEqual(path.resolve(__dirname, "fixtures/outer_transitive.js"));
});

test("non-existent filepath modules throw a module not found error", () => {
try {
_require("/tmp/does-not-exist-requirefire-test.js");
} catch (error: any) {
expect(error).toBeTruthy();
expect(error.code).toEqual("MODULE_NOT_FOUND");
expect(error.message).toContain("Cannot find module '/tmp/does-not-exist-requirefire-test.js'");
return;
}
// unreachable
expect(false).toBe(true);
});

test("non-existent node_modules modules throw a module not found error", () => {
try {
_require("a-magical-package-that-does-everything");
} catch (error: any) {
expect(error).toBeTruthy();
expect(error.code).toEqual("MODULE_NOT_FOUND");
expect(error.message).toContain("Cannot find module 'a-magical-package-that-does-everything'");
return;
}
// unreachable
expect(false).toBe(true);
});

test("mutual (circular) requires can be required", () => {
const a = _require("./fixtures/mutual_a");
const b = _require("./fixtures/mutual_b");
expect(a.getB()).toBe(b);
expect(b.getA()).toBe(a);
});

test("modules without newlines at the end can be required", () => {
_require("./fixtures/no-newline");
});

test("aliased modules that resolve to the same module should resolve to the same module if cached", () => {
const linked = _require("./fixtures/linked_module");
linked.foo = "not foo";
const { linked: outerLinked } = _require("./fixtures/outer_linked_module");

expect(linked).toBe(outerLinked);
});

test("packages with combo esm/cjs exports configured can be requirefired", async () => {
const modDir = fs.mkdtempSync(path.join(os.tmpdir(), "requirefire-"));
await fs.rm(modDir, { recursive: true, force: true });
await fs.mkdir(modDir);

await fs.writeFile(path.join(modDir, "index.js"), `module.exports = require('dualexports')`);
await fs.writeFile(
path.join(modDir, "package.json"),
JSON.stringify({
name: "parent",
version: "0.1.0",
dependencies: {
dualexports: `file:${path.resolve(path.join(__dirname, "fixtures", "dualexports"))}`,
},
})
);

await execa("npm", ["install"], { cwd: modDir });

jest.isolateModules(() => {
const mod = _require(modDir);
expect(mod.foo).toEqual("bar");
});
});
});
});
Loading

0 comments on commit 638a406

Please sign in to comment.