Version
4.6.0
What happened?
When Angular native-federation loads a remote over http(s) in a Node SSR process,
resolve() in src/scripts/node-loader.ts does not short-circuit for absolute http(s) URLs the way load() already does.
Two related issues:
-
resolveSpecifier() only returns a URL when the specifier matches an entry
in the import map. A relative specifier that is a sibling chunk of an
already-loaded remote bundle (e.g. ./chunk-abc.js imported from
https://remote-host/remote/entry.js) is not in the import map at all, so
resolve() falls through to nextResolve(), which only understands
file:/data:/node: specifiers and throws ERR_INVALID_URL for an http(s)
URL.
-
context.parentURL can arrive as an empty string (not undefined)
inside this hook. This happens under module.register()'s worker-thread
hook execution, where the hooks thread appears to lose the parent module
context in some nested-import scenarios. When that happens,
resolveSpecifier()'s parentURL ? ... : baseURL check treats the empty
string as falsy and silently falls back to the local baseURL instead of
the remote's base => breaking both relative sibling-chunk resolution and
import-map scope matching for that remote.
Expected: resolving a remote's own chunks/shared deps by http(s) URL should
work the same way load() already fetches http(s) URLs via a short-circuit instead of being handed to Node's built-in resolver.
Steps to reproduce
- Set up a native-federation host that loads a remote exposing more than one
chunk (e.g. a lazy route), served over http/https (SSR / Node consumer,
not the browser).
- Have the remote's entry chunk import another chunk of the same remote with
a relative specifier (e.g. import('./chunk-abc.js')), which is normal
output from any bundler doing code-splitting.
- Load the remote from the Node SSR process (loader registered via
module.register(...), as this package does).
- Observe
resolve() throwing ERR_INVALID_URL for the relative specifier,
or (once that's worked around) resolving against the wrong base and 404ing,
because context.parentURL was empty on that call.
I have a fix + tests ready (branch fix/node-loader-http-resolve-and-empty-parenturl
in a fork) and will open a PR referencing this issue.
Version
4.6.0
What happened?
When Angular native-federation loads a remote over http(s) in a Node SSR process,
resolve()insrc/scripts/node-loader.tsdoes not short-circuit for absolute http(s) URLs the wayload()already does.Two related issues:
resolveSpecifier()only returns a URL when the specifier matches an entryin the import map. A relative specifier that is a sibling chunk of an
already-loaded remote bundle (e.g.
./chunk-abc.jsimported fromhttps://remote-host/remote/entry.js) is not in the import map at all, soresolve()falls through tonextResolve(), which only understandsfile:/data:/node: specifiers and throws
ERR_INVALID_URLfor an http(s)URL.
context.parentURLcan arrive as an empty string (notundefined)inside this hook. This happens under
module.register()'s worker-threadhook execution, where the hooks thread appears to lose the parent module
context in some nested-import scenarios. When that happens,
resolveSpecifier()'sparentURL ? ... : baseURLcheck treats the emptystring as falsy and silently falls back to the local
baseURLinstead ofthe remote's base => breaking both relative sibling-chunk resolution and
import-map scope matching for that remote.
Expected: resolving a remote's own chunks/shared deps by http(s) URL should
work the same way
load()already fetches http(s) URLs via a short-circuit instead of being handed to Node's built-in resolver.Steps to reproduce
chunk (e.g. a lazy route), served over http/https (SSR / Node consumer,
not the browser).
a relative specifier (e.g.
import('./chunk-abc.js')), which is normaloutput from any bundler doing code-splitting.
module.register(...), as this package does).resolve()throwingERR_INVALID_URLfor the relative specifier,or (once that's worked around) resolving against the wrong base and 404ing,
because
context.parentURLwas empty on that call.I have a fix + tests ready (branch
fix/node-loader-http-resolve-and-empty-parenturlin a fork) and will open a PR referencing this issue.