diff --git a/package.json b/package.json index 90b1b6822ee..162e8f0ae74 100644 --- a/package.json +++ b/package.json @@ -99,9 +99,6 @@ }, "prettier": "@sanity/prettier-config", "devDependencies": { - "@babel/preset-env": "^7.24.7", - "@babel/preset-react": "^7.24.7", - "@babel/preset-typescript": "^7.24.7", "@google-cloud/storage": "^7.11.0", "@playwright/test": "1.44.1", "@repo/dev-aliases": "workspace:*", diff --git a/packages/@repo/test-config/.depcheckrc.json b/packages/@repo/test-config/.depcheckrc.json new file mode 100644 index 00000000000..6f9da0ba787 --- /dev/null +++ b/packages/@repo/test-config/.depcheckrc.json @@ -0,0 +1,8 @@ +{ + "ignores": [ + "@babel/preset-env", + "@babel/preset-react", + "@babel/preset-typescript", + "babel-plugin-transform-vite-meta-hot" + ] +} diff --git a/packages/@repo/test-config/jest/createJestConfig.mjs b/packages/@repo/test-config/jest/createJestConfig.mjs index 174738b1f3d..8d1f3fbbd6a 100644 --- a/packages/@repo/test-config/jest/createJestConfig.mjs +++ b/packages/@repo/test-config/jest/createJestConfig.mjs @@ -1,9 +1,10 @@ /* eslint-disable tsdoc/syntax */ -import devAliases from '@repo/dev-aliases' - import path from 'node:path' + +import devAliases from '@repo/dev-aliases' import {escapeRegExp, omit} from 'lodash-es' + import {resolveDirName} from './resolveDirName.mjs' const dirname = resolveDirName(import.meta.url) @@ -71,7 +72,6 @@ export function createJestConfig(config = {}) { resolver: path.resolve(dirname, './resolver.cjs'), testEnvironment: path.resolve(dirname, './jsdom.jest.env.ts'), setupFiles: [...setupFiles, path.resolve(dirname, './setup.ts')], - // testEnvironment: 'jsdom', testEnvironmentOptions: { url: 'http://localhost:3333', }, @@ -103,6 +103,7 @@ export function createJestConfig(config = {}) { '@babel/preset-typescript', ['@babel/preset-react', {runtime: 'automatic'}], ], + plugins: ['babel-plugin-transform-vite-meta-hot'], }, ], }, diff --git a/packages/@repo/test-config/package.json b/packages/@repo/test-config/package.json index 8c8c09da1e3..536754f7f34 100644 --- a/packages/@repo/test-config/package.json +++ b/packages/@repo/test-config/package.json @@ -9,8 +9,12 @@ "./vitest": "./vitest/index.mjs" }, "devDependencies": { + "@babel/preset-env": "^7.24.7", + "@babel/preset-react": "^7.24.7", + "@babel/preset-typescript": "^7.24.7", "@jest/globals": "^29.7.0", "@repo/dev-aliases": "workspace:*", + "babel-plugin-transform-vite-meta-hot": "^1.0.0", "dotenv": "^16.4.5", "jest-environment-jsdom": "^29.7.0", "lodash-es": "^4.17.21", diff --git a/packages/sanity/src/core/error/ErrorLogger.tsx b/packages/sanity/src/core/error/ErrorLogger.tsx index 708699b8baf..87dbfb75a50 100644 --- a/packages/sanity/src/core/error/ErrorLogger.tsx +++ b/packages/sanity/src/core/error/ErrorLogger.tsx @@ -64,5 +64,9 @@ function isKnownError(err: Error): boolean { return true } + if ('ViteDevServerStoppedError' in err && err.ViteDevServerStoppedError) { + return true + } + return false } diff --git a/packages/sanity/src/core/studio/StudioErrorBoundary.tsx b/packages/sanity/src/core/studio/StudioErrorBoundary.tsx index 7c26dc8179f..32b0de92a00 100644 --- a/packages/sanity/src/core/studio/StudioErrorBoundary.tsx +++ b/packages/sanity/src/core/studio/StudioErrorBoundary.tsx @@ -11,7 +11,14 @@ import { Stack, Text, } from '@sanity/ui' -import {type ComponentType, type ErrorInfo, type ReactNode, useCallback, useState} from 'react' +import { + type ComponentType, + type ErrorInfo, + lazy, + type ReactNode, + useCallback, + useState, +} from 'react' import {ErrorActions, isDev, isProd} from 'sanity' import {styled} from 'styled-components' import {useHotModuleReload} from 'use-hot-module-reload' @@ -22,6 +29,17 @@ import {CorsOriginError} from '../store' import {isRecord} from '../util' import {CorsOriginErrorScreen, SchemaErrorsScreen} from './screens' +/** + * The DevServerStoppedErrorScreen will always have been lazy loaded to client + * in instances where it is used, since DevServerStoppedError is only thrown + * when this module is loaded, and this screen is also conditional on this error type + */ +const DevServerStoppedErrorScreen = lazy(() => + import('./ViteDevServerStopped').then((DevServerStopped) => ({ + default: DevServerStopped.DevServerStoppedErrorScreen, + })), +) + interface StudioErrorBoundaryProps { children: ReactNode heading?: string @@ -80,6 +98,10 @@ export const StudioErrorBoundary: ComponentType = ({ return } + if (error && 'ViteDevServerStoppedError' in error && error.ViteDevServerStoppedError) { + return + } + if (!error) { return {children} } diff --git a/packages/sanity/src/core/studio/StudioLayout.tsx b/packages/sanity/src/core/studio/StudioLayout.tsx index 5641104e904..9c992354bcc 100644 --- a/packages/sanity/src/core/studio/StudioLayout.tsx +++ b/packages/sanity/src/core/studio/StudioLayout.tsx @@ -1,7 +1,7 @@ /* eslint-disable i18next/no-literal-string, @sanity/i18n/no-attribute-template-literals */ import {Card, Flex} from '@sanity/ui' import {startCase} from 'lodash' -import {Suspense, useCallback, useEffect, useMemo, useState} from 'react' +import {lazy, Suspense, useCallback, useEffect, useMemo, useState} from 'react' import {NavbarContext} from 'sanity/_singletons' import {RouteScope, useRouter, useRouterState} from 'sanity/router' import {styled} from 'styled-components' @@ -18,6 +18,14 @@ import { import {StudioErrorBoundary} from './StudioErrorBoundary' import {useWorkspace} from './workspace' +const DetectViteDevServerStopped = lazy(() => + import('./ViteDevServerStopped').then((DevServerStopped) => ({ + default: DevServerStopped.DetectViteDevServerStopped, + })), +) + +const detectViteDevServerStopped = import.meta.hot && process.env.NODE_ENV === 'development' + const SearchFullscreenPortalCard = styled(Card)` height: 100%; left: 0; @@ -173,6 +181,7 @@ export function StudioLayoutComponent() { {/* By using the tool name as the key on the error boundary, we force it to re-render when switching tools, which ensures we don't show the wrong tool having crashed */} + {detectViteDevServerStopped && }