Repository navigation
Conversation
Modules with no file on disk need a graph path that can't be mistaken for a real one. This reserves `virtual:<absolute path>` for them (#2036 lets resolvers produce such modules), and updates the places where a module path leaves Metro to handle it. A module path becomes user-visible in development module names, HMR source URLs, server-URL source paths and async bundle paths. Each derives a name from the path with `path` functions, which give machine-dependent results for a path that isn't absolute. They now derive it from a virtual module's virtual path, using the helpers in `lib/modulePath`. Dev names use `virtual:<relative path>`, and URLs are the ones a file at the virtual path would have, plus a `virtual=true` search parameter. `getAllFiles` leaves virtual modules out, since they have no file. The server can't serve a virtual module by URL yet, and the path in its URL may be a real file's. So bundle and map requests with the parameter fail, and source requests with it are passed on rather than served from disk. Nothing produces a `virtual:` path until #2036, so existing bundles are unchanged. Changelog: Internal Test plan: New unit tests for the helpers, plus HMR, dev name, async path, `getAllFiles` and url-server source map cases for a virtual module, and for the server's handling of virtual module URLs. In particular, a virtual module at the same path as a real file gets distinct HMR URLs and source paths, and a request for its source isn't served from that file.
|
How far are we from migrating to |
I don't have any short term plans, but I think there'd be value in Metro moving to project-relative paths represented as URLs (giving us schemes, query parameters, uniform posix, portability), instead of absolute paths everywhere, and it'd follow from that. I haven't gone with that in this PR because Changing absolute paths to URLs would be a pretty significant breaking API change though unfortunately - these paths leak out everywhere, which is what made even this change tricky. |
|
Are these urls exposed to any plausible use outside of Metro? If so, adding "virtual:" is obviously a breaking change as well. |
Currently all modules in a
Graphare keyed by a module's absolute real path on disk, with the exception of context modules (our only "virtual" module at present), which use a distinguishing?ctx=...suffix and some bespoke wiring.The
pathis therefore the module's build-time identifier. We use it as keys in change sets in the delta calculator and HMR, and as the only input to module ID factories (serializer.createModuleIdFactory). So we need a way to guarantee virtual and real paths do not clash.This reserves
virtual:<absolute path>as that identifier, which maps to?virtual=truefor URLs referring to modules.Exposure
A module path becomes user-visible in development module names, HMR source URLs, server-URL source paths and async bundle paths. Dev names (for visual inspection of the bundle) use
virtual:<relative path>, and URLs are the ones a file at the virtual path would have, plus avirtual=truequery parameter.getAllFilesleaves virtual modules out, since they have no file.The server can't serve a virtual module by URL yet, and the path in its URL may be a real file's. So bundle and map requests with the parameter fail, and source requests with it are passed on rather than served from disk.
Nothing produces a
virtual:path until #2036, so existing bundles are unchanged.Design
Why
virtual:for file paths/foo.js?virtualis a valid file name in posix)\0prefix, which has all of the same tradeoffs.)virtual:///…, mirroringfile:///…, if module identities ever become URLs (which I'd like!)Why a namespace rather than a
virtualflagdeletedlists and inverse dependencies only ever see the path stringWhy
?virtual=truefor URLs[metro-project],[metro-watchFolders]/N, server-root-relative) without stacking routesvirtual:<path>Tradeoffs
node:pathAPI uses egpath.resolveinterpret thevirtual:/absolute/pathas a relative path from the cwd (this is also true of\0prefix, or any prefix).\0prefix or Metro's current?ctx=- but both can be aligned.Changelog: Internal
Test plan
New unit tests for the helpers, plus HMR, dev name, async path,
getAllFilesand url-server source map cases for a virtual module, and for the server's handling of virtual module URLs.In particular, a virtual module at the same path as a real file gets distinct HMR URLs and source paths, and a request for its source isn't served from that file.