Skip to content

Commit

Permalink
Turbopack: Change edge wrapper to proxy exports (vercel#72502)
Browse files Browse the repository at this point in the history
The edge runtime does `await
self._ENTRIES["middleware_..."].default.call(...)`, so instead export a
Proxy that hides that the module object itself is a promise.

Partial revert of vercel#62141
  • Loading branch information
mischnic authored Nov 20, 2024
1 parent 0344392 commit 2792c3a
Showing 1 changed file with 18 additions and 2 deletions.
20 changes: 18 additions & 2 deletions crates/next-core/src/next_edge/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,26 @@ pub async fn wrap_edge_entry(
// The wrapped module could be an async module, we handle that with the proxy
// here. The comma expression makes sure we don't call the function with the
// module as the "this" arg.
// Turn exports into functions that are also a thenable. This way you can await the whole object
// or exports (e.g. for Components) or call them directly as though they are async functions
// (e.g. edge functions/middleware, this is what the Edge Runtime does).
// Catch promise to prevent UnhandledPromiseRejectionWarning, this will be propagated through
// the awaited export(s) anyway.
let source = formatdoc!(
r#"
self._ENTRIES ||= {{}}
self._ENTRIES[{}] = import('MODULE')
self._ENTRIES ||= {{}};
const modProm = import('MODULE');
modProm.catch(() => {{}});
self._ENTRIES[{}] = new Proxy(modProm, {{
get(modProm, name) {{
if (name === "then") {{
return (res, rej) => modProm.then(res, rej);
}}
let result = (...args) => modProm.then((mod) => (0, mod[name])(...args));
result.then = (res, rej) => modProm.then((mod) => mod[name]).then(res, rej);
return result;
}},
}});
"#,
StringifyJs(&format_args!("middleware_{}", pathname))
);
Expand Down

0 comments on commit 2792c3a

Please sign in to comment.