Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vite SSR Imports not loading classes correctly - constructors not loaded #14048

Open
lib-eramen opened this issue Aug 9, 2023 · 13 comments
Open
Labels
contribution welcome feat: ssr p2-nice-to-have Not breaking anything but nice to have (priority)

Comments

@lib-eramen
Copy link

Describe the bug

I'm trying to use a class in a Vite + SvelteKit project with TypeScript enabled. However, when I try to use a class and construct it in other places, while IntelliSense/LSPs don't throw any errors, when building/developing, the following error is outputted:

11:00:08 AM [vite] Error when evaluating SSR module /src/lib/core/games/chess/chess.ts:
|- TypeError: __vite_ssr_import_0__.GameMetadata is not a constructor
    at eval (/home/ramendev/projects/just-games/src/lib/core/games/chess/chess.ts:5:15)
    at async instantiateModule (file:///home/ramendev/projects/just-games/node_modules/vite/dist/node/chunks/dep-df561101.js:55974:9)

*other errors caused when importing the chess.ts file*

11:00:08 AM [vite] Error when evaluating SSR module /src/routes/+page.svelte: failed to import "/src/lib/components/games/GamesCarousel.svelte"
|- TypeError: __vite_ssr_import_0__.GameMetadata is not a constructor
    at eval (/home/ramendev/projects/just-games/src/lib/core/games/chess/chess.ts:5:15)
    at async instantiateModule (file:///home/ramendev/projects/just-games/node_modules/vite/dist/node/chunks/dep-df561101.js:55974:9)

Internal server error: __vite_ssr_import_0__.GameMetadata is not a constructor
      at eval (/home/ramendev/projects/just-games/src/lib/core/games/chess/chess.ts:5:15)
      at async instantiateModule (file:///home/ramendev/projects/just-games/node_modules/vite/dist/node/chunks/dep-df561101.js:55974:9)
TypeError: __vite_ssr_import_0__.GameMetadata is not a constructor
    at eval (/home/ramendev/projects/just-games/src/lib/core/games/chess/chess.ts:5:15)
    at async instantiateModule (file:///home/ramendev/projects/just-games/node_modules/vite/dist/node/chunks/dep-df561101.js:55974:9)

The class in question is defined as follows:
src/lib/core/games.ts

export class GameMetadata {
	name: string;
	aka: string;
	description: string;
	jpName: string;

	constructor(name: string, aka: string, description: string, jpName: string) {
		this.name = name;
		this.aka = aka;
		this.description = description;
		this.jpName = jpName;
	}

src/lib/core/games/chess/chess.ts

import { GameMetadata } from "../../game";

export const chess = new GameMetadata(
	"chess",
	'...',
	"...",
	"西洋将棋"
);

Reproduction

https://github.com/developer-ramen/just-games

Steps to reproduce

Clone the repo, followed by npm install and npm run dev

System Info

System:
    OS: Linux 5.15 Ubuntu 22.04.2 LTS 22.04.2 LTS (Jammy Jellyfish)
    CPU: (8) x64 Intel(R) Core(TM) i7-8665U CPU @ 1.90GHz
    Memory: 5.39 GB / 7.67 GB
    Container: Yes
    Shell: 5.8.1 - /usr/bin/zsh
  Binaries:
    Node: 18.17.0 - /usr/local/bin/node
    npm: 9.6.7 - /usr/local/bin/npm
  npmPackages:
    vite: ^4.4.2 => 4.4.9

Used Package Manager

npm

Logs

Logs from runnning `vite-build-debug` ```shell vite:config bundled config file loaded in 675.06ms +0ms vite:vite-plugin-svelte adding bare svelte packages to optimizeDeps.include: svelte/animate, svelte/easing, svelte/internal, svelte/motion, svelte/store, svelte/transition, svelte, svelte/internal/disclose-version +0ms vite:vite-plugin-svelte extra config for dependencies generated by vitefu { optimizeDeps: { include: [], exclude: [] }, ssr: { noExternal: [], external: [] } } +5ms vite:vite-plugin-svelte post-processed extra config for dependencies { optimizeDeps: { include: [], exclude: [] }, ssr: { noExternal: [], external: [] } } +1ms vite:vite-plugin-svelte enabling "experimental.hmrPartialAccept" in vite config +1ms vite:vite-plugin-svelte additional vite config { resolve: { dedupe: [ 'svelte/animate', 'svelte/easing', 'svelte/internal', 'svelte/motion', 'svelte/ssr', 'svelte/store', 'svelte/transition', 'svelte', 'svelte/internal/disclose-version', 'svelte-hmr/runtime/hot-api-esm.js', 'svelte-hmr/runtime/proxy-adapter-dom.js', 'svelte-hmr' ], conditions: [ 'svelte' ] }, optimizeDeps: { include: [ 'svelte/animate', 'svelte/easing', 'svelte/internal', 'svelte/motion', 'svelte/store', 'svelte/transition', 'svelte', 'svelte/internal/disclose-version' ], exclude: [ 'svelte-hmr' ] }, ssr: { external: [], noExternal: [ 'svelte', /^svelte\// ] }, experimental: { hmrPartialAccept: true } } +0ms vite:vite-plugin-svelte resolved options { hot: false, compilerOptions: { css: 'external', dev: false, hydratable: true }, extensions: [ '.svelte' ], emitCss: true, prebundleSvelteLibraries: false, configFile: false, preprocess: [ { markup: [AsyncFunction: markup], script: [AsyncFunction: script], style: [AsyncFunction: style] }, { script: [Function: script], markup: [Function: markup] } ], onwarn: undefined, root: '/home/ramendev/projects/just-games', isBuild: true, isServe: false, isDebug: true, isProduction: true, stats: VitePluginSvelteStats {} } +53ms

vite:config using resolved config: {
vite:config plugins: [
vite:config 'vite:optimized-deps-build',
vite:config 'vite:build-metadata',
vite:config 'vite:watch-package-data',
vite:config 'vite:pre-alias',
vite:config 'alias',
vite:config 'vite-plugin-svelte',
vite:config 'vite:modulepreload-polyfill',
vite:config 'vite:resolve',
vite:config 'vite:html-inline-proxy',
vite:config 'vite:css',
vite:config 'vite:esbuild',
vite:config 'vite:json',
vite:config 'vite:wasm-helper',
vite:config 'vite:worker',
vite:config 'vite:asset',
vite:config 'vite-plugin-sveltekit-setup',
vite:config 'vite-plugin-sveltekit-virtual-modules',
vite:config 'vite-plugin-sveltekit-guard',
vite:config 'vite-plugin-sveltekit-compile',
vite:config 'vite:wasm-fallback',
vite:config 'vite:define',
vite:config 'vite:css-post',
vite:config 'vite:build-html',
vite:config 'vite:worker-import-meta-url',
vite:config 'vite:asset-import-meta-url',
vite:config 'vite:force-systemjs-wrap-complete',
vite:config 'commonjs',
vite:config 'vite:data-uri',
vite:config 'vite:dynamic-import-vars',
vite:config 'vite:import-glob',
vite:config 'vite:build-import-analysis',
vite:config 'vite:esbuild-transpile',
vite:config 'vite:manifest',
vite:config 'vite:reporter',
vite:config 'vite:load-fallback'
vite:config ],
vite:config test: { include: [ 'src/**/*.{test,spec}.{js,ts}' ] },
vite:config optimizeDeps: {
vite:config disabled: false,
vite:config include: [
vite:config 'svelte/animate',
vite:config 'svelte/easing',
vite:config 'svelte/internal',
vite:config 'svelte/motion',
vite:config 'svelte/store',
vite:config 'svelte/transition',
vite:config 'svelte',
vite:config 'svelte/internal/disclose-version'
vite:config ],
vite:config exclude: [ 'svelte-hmr', '@sveltejs/kit', '$app', '$env' ],
vite:config esbuildOptions: { preserveSymlinks: false }
vite:config },
vite:config build: {
vite:config target: 'node16.14',
vite:config cssTarget: 'node16.14',
vite:config outDir: '/home/ramendev/projects/just-games/.svelte-kit/output/server',
vite:config assetsDir: 'assets',
vite:config assetsInlineLimit: 4096,
vite:config cssCodeSplit: true,
vite:config sourcemap: false,
vite:config rollupOptions: {
vite:config input: [Object],
vite:config output: [Object],
vite:config preserveEntrySignatures: 'strict'
vite:config },
vite:config minify: false,
vite:config terserOptions: {},
vite:config write: true,
vite:config emptyOutDir: null,
vite:config copyPublicDir: false,
vite:config manifest: 'vite-manifest.json',
vite:config lib: false,
vite:config ssr: true,
vite:config ssrManifest: false,
vite:config ssrEmitAssets: true,
vite:config reportCompressedSize: true,
vite:config chunkSizeWarningLimit: 500,
vite:config watch: null,
vite:config cssMinify: true,
vite:config commonjsOptions: { include: [Array], extensions: [Array] },
vite:config dynamicImportVarsOptions: { warnOnError: true, exclude: [Array] },
vite:config modulePreload: { polyfill: true }
vite:config },
vite:config resolve: {
vite:config mainFields: [ 'svelte', 'module', 'jsnext:main', 'jsnext' ],
vite:config browserField: true,
vite:config conditions: [ 'svelte' ],
vite:config extensions: [
vite:config '.mjs', '.js',
vite:config '.mts', '.ts',
vite:config '.jsx', '.tsx',
vite:config '.json'
vite:config ],
vite:config dedupe: [
vite:config 'svelte/animate',
vite:config 'svelte/easing',
vite:config 'svelte/internal',
vite:config 'svelte/motion',
vite:config 'svelte/ssr',
vite:config 'svelte/store',
vite:config 'svelte/transition',
vite:config 'svelte',
vite:config 'svelte/internal/disclose-version',
vite:config 'svelte-hmr/runtime/hot-api-esm.js',
vite:config 'svelte-hmr/runtime/proxy-adapter-dom.js',
vite:config 'svelte-hmr'
vite:config ],
vite:config preserveSymlinks: false,
vite:config alias: [ [Object], [Object], [Object], [Object], [Object] ]
vite:config },
vite:config ssr: {
vite:config format: 'esm',
vite:config target: 'node',
vite:config external: [],
vite:config noExternal: [ 'svelte', /^svelte//, 'esm-env', '@sveltejs/kit' ],
vite:config optimizeDeps: { disabled: true, esbuildOptions: [Object] }
vite:config },
vite:config experimental: { importGlobRestoreExtension: false, hmrPartialAccept: true },
vite:config root: '/home/ramendev/projects/just-games',
vite:config server: {
vite:config preTransformRequests: true,
vite:config cors: { preflightContinue: true },
vite:config fs: { strict: true, allow: [Array], deny: [Array] },
vite:config sourcemapIgnoreList: [Function: sourcemapIgnoreList],
vite:config watch: { ignored: [Array] },
vite:config middlewareMode: false
vite:config },
vite:config preview: {
vite:config port: undefined,
vite:config strictPort: undefined,
vite:config host: undefined,
vite:config https: undefined,
vite:config open: undefined,
vite:config proxy: undefined,
vite:config cors: { preflightContinue: true },
vite:config headers: undefined
vite:config },
vite:config define: {
vite:config SVELTEKIT_ADAPTER_NAME: '"@sveltejs/adapter-netlify"',
vite:config SVELTEKIT_APP_VERSION_FILE: '"app/version.json"',
vite:config SVELTEKIT_APP_VERSION_POLL_INTERVAL: '0',
vite:config SVELTEKIT_DEV: 'false',
vite:config SVELTEKIT_EMBEDDED: 'false'
vite:config },
vite:config base: '/',
vite:config publicDir: '/home/ramendev/projects/just-games/static',
vite:config worker: {
vite:config format: 'iife',
vite:config plugins: [
vite:config 'vite:optimized-deps-build',
vite:config 'vite:build-metadata',
vite:config 'vite:watch-package-data',
vite:config 'vite:pre-alias',
vite:config 'alias',
vite:config 'vite:modulepreload-polyfill',
vite:config 'vite:resolve',
vite:config 'vite:html-inline-proxy',
vite:config 'vite:css',
vite:config 'vite:esbuild',
vite:config 'vite:json',
vite:config 'vite:wasm-helper',
vite:config 'vite:worker',
vite:config 'vite:asset',
vite:config 'vite:wasm-fallback',
vite:config 'vite:define',
vite:config 'vite:css-post',
vite:config 'vite:build-html',
vite:config 'vite:worker-import-meta-url',
vite:config 'vite:asset-import-meta-url',
vite:config 'vite:force-systemjs-wrap-complete',
vite:config 'commonjs',
vite:config 'vite:data-uri',
vite:config 'vite:worker-post',
vite:config 'vite:dynamic-import-vars',
vite:config 'vite:import-glob',
vite:config 'vite:build-import-analysis',
vite:config 'vite:esbuild-transpile',
vite:config 'vite:load-fallback'
vite:config ],
vite:config rollupOptions: { output: [Object] },
vite:config getSortedPlugins: [Function: getSortedPlugins],
vite:config getSortedPluginHooks: [Function: getSortedPluginHooks]
vite:config },
vite:config configFile: '/home/ramendev/projects/just-games/vite.config.ts',
vite:config configFileDependencies: [ '/home/ramendev/projects/just-games/vite.config.ts' ],
vite:config inlineConfig: {
vite:config root: undefined,
vite:config base: undefined,
vite:config mode: undefined,
vite:config configFile: undefined,
vite:config logLevel: undefined,
vite:config clearScreen: undefined,
vite:config optimizeDeps: { force: undefined },
vite:config build: {}
vite:config },
vite:config rawBase: '/',
vite:config cacheDir: '/home/ramendev/projects/just-games/node_modules/.vite',
vite:config command: 'build',
vite:config mode: 'production',
vite:config isWorker: false,
vite:config mainConfig: null,
vite:config isProduction: true,
vite:config css: undefined,
vite:config esbuild: { jsxDev: false },
vite:config envDir: '/home/ramendev/projects/just-games',
vite:config env: { BASE_URL: '/', MODE: 'production', DEV: false, PROD: true },
vite:config assetsInclude: [Function: assetsInclude],
vite:config logger: {
vite:config hasWarned: true,
vite:config info: [Function: info],
vite:config warn: [Function: warn],
vite:config warnOnce: [Function: warnOnce],
vite:config error: [Function: error],
vite:config clearScreen: [Function: clearScreen],
vite:config hasErrorLogged: [Function: hasErrorLogged]
vite:config },
vite:config packageCache: Map(1) {
vite:config 'fnpd
/home/ramendev/projects/just-games' => {
vite:config dir: '/home/ramendev/projects/just-games',
vite:config data: [Object],
vite:config hasSideEffects: [Function: hasSideEffects],
vite:config webResolvedImports: {},
vite:config nodeResolvedImports: {},
vite:config setResolvedCache: [Function: setResolvedCache],
vite:config getResolvedCache: [Function: getResolvedCache]
vite:config },
vite:config set: [Function (anonymous)]
vite:config },
vite:config createResolver: [Function: createResolver],
vite:config appType: 'spa',
vite:config getSortedPlugins: [Function: getSortedPlugins],
vite:config getSortedPluginHooks: [Function: getSortedPluginHooks]
vite:config } +77ms
vite v4.4.9 building SSR bundle for production...
transforming (1) node_modules/@sveltejs/kit/src/runtime/server/index.js vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/routes/+layout.svelte +122ms
vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/routes/+error.svelte +280ms
vite:vite-plugin-svelte resolveId resolved virtual css module /home/ramendev/projects/just-games/src/routes/+error.svelte?svelte&type=style&lang.css +6ms
vite:vite-plugin-svelte load returns css for /home/ramendev/projects/just-games/src/routes/+error.svelte +1ms
vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/routes/+page.svelte +21ms
vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/routes/games/+page.svelte +12ms
vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/routes/login/+page.svelte +23ms
vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/routes/signup/+page.svelte +10ms
vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/routes/resources/+page.svelte +31ms
transforming (11) src/routes/resources/+page.svelte vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/routes/about/+page.svelte +8ms
vite:esbuild 537.78ms tsconfck init /home/ramendev/projects/just-games +0ms
vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/lib/components/NavBar.svelte +130ms
vite:vite-plugin-svelte resolveId resolved virtual css module /home/ramendev/projects/just-games/src/lib/components/NavBar.svelte?svelte&type=style&lang.css +8ms
vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/lib/components/Footer.svelte +31ms
vite:vite-plugin-svelte resolveId resolved virtual css module /home/ramendev/projects/just-games/src/lib/components/Footer.svelte?svelte&type=style&lang.css +3ms
vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/.svelte-kit/generated/root.svelte +70ms
vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/lib/components/home/GamePageButton.svelte +75ms
vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/lib/components/games/GamesCarousel.svelte +52ms
vite:vite-plugin-svelte resolveId resolved virtual css module /home/ramendev/projects/just-games/src/lib/components/games/GamesCarousel.svelte?svelte&type=style&lang.css +5ms
vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/lib/components/home/HomeBanner.svelte +11ms
vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/lib/components/games/GamesContent.svelte +24ms
vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/lib/components/WipBanner.svelte +20ms
vite:vite-plugin-svelte resolveId resolved virtual css module /home/ramendev/projects/just-games/src/lib/components/WipBanner.svelte?svelte&type=style&lang.css +5ms
transforming (26) node_modules/@sveltejs/kit/src/runtime/server/endpoint.js vite:vite-plugin-svelte load returns css for /home/ramendev/projects/just-games/src/lib/components/NavBar.svelte +188ms
vite:vite-plugin-svelte load returns css for /home/ramendev/projects/just-games/src/lib/components/Footer.svelte +5ms
vite:vite-plugin-svelte load returns css for /home/ramendev/projects/just-games/src/lib/components/games/GamesCarousel.svelte +33ms
transforming (45) node_modules/svelte/src/runtime/internal/dom.js vite:vite-plugin-svelte load returns css for /home/ramendev/projects/just-games/src/lib/components/WipBanner.svelte +109ms
vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/lib/components/NameLabel.svelte +168ms
vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/lib/components/NavButton.svelte +45ms
vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/lib/components/games/CarouselGameItem.svelte +28ms
vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/lib/components/games/GameCarouselHelpText.svelte +28ms
vite:vite-plugin-svelte resolveId resolved virtual css module /home/ramendev/projects/just-games/src/lib/components/games/GameCarouselHelpText.svelte?svelte&type=style&lang.css +1ms
vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/lib/components/games/search/GoogleImitationTitle.svelte +378ms
transforming (65) src/lib/components/games/search/GoogleImitationTitle.svelte vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/lib/components/games/search/GoogleBannerImitation.svelte +30ms
vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/lib/components/games/search/SearchSection.svelte +25ms
vite:vite-plugin-svelte load returns css for /home/ramendev/projects/just-games/src/lib/components/games/GameCarouselHelpText.svelte +3ms
transforming (83) node_modules/svelte/src/shared/utils/names.js vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/lib/components/games/search/SearchBar.svelte +434ms
vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/lib/components/games/search/SearchResults.svelte +41ms
transforming (100) src/lib/core/game.ts vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/lib/components/games/search/SearchResult.svelte +190ms
"slice" is imported from external module "lodash" but never used in "src/lib/components/games/search/GoogleBannerImitation.svelte", "src/lib/core/game.ts", "src/lib/components/games/GamesCarousel.svelte" and "src/routes/+error.svelte".
✓ 109 modules transformed.
vite:vite-plugin-svelte:stats ssr compile done.
vite:vite-plugin-svelte:stats package files time avg
vite:vite-plugin-svelte:stats svelte-games 26 0.36s 13.7ms +0ms
vite:config bundled config file loaded in 17.58ms +3s
vite:vite-plugin-svelte adding bare svelte packages to optimizeDeps.include: svelte/animate, svelte/easing, svelte/internal, svelte/motion, svelte/store, svelte/transition, svelte, svelte/internal/disclose-version +534ms
vite:vite-plugin-svelte extra config for dependencies generated by vitefu {
optimizeDeps: { include: [], exclude: [] },
ssr: { noExternal: [], external: [] }
} +3ms
vite:vite-plugin-svelte post-processed extra config for dependencies {
optimizeDeps: { include: [], exclude: [] },
ssr: { noExternal: [], external: [] }
} +1ms
vite:vite-plugin-svelte enabling "experimental.hmrPartialAccept" in vite config +0ms
vite:vite-plugin-svelte additional vite config {
resolve: {
dedupe: [
'svelte/animate',
'svelte/easing',
'svelte/internal',
'svelte/motion',
'svelte/ssr',
'svelte/store',
'svelte/transition',
'svelte',
'svelte/internal/disclose-version',
'svelte-hmr/runtime/hot-api-esm.js',
'svelte-hmr/runtime/proxy-adapter-dom.js',
'svelte-hmr'
],
conditions: [ 'svelte' ]
},
optimizeDeps: {
include: [
'svelte/animate',
'svelte/easing',
'svelte/internal',
'svelte/motion',
'svelte/store',
'svelte/transition',
'svelte',
'svelte/internal/disclose-version'
],
exclude: [ 'svelte-hmr' ]
},
ssr: { external: [], noExternal: [ 'svelte', /^svelte// ] },
experimental: { hmrPartialAccept: true }
} +0ms
vite:vite-plugin-svelte resolved options {
hot: false,
compilerOptions: { css: 'external', dev: false, hydratable: true },
extensions: [ '.svelte' ],
emitCss: true,
prebundleSvelteLibraries: false,
configFile: false,
preprocess: [
{
markup: [AsyncFunction: markup],
script: [AsyncFunction: script],
style: [AsyncFunction: style]
},
{ script: [Function: script], markup: [Function: markup] }
],
onwarn: undefined,
root: '/home/ramendev/projects/just-games',
isBuild: true,
isServe: false,
isDebug: true,
isProduction: true,
stats: VitePluginSvelteStats {}
} +6ms

vite:config using resolved config: {
vite:config plugins: [
vite:config 'vite:optimized-deps-build',
vite:config 'vite:build-metadata',
vite:config 'vite:watch-package-data',
vite:config 'vite:pre-alias',
vite:config 'alias',
vite:config 'vite-plugin-svelte',
vite:config 'vite:modulepreload-polyfill',
vite:config 'vite:resolve',
vite:config 'vite:html-inline-proxy',
vite:config 'vite:css',
vite:config 'vite:esbuild',
vite:config 'vite:json',
vite:config 'vite:wasm-helper',
vite:config 'vite:worker',
vite:config 'vite:asset',
vite:config 'vite-plugin-sveltekit-setup',
vite:config 'vite-plugin-sveltekit-virtual-modules',
vite:config 'vite-plugin-sveltekit-guard',
vite:config 'vite-plugin-sveltekit-compile',
vite:config 'vite:wasm-fallback',
vite:config 'vite:define',
vite:config 'vite:css-post',
vite:config 'vite:build-html',
vite:config 'vite:worker-import-meta-url',
vite:config 'vite:asset-import-meta-url',
vite:config 'vite:force-systemjs-wrap-complete',
vite:config 'commonjs',
vite:config 'vite:data-uri',
vite:config 'vite:dynamic-import-vars',
vite:config 'vite:import-glob',
vite:config 'vite:build-import-analysis',
vite:config 'vite:esbuild-transpile',
vite:config 'vite:terser',
vite:config 'vite:manifest',
vite:config 'vite:reporter',
vite:config 'vite:load-fallback'
vite:config ],
vite:config test: { include: [ 'src/**/*.{test,spec}.{js,ts}' ] },
vite:config optimizeDeps: {
vite:config disabled: false,
vite:config include: [
vite:config 'svelte/animate',
vite:config 'svelte/easing',
vite:config 'svelte/internal',
vite:config 'svelte/motion',
vite:config 'svelte/store',
vite:config 'svelte/transition',
vite:config 'svelte',
vite:config 'svelte/internal/disclose-version'
vite:config ],
vite:config exclude: [ 'svelte-hmr', '@sveltejs/kit', '$app', '$env' ],
vite:config esbuildOptions: { preserveSymlinks: false }
vite:config },
vite:config configFile: '/home/ramendev/projects/just-games/vite.config.ts',
vite:config mode: 'production',
vite:config build: {
vite:config target: [ 'es2020', 'edge88', 'firefox78', 'chrome87', 'safari14' ],
vite:config cssTarget: [ 'es2020', 'edge88', 'firefox78', 'chrome87', 'safari14' ],
vite:config outDir: '/home/ramendev/projects/just-games/.svelte-kit/output/client',
vite:config assetsDir: 'assets',
vite:config assetsInlineLimit: 4096,
vite:config cssCodeSplit: true,
vite:config sourcemap: false,
vite:config rollupOptions: {
vite:config input: [Object],
vite:config output: [Object],
vite:config preserveEntrySignatures: 'strict'
vite:config },
vite:config minify: 'esbuild',
vite:config terserOptions: {},
vite:config write: true,
vite:config emptyOutDir: null,
vite:config copyPublicDir: true,
vite:config manifest: 'vite-manifest.json',
vite:config lib: false,
vite:config ssr: false,
vite:config ssrManifest: false,
vite:config ssrEmitAssets: true,
vite:config reportCompressedSize: true,
vite:config chunkSizeWarningLimit: 500,
vite:config watch: null,
vite:config cssMinify: true,
vite:config commonjsOptions: { include: [Array], extensions: [Array] },
vite:config dynamicImportVarsOptions: { warnOnError: true, exclude: [Array] },
vite:config modulePreload: { polyfill: true }
vite:config },
vite:config resolve: {
vite:config mainFields: [ 'svelte', 'module', 'jsnext:main', 'jsnext' ],
vite:config browserField: true,
vite:config conditions: [ 'svelte' ],
vite:config extensions: [
vite:config '.mjs', '.js',
vite:config '.mts', '.ts',
vite:config '.jsx', '.tsx',
vite:config '.json'
vite:config ],
vite:config dedupe: [
vite:config 'svelte/animate',
vite:config 'svelte/easing',
vite:config 'svelte/internal',
vite:config 'svelte/motion',
vite:config 'svelte/ssr',
vite:config 'svelte/store',
vite:config 'svelte/transition',
vite:config 'svelte',
vite:config 'svelte/internal/disclose-version',
vite:config 'svelte-hmr/runtime/hot-api-esm.js',
vite:config 'svelte-hmr/runtime/proxy-adapter-dom.js',
vite:config 'svelte-hmr'
vite:config ],
vite:config preserveSymlinks: false,
vite:config alias: [ [Object], [Object], [Object], [Object], [Object] ]
vite:config },
vite:config ssr: {
vite:config format: 'esm',
vite:config target: 'node',
vite:config external: [],
vite:config noExternal: [ 'svelte', /^svelte//, 'esm-env', '@sveltejs/kit' ],
vite:config optimizeDeps: { disabled: true, esbuildOptions: [Object] }
vite:config },
vite:config experimental: { importGlobRestoreExtension: false, hmrPartialAccept: true },
vite:config root: '/home/ramendev/projects/just-games',
vite:config server: {
vite:config preTransformRequests: true,
vite:config cors: { preflightContinue: true },
vite:config fs: { strict: true, allow: [Array], deny: [Array] },
vite:config sourcemapIgnoreList: [Function: sourcemapIgnoreList],
vite:config watch: { ignored: [Array] },
vite:config middlewareMode: false
vite:config },
vite:config preview: {
vite:config port: undefined,
vite:config strictPort: undefined,
vite:config host: undefined,
vite:config https: undefined,
vite:config open: undefined,
vite:config proxy: undefined,
vite:config cors: { preflightContinue: true },
vite:config headers: undefined
vite:config },
vite:config define: {
vite:config SVELTEKIT_ADAPTER_NAME: '"@sveltejs/adapter-netlify"',
vite:config SVELTEKIT_APP_VERSION_FILE: '"app/version.json"',
vite:config SVELTEKIT_APP_VERSION_POLL_INTERVAL: '0',
vite:config SVELTEKIT_DEV: 'false',
vite:config SVELTEKIT_EMBEDDED: 'false'
vite:config },
vite:config base: './',
vite:config publicDir: '/home/ramendev/projects/just-games/static',
vite:config worker: {
vite:config format: 'iife',
vite:config plugins: [
vite:config 'vite:optimized-deps-build',
vite:config 'vite:build-metadata',
vite:config 'vite:watch-package-data',
vite:config 'vite:pre-alias',
vite:config 'alias',
vite:config 'vite:modulepreload-polyfill',
vite:config 'vite:resolve',
vite:config 'vite:html-inline-proxy',
vite:config 'vite:css',
vite:config 'vite:esbuild',
vite:config 'vite:json',
vite:config 'vite:wasm-helper',
vite:config 'vite:worker',
vite:config 'vite:asset',
vite:config 'vite:wasm-fallback',
vite:config 'vite:define',
vite:config 'vite:css-post',
vite:config 'vite:build-html',
vite:config 'vite:worker-import-meta-url',
vite:config 'vite:asset-import-meta-url',
vite:config 'vite:force-systemjs-wrap-complete',
vite:config 'commonjs',
vite:config 'vite:data-uri',
vite:config 'vite:worker-post',
vite:config 'vite:dynamic-import-vars',
vite:config 'vite:import-glob',
vite:config 'vite:build-import-analysis',
vite:config 'vite:esbuild-transpile',
vite:config 'vite:terser',
vite:config 'vite:load-fallback'
vite:config ],
vite:config rollupOptions: { output: [Object] },
vite:config getSortedPlugins: [Function: getSortedPlugins],
vite:config getSortedPluginHooks: [Function: getSortedPluginHooks]
vite:config },
vite:config configFileDependencies: [ '/home/ramendev/projects/just-games/vite.config.ts' ],
vite:config inlineConfig: {
vite:config configFile: '/home/ramendev/projects/just-games/vite.config.ts',
vite:config mode: 'production',
vite:config logLevel: undefined,
vite:config clearScreen: undefined,
vite:config build: { minify: undefined, assetsInlineLimit: 4096, sourcemap: false },
vite:config optimizeDeps: { force: undefined }
vite:config },
vite:config rawBase: './',
vite:config cacheDir: '/home/ramendev/projects/just-games/node_modules/.vite',
vite:config command: 'build',
vite:config isWorker: false,
vite:config mainConfig: null,
vite:config isProduction: true,
vite:config css: undefined,
vite:config esbuild: { jsxDev: false },
vite:config envDir: '/home/ramendev/projects/just-games',
vite:config env: { BASE_URL: './', MODE: 'production', DEV: false, PROD: true },
vite:config assetsInclude: [Function: assetsInclude],
vite:config logger: {
vite:config hasWarned: true,
vite:config info: [Function: info],
vite:config warn: [Function: warn],
vite:config warnOnce: [Function: warnOnce],
vite:config error: [Function: error],
vite:config clearScreen: [Function: clearScreen],
vite:config hasErrorLogged: [Function: hasErrorLogged]
vite:config },
vite:config packageCache: Map(1) {
vite:config 'fnpd
/home/ramendev/projects/just-games' => {
vite:config dir: '/home/ramendev/projects/just-games',
vite:config data: [Object],
vite:config hasSideEffects: [Function: hasSideEffects],
vite:config webResolvedImports: {},
vite:config nodeResolvedImports: {},
vite:config setResolvedCache: [Function: setResolvedCache],
vite:config getResolvedCache: [Function: getResolvedCache]
vite:config },
vite:config set: [Function (anonymous)]
vite:config },
vite:config createResolver: [Function: createResolver],
vite:config appType: 'spa',
vite:config getSortedPlugins: [Function: getSortedPlugins],
vite:config getSortedPluginHooks: [Function: getSortedPluginHooks]
vite:config } +14ms
vite v4.4.9 building for production...
vite:resolve 5.27ms svelte/animate -> /home/ramendev/projects/just-games/node_modules/svelte/src/runtime/animate/index.js +0ms
vite:resolve 0.29ms svelte/easing -> /home/ramendev/projects/just-games/node_modules/svelte/src/runtime/easing/index.js +0ms
vite:resolve 0.19ms svelte/internal -> /home/ramendev/projects/just-games/node_modules/svelte/src/runtime/internal/index.js +1ms
vite:resolve 0.18ms svelte/motion -> /home/ramendev/projects/just-games/node_modules/svelte/src/runtime/motion/index.js +0ms
vite:resolve 0.17ms svelte/store -> /home/ramendev/projects/just-games/node_modules/svelte/src/runtime/store/index.js +1ms
vite:resolve 0.21ms svelte/transition -> /home/ramendev/projects/just-games/node_modules/svelte/src/runtime/transition/index.js +0ms
vite:resolve 0.21ms svelte -> /home/ramendev/projects/just-games/node_modules/svelte/src/runtime/index.js +0ms
vite:resolve 0.24ms svelte/internal/disclose-version -> /home/ramendev/projects/just-games/node_modules/svelte/src/runtime/internal/disclose-version/index.js +1ms
transforming (1) .svelte-kit/generated/client-optimized/app.js vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/.svelte-kit/generated/root.svelte +236ms
vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/routes/+layout.svelte +23ms
vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/routes/+error.svelte +59ms
vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/routes/+page.svelte +18ms
vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/routes/about/+page.svelte +8ms
vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/routes/games/+page.svelte +12ms
vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/routes/login/+page.svelte +13ms
vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/routes/resources/+page.svelte +12ms
vite:vite-plugin-svelte transform returns compiled js for /home/ramendev/projects/just-games/src/routes/signup/+page.svelte +9ms
transforming (12) node_modules/esm-env/prod-browser.jsUnexpected early exit. This happens when Promises returned by plugins cannot resolve. Unfinished hook action(s) on exit:
(commonjs--resolver) resolveId "/home/ramendev/projects/just-games/node_modules/@sveltejs/kit/src/runtime/client/start.js" undefined
(vite:build-import-analysis) transform "/home/ramendev/projects/just-games/node_modules/@sveltejs/kit/src/runtime/client/start.js"
(vite:build-import-analysis) transform "/home/ramendev/projects/just-games/.svelte-kit/generated/root.svelte"
(commonjs--resolver) resolveId "svelte/internal" "/home/ramendev/projects/just-games/.svelte-kit/generated/root.svelte"
(vite:optimized-deps-build) load "/home/ramendev/projects/just-games/node_modules/.vite/deps_build-e2ef5bc8/svelte_internal.js"
(vite:build-import-analysis) transform "/home/ramendev/projects/just-games/src/routes/+layout.svelte"
(commonjs--resolver) resolveId "svelte/internal" "/home/ramendev/projects/just-games/src/routes/+layout.svelte"
(vite:build-import-analysis) transform "/home/ramendev/projects/just-games/src/routes/+error.svelte"
(commonjs--resolver) resolveId "svelte/internal" "/home/ramendev/projects/just-games/src/routes/+error.svelte"
(vite:build-import-analysis) transform "/home/ramendev/projects/just-games/src/routes/+page.svelte"
(commonjs--resolver) resolveId "svelte/internal" "/home/ramendev/projects/just-games/src/routes/+page.svelte"
(vite:build-import-analysis) transform "/home/ramendev/projects/just-games/src/routes/about/+page.svelte"
(commonjs--resolver) resolveId "svelte/internal" "/home/ramendev/projects/just-games/src/routes/about/+page.svelte"
(vite:build-import-analysis) transform "/home/ramendev/projects/just-games/src/routes/games/+page.svelte"
(commonjs--resolver) resolveId "svelte/internal" "/home/ramendev/projects/just-games/src/routes/games/+page.svelte"
(vite:build-import-analysis) transform "/home/ramendev/projects/just-games/src/routes/login/+page.svelte"
(commonjs--resolver) resolveId "svelte/internal" "/home/ramendev/projects/just-games/src/routes/login/+page.svelte"
(vite:build-import-analysis) transform "/home/ramendev/projects/just-games/src/routes/resources/+page.svelte"
(commonjs--resolver) resolveId "svelte/internal" "/home/ramendev/projects/just-games/src/routes/resources/+page.svelte"
(vite:build-import-analysis) transform "/home/ramendev/projects/just-games/src/routes/signup/+page.svelte"
(commonjs--resolver) resolveId "svelte/internal" "/home/ramendev/projects/just-games/src/routes/signup/+page.svelte"
(commonjs--resolver) resolveId "./client.js" "/home/ramendev/projects/just-games/node_modules/@sveltejs/kit/src/runtime/client/start.js"
(vite:build-import-analysis) transform "/home/ramendev/projects/just-games/node_modules/@sveltejs/kit/src/runtime/client/client.js"
(commonjs--resolver) resolveId "svelte" "/home/ramendev/projects/just-games/node_modules/@sveltejs/kit/src/runtime/client/client.js"
(vite:optimized-deps-build) load "/home/ramendev/projects/just-games/node_modules/.vite/deps_build-e2ef5bc8/svelte.js"
Unexpected early exit. This happens when Promises returned by plugins cannot resolve. Unfinished hook action(s) on exit:
(vite-plugin-sveltekit-compile) writeBundle
✓ built in 3.72s
error during build:
Error: Unexpected early exit. This happens when Promises returned by plugins cannot resolve. Unfinished hook action(s) on exit:
(vite-plugin-sveltekit-compile) writeBundle
at process.handleBeforeExit (file:///home/ramendev/projects/just-games/node_modules/rollup/dist/es/shared/node-entry.js:25714:28)
at Object.onceWrapper (node:events:629:26)
at process.emit (node:events:514:28)

</details>

### Validations

- [X] Follow our [Code of Conduct](https://github.com/vitejs/vite/blob/main/CODE_OF_CONDUCT.md)
- [X] Read the [Contributing Guidelines](https://github.com/vitejs/vite/blob/main/CONTRIBUTING.md).
- [X] Read the [docs](https://vitejs.dev/guide).
- [X] Check that there isn't [already an issue](https://github.com/vitejs/vite/issues) that reports the same bug to avoid creating a duplicate.
- [X] Make sure this is a Vite issue and not a framework-specific issue. For example, if it's a Vue SFC related bug, it should likely be reported to [vuejs/core](https://github.com/vuejs/core) instead.
- [X] Check that this is a concrete bug. For Q&A open a [GitHub Discussion](https://github.com/vitejs/vite/discussions) or join our [Discord Chat Server](https://chat.vitejs.dev/).
- [X] The provided reproduction is a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) of the bug.
@sapphi-red
Copy link
Member

Your code includes a circular dependency. So it's correct that it doesn't work.
https://stackblitz.com/edit/node-fkfv2m?file=game.js,chess.js,index.js

I think it'd be nice to have a better error message though. (like Node: Error: Cannot access 'GameMetadata' before initialization)

@sapphi-red sapphi-red added contribution welcome p2-nice-to-have Not breaking anything but nice to have (priority) feat: ssr and removed pending triage labels Aug 9, 2023
@lib-eramen
Copy link
Author

lib-eramen commented Aug 9, 2023

Thanks for spotting the issue! Resolving the circular dependency worked.

@lib-eramen

This comment was marked as off-topic.

@lib-eramen lib-eramen reopened this Aug 9, 2023
@sapphi-red

This comment was marked as off-topic.

@sapphi-red sapphi-red reopened this Aug 9, 2023
@sapphi-red
Copy link
Member

I'll reopen this issue for making the error message better.

@chaejunlee
Copy link
Contributor

@sapphi-red it looks like the circular dependency should not error.

test(`circular dependencies modules doesn't throw`, async () => {

Do you have any clue why this particular case throws error?

I would like to work on this issue.

However, I am not sure if I should detect the particular case then throw new error, or just change the error message at the instantiateModule level.

@lib-eramen
Copy link
Author

@chaejunlee I was trying to reproduce the error for a different issue: StackBlitz
Just wanted to put it out there. I tried to make the example as minimal as possible.

@chaejunlee
Copy link
Contributor

chaejunlee commented Aug 9, 2023

As far as I can see, ssrImport is used as __vite_ssr_import__(source) during ssr.

const ssrImport = async (dep: string) => {

`const ${importId} = await ${ssrImportKey}(${JSON.stringify(source)});\n`,

In the case of this issue, source (in this case src/lib/core/game.ts) has a circular dependency. Then, ssrImport returns moduleGraph.urlToModuleMap.get(dep)?.ssrModule which is {} in this case.

if (!isCircular(dep) && !pendingImports.get(dep)?.some(isCircular)) {
pendingDeps.push(dep)
if (pendingDeps.length === 1) {
pendingImports.set(url, pendingDeps)
}
const mod = await ssrLoadModule(
dep,
server,
context,
urlStack,
fixStacktrace,
)
if (pendingDeps.length === 1) {
pendingImports.delete(url)
} else {
pendingDeps.splice(pendingDeps.indexOf(dep), 1)
}
// return local module to avoid race condition #5470
return mod
}
return moduleGraph.urlToModuleMap.get(dep)?.ssrModule

That is why the error says __vite_ssr_import_0__.GameMetadata is not a constructor. The object __vite_ssr_import_0__ is empty.

Screenshot 2023-08-10 at 3 22 44

What I am currently trying to do is throwing error at the ssrImport level, but this doesn't look good. Because, It throws the error every time the circular dependency (in this case, src/lib/core/game.ts) with empty moduleGraph.urlToModuleMap.get(dep)?.ssrModule is imported in the original javscript file.

Because this is a problem of the nature of ssrImport handles circular dependency, I can't think of any better solution.

I would like to hear other's thought on this.

@sapphi-red
Copy link
Member

@sapphi-red it looks like the circular dependency should not error.

test(`circular dependencies modules doesn't throw`, async () => {

Do you have any clue why this particular case throws error?

The test case one doesn't throw any errors on Node: https://stackblitz.com/edit/node-qgbmvq?file=index.js,circular-dep-init.js,module-b.js

I don't know why it doesn't throw in this case and it throws in the OP's case. But I guess it's written in the ECMA script spec.
Maybe this part is related: https://262.ecma-international.org/14.0/#sec-example-cyclic-module-record-graphs

Because this is a problem of the nature of ssrImport handles circular dependency, I can't think of any better solution.

I guess splitting into two phases would work. Collecting the exports / linking in the first phase and executing in the second phase. Though I haven't thought this deeply yet.

@sheremet-va
Copy link
Member

I guess splitting into two phases would work. Collecting the exports / linking in the first phase and executing in the second phase. Though I haven't thought this deeply yet.

Would be nice to implement this when porting vite-node (I'm planning to resume the efforts soon). I noticed how it's implemented in VM module and quite liked the performance implications there. If you are looking to implement it, I would look into their implementation even though VM API is not perfect for memory management and HMR.

@sapphi-red
Copy link
Member

We can also check how engine262 handles this. Performance is not included in their goals but its implementation would be 100% spec compliant.
https://github.com/engine262/engine262/blob/1582a0c3b2b75eaa81d5c535852d632de7e7a28a/src/modules.mts#L123-L169

@AlbertMarashi
Copy link

I'm getting these issues with so many modules. In SSR, the module is treated as an object, but in client-side it works

@AriPerkkio
Copy link
Contributor

Here's minimal reproduction case without any 3rd party dependencies: https://stackblitz.com/~/edit/vite-cyclic-imports-vs-node?file=load-with-vite.mjs&file=load-with-node.mjs

$ node ./load-with-vite.mjs

10:36:04 [vite] Error when evaluating SSR module /ion-js/dom/Blob.js:
|- TypeError: Cannot read properties of undefined (reading 'BLOB')
    at eval (/home/projects/vite-cyclic-imports-vs-node/ion-js/dom/Blob.js:5:45)
    at async instantiateModule (file:///home/projects/vite-cyclic-imports-vs-node/node_modules/vite/dist/node/chunks/dep-DyBnyoVI.js:52963:5)

Loading the same setup with Node without Vite works fine:

$ node ./load-with-node.mjs

[Module: null prototype] {
  IonTypes: { BLOB: 'Blob' },
  dom: [Module: null prototype] { Blob: 'Blob' }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
contribution welcome feat: ssr p2-nice-to-have Not breaking anything but nice to have (priority)
Projects
None yet
Development

No branches or pull requests

6 participants