fix(ssr): hoist export to handle cyclic import better#18983
fix(ssr): hoist export to handle cyclic import better#18983sapphi-red merged 25 commits intovitejs:mainfrom
Conversation
ff8cf4b to
3cc86da
Compare
|
/ecosystem-ci run |
commit: |
|
📝 Ran ecosystem CI on
✅ analogjs, astro, ladle, previewjs, quasar, qwik, rakkas, storybook, sveltekit, unocss, vite-environment-examples, vite-plugin-pwa, vite-plugin-react, vite-plugin-react-swc, vite-plugin-vue, vite-setup-catalogue, vitepress, vuepress |
vitest.config.ts
Outdated
| // TODO: | ||
| // importing non entry file can be broken due to cyclic import e.g. | ||
| // pnpm exec tsx packages/vite/src/node/server/index.ts | ||
| setupFiles: ['./packages/vite/src/node/index.ts'], |
There was a problem hiding this comment.
Interestingly, export hoisting can make cyclic import handling stricter as seen by:
$ pnpm test-unit packages/vite/src/node/ssr/runtime/__tests__/server-runtime.spec.ts
FAIL packages/vite/src/node/ssr/runtime/__tests__/server-runtime.spec.ts [ packages/vite/src/node/ssr/runtime/__tests__/server-runtime.spec.ts ]
ReferenceError: Cannot access 'serverConfigDefaults' before initialization
❯ Module.get [as serverConfigDefaults] packages/vite/src/node/server/index.ts:4:116but this case might be legitimate since this is the same error as tsx:
$ pnpm exec tsx packages/vite/src/node/server/index.ts
/home/hiroshi/code/others/vite/packages/vite/src/node/config.ts:648
server: serverConfigDefaults,
^
ReferenceError: Cannot access 'serverConfigDefaults' before initializationI'd imagine previously these were undefined (still wrong but no hard error) since __vite_ssr_import_x_.serverConfigDefaults getter was not defined. But now this hits uninitialized const serverConfigDefaults access due to getter.
Just temporarily, I added this silly setupFiles, so that modules will be initialized in a known safe order.
4e35256 to
2245aaa
Compare
| // it throws a same error as browser case, | ||
| // but it doesn't auto reload and it calls `hot.accept` called with `undefined` | ||
| await untilUpdated(() => el(), '') |
There was a problem hiding this comment.
It turns out the error now became same as playground/hmr but module runner doesn't auto-reload, so the existing test failed.
ReferenceError: Cannot access 'c' before initialization
I adjust this test case for now to make it pass.
|
/ecosystem-ci run |
|
📝 Ran ecosystem CI on
✅ analogjs, astro, laravel, marko, previewjs, quasar, qwik, rakkas, storybook, sveltekit, unocss, vike, vite-environment-examples, vite-plugin-pwa, vite-plugin-react, vite-plugin-react-swc, vite-plugin-vue, vite-setup-catalogue, vitepress, vuepress |
|
📝 Ran ecosystem CI on
✅ analogjs, astro, laravel, marko, previewjs, quasar, qwik, rakkas, storybook, sveltekit, unocss, vike, vite-environment-examples, vite-plugin-pwa, vite-plugin-react, vite-plugin-react-swc, vite-plugin-vue, vite-setup-catalogue, vitepress, vuepress |
|
/ecosystem-ci run |
|
📝 Ran ecosystem CI on
✅ ladle, histoire, previewjs, nuxt, analogjs, marko, qwik, react-router, storybook, vite-plugin-react, vite-environment-examples, laravel, quasar, vite-plugin-pwa, vite-plugin-react-swc, unocss, vite-setup-catalogue, vite-plugin-vue, vitepress, waku, vike, vuepress, rakkas |
|
📝 Ran ecosystem CI on
✅ histoire, quasar, react-router, vite-environment-examples, previewjs, qwik, storybook, analogjs, vike, nuxt, vite-plugin-react-swc, rakkas, unocss, vite-plugin-pwa, vite-plugin-react, vite-plugin-vue, ladle, laravel, marko, astro, waku, vite-setup-catalogue, vitepress, vuepress |
|
This looks good on Vitest side as confirmed in vitest-dev/vitest#7621 |
Aligning with vitejs/vite#18983 I manually verified the test case output matches with the ones in Vite repo. ~I add a new TODO about "export default" getter, but this difference existed already. I plan to fix this separately.~ (EDIT: It turned out Vite's transform is the wrong one vitejs/vite#19834.)
Co-authored-by: sapphi-red <[email protected]>
Description
Currently
Object.defineProperty(__vite_ssr_exports__, ...)is not hoisted and this is different from what bundlers normally do (see my notes in https://github.com/hi-ogawa/reproductions/tree/main/cyclic-import). By defining__vite_ssr_exports__property early beforeawait __vite_ssr_import__(...)calls, it fixes certain cyclic import scenarios.For
export * from "...", bundlers statically analyze the export names and hoist them too, but this is not possible for Vite SSR, so__vite_ssr_exportAll__is kept as is.One potential issue with this change is that this can technically break a "working" code with cyclic import which were previously forgiven. This was actually the case of our own unit test. See #18983 (comment) for details.
todo
setupFiles: ['./packages/vite/src/node/index.ts']trickvitest: broken source map?(the issue is on Vitest side test: debug Vite PR 18983 vitest-dev/vitest#7096)this could be a blocker. we probably need some judgement from Ari.this doesn't happen if we ensure;\nwhen hoisting, but that would entirely diminish the effort of fix(ssrTransform): preserve line offset when transforming imports #19004