-
Notifications
You must be signed in to change notification settings - Fork 30.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unexpected early exit (code 13) when trying to import {}
from a dynamic import()
#44601
Comments
FWIW this can be simplified to: // server.js
export const BASE_URL = new URL("http://localhost:8080");
const exports = await import(new URL("./index.js", import.meta.url));
console.log(exports); // <-- we never get here
To me that seems like the expected behavior, code 13 means unfinished top-level await (see https://nodejs.org/api/process.html#exit-codes). Because |
I see your original issue. I believe the code won't works because you are trying to transit from |
Yes, if you have a cycle you shouldn't use dynamic import at the top level to load the other module. In general you can just use a top-level import and things won't deadlock: // index.js
import { BASE_URL } from "./server.js";
// ...etc // server.js
import * as path from "path";
import * as url from "url";
import * as exports from "./index.js";
// ...etc The reason static import works (and CJS equivalent for that matter) is that static import is allowed to return a namespace that isn't fully evaluated. i.e. You can get // a.js
import * as modB from "./b.js";
console.log("Executing a.js");
console.log(modB);
export const a = "a"; // b.js
import { a } from "./a.js";
console.log("Executing b.js");
console.log(modA);
export const b = "b"; And so if you run it, this happens:
Notice that Dynamic import is different from static import in that it only ever returns fully initialized modules, so it can't return early with a partially initialized module. i.e. This isn't allowed to print const modA = await import("./a.js");
console.log(modA); In principle dynamic |
Based on @aduh95 and @Jamesernator comments I agree that this looks like the correct behavior Based on that, is this issue still relevant? or should it be closed? (I don't think there's any actionable item here?) |
As explained already, top-level await on a dynamic import that involves circular dependency would lead to deadlock in the JS execution, and in Node.js since the process is only kept alive by I/O (or, active handles in the event loop), not by pending tasks, a deadlock purely on the JS side would just leave the event loop clear of any active handles, therefore Node.js would just exit without executing any code following the problematic top-level await (in browsers, where there is not a concept of "exit on completion", the deadlock would just prevent any code below the problematic top-level await from ever executing, until it's signaled to exit when you e.g. close the tab, and still won't execute those code). This is exactly why the exit code 13 was invented to warn about this case. So it's not a bug but a known limitation. |
Version
v18.9.0
Platform
Microsoft Windows NT 10.0.19044.0 x64
Subsystem
Also tested in a Linux devcontainer (Linux docker-desktop 5.10.16.3-microsoft-standard-WSL2)
What steps will reproduce the bug?
How often does it reproduce? Is there a required condition?
Always.
What is the expected behavior?
The
BASE_URL
getsconsole.log
d.What do you see instead?
Unexpected early exit (code 13) on the dynamic
import()
.No error. Also no error if wrapped in a
try...catch
.Additional information
Originating issue: TypeStrong/ts-node#1883
The text was updated successfully, but these errors were encountered: