Skip to content

Instantly share code, notes, and snippets.

@trentm
Created November 16, 2023 00:51
Show Gist options
  • Save trentm/aa10ec6c34a473aa64a2e717b931742c to your computer and use it in GitHub Desktop.
Save trentm/aa10ec6c34a473aa64a2e717b931742c to your computer and use it in GitHub Desktop.
diff --git a/lib/get-exports.js b/lib/get-exports.js
index 70324db..13961ab 100644
--- a/lib/get-exports.js
+++ b/lib/get-exports.js
@@ -9,18 +9,28 @@ function addDefault(arr) {
return Array.from(new Set(['default', ...arr]))
}
+const urlsBeingProcessed = new Set(); // Guard against circular imports.
+
async function getFullCjsExports(url, context, parentLoad, source) {
+ if (urlsBeingProcessed.has(url)) {
+ return [];
+ }
+ urlsBeingProcessed.add(url);
+
const ex = getCjsExports(source)
- return Array.from(new Set([
+ const full = Array.from(new Set([
...addDefault(ex.exports),
...(await Promise.all(ex.reexports.map(re => getExports(
- re.startsWith('./') || re.startsWith('../')
- ? pathToFileURL(require.resolve(fileURLToPath(new URL(re, url)))).toString()
- : pathToFileURL(require.resolve(re)).toString(),
- context,
- parentLoad
+ re.startsWith('./') || re.startsWith('../')
+ ? pathToFileURL(require.resolve(fileURLToPath(new URL(re, url)))).toString()
+ : pathToFileURL(require.resolve(re)).toString(),
+ context,
+ parentLoad
)))).flat()
]))
+
+ urlsBeingProcessed.delete(url);
+ return full
}
async function getExports (url, context, parentLoad) {
diff --git a/test/fixtures/circular-a.js b/test/fixtures/circular-a.js
new file mode 100644
index 0000000..f267ad5
--- /dev/null
+++ b/test/fixtures/circular-a.js
@@ -0,0 +1,18 @@
+// The following is generated by tslib. __exportStar is a format which cjs-module-lexer exposes as a reexport
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
+}) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+}));
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+
+
+__exportStar(require("./circular-b"), exports);
+
+exports.foo = 42;
+
diff --git a/test/fixtures/circular-b.js b/test/fixtures/circular-b.js
new file mode 100644
index 0000000..597816d
--- /dev/null
+++ b/test/fixtures/circular-b.js
@@ -0,0 +1,15 @@
+// The following is generated by tslib. __exportStar is a format which cjs-module-lexer exposes as a reexport
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
+}) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+}));
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+
+__exportStar(require("./circular-a"), exports);
+
diff --git a/test/hook/circular-imports.mjs b/test/hook/circular-imports.mjs
new file mode 100644
index 0000000..3a6a316
--- /dev/null
+++ b/test/hook/circular-imports.mjs
@@ -0,0 +1,11 @@
+import {foo} from '../fixtures/circular-b.js';
+import Hook from '../../index.js'
+import { strictEqual } from 'assert'
+
+Hook((exports, name) => {
+ if (name.match(/circular-[ab].js/)) {
+ exports.foo += 15
+ }
+})
+
+strictEqual(foo, 57);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment