feat: support bundled dev mode in ssr#21626
Conversation
|
Very excited to see the beginnings of this! |
…he runner code to minimise copypaste
…undle-mode-in-ssr
| // It should removed on rolldown side | ||
|
|
||
| // TODO: this crashes the server, not yet supported(?) | ||
| test.skip(`circular dependencies modules doesn't throw`, async () => { |
There was a problem hiding this comment.
This breaks outside of try/catch in the server entry (valueA.concat is not defined)
Not sure why it happens in a separate tick 🤔
There was a problem hiding this comment.
Not sure why it happens in a separate tick 🤔
This seems to be a bug in Rolldown. Made a test case in rolldown/rolldown#9975
|
I think |
| import kill from 'kill-port' | ||
| import { createInMemoryLogger, hmrPorts, ports, rootDir } from '~utils' | ||
|
|
||
| export const port = ports.ssr |
There was a problem hiding this comment.
We should use a unique port here ports['ssr-bundled-dev']
| if (!ssrResult) { | ||
| throw new Error(`[vite] cannot apply ssr transform to '${url}'.`) | ||
| } | ||
| result.code = ssrResult.code |
There was a problem hiding this comment.
Ah, yeah, we need triggerLazyBundling to return a source map.
| // It should removed on rolldown side | ||
|
|
||
| // TODO: this crashes the server, not yet supported(?) | ||
| test.skip(`circular dependencies modules doesn't throw`, async () => { |
There was a problem hiding this comment.
Not sure why it happens in a separate tick 🤔
This seems to be a bug in Rolldown. Made a test case in rolldown/rolldown#9975
This PR adds a failing test that covers a bug found in vitejs/vite#21626. When lazy bundling is enabled, the following bug exists: ```javascript try { await import('./foo.js'); // throws an error inside } catch (e) { // the error is not caught here and a unhandled error happens } ``` <!-- - What is this PR solving? Write a clear and concise description. - Reference the issues it solves (e.g. `fixes #123`). - What other alternatives have you explored? - Are there any parts you think require more attention from reviewers? Also, please make sure you do the following: - Read the Contributing Guidelines at https://rolldown.rs/contribution-guide/. - Check that there isn't already a PR that solves the problem the same way. If you find a duplicate, please help us review it. - Update the corresponding documentation if needed. - Include relevant tests that fail without this PR but pass with it. If the tests are not included, explain why. Thank you for contributing to Rolldown! -->
Builds on #9975 (which added the failing test). Fixes the bug found in vitejs/vite#21626. ## Problem With lazy compilation enabled, an error thrown while a lazily-imported module *initializes* never reached the consumer: ```js try { await import('./foo.js'); // throws during init } catch (e) { // never runs — instead the error escaped as an unhandled rejection, // and `await import(...)` resolved as if nothing went wrong } ``` The lazy proxy wraps the import in an eagerly-created `lazyExports` async IIFE. On the first compile of the lazy chunk (the on-demand `@vite/lazy` response), the real module's initializer runs synchronously inside that IIFE and throws, so `lazyExports` rejects before any consumer can attach a handler. The rejection went unhandled, and the proxy then returned the module namespace as if the import had succeeded. ## Fix - **`proxy-module-template.js`**: after loading the chunk, `await` the real module's own `rolldown:exports` promise instead of just handing back the namespace from `loadExports`. An error during init now rejects `lazyExports` too, so it surfaces at the consumer's `await import(...)` (catchable) rather than escaping as an unhandled rejection. ## Tests - Rewrote the `lazy-init-error` spec to assert both cases against the same module: with `try/catch` the error is caught at `await import(...)`; with no handler it surfaces as exactly one `unhandledrejection`.
| } | ||
|
|
||
| function resolveBundledEntryFilename( | ||
| environment: BundledDev, |
There was a problem hiding this comment.
Not environment anymore
TODO
wsinjection on rolldown side https://github.com/rolldown/rolldown/blob/d7f919c18980e6b4a26d06bd071d7cf14cf810a7/crates/rolldown_plugin_hmr/src/hmr_plugin.rsconst __require = createRequire()in rolldown (somewhere)wsdependency from the playgroundI am exploring how full bundle mode can be supported in SSR. At the moment the goal is to support
environments.ssr.runner.importandenvironment.fetchModule. Module graph,transformRequest,pluginContainerare out of scope of this PR, but they will be revisited later.Known quirks (to discuss)
runner.import(url)is not resolved withresolveIdlike it is done usually. Instead it accepts:rolldownOptions.input/(/entry-point.jsvs./entry-point.js)urlmust be an actual filename or a URL with the extension at the endimport.meta.url,import.meta.filenameandimport.meta.dirnamereference "would be" (or "virtual") files, these are the URLs that would exist if vite kept the bundle on the file system. Doing something likereadFileSync(import.meta.filename)will throw an error because the file does not exist on disk{ ourDir: './dist' }, the filename would be something like<root>/dist/asset/chunk-1.jsTo enable full bundle mode in SSR, add this to the config: