diff --git a/npm/vite-dev-server/src/plugins/cypress.ts b/npm/vite-dev-server/src/plugins/cypress.ts index 49e16312ffe..91e95b1f552 100644 --- a/npm/vite-dev-server/src/plugins/cypress.ts +++ b/npm/vite-dev-server/src/plugins/cypress.ts @@ -2,7 +2,7 @@ import debugFn from 'debug' import type { ModuleNode, PluginOption, ViteDevServer } from 'vite-7' import type { Vite } from '../getVite.js' import { parse, HTMLElement } from 'node-html-parser' -import fs from 'fs' +import fs from 'fs/promises' import type { ViteDevServerConfig } from '../devServer.js' import path from 'path' @@ -33,6 +33,7 @@ export const Cypress = ( vite: Vite, ): PluginOption => { let base = '/' + let loaderPromise: Promise | null = null const projectRoot = options.cypressConfig.projectRoot const supportFilePath = options.cypressConfig.supportFile ? path.resolve(projectRoot, options.cypressConfig.supportFile) : false @@ -42,9 +43,31 @@ export const Cypress = ( const indexHtmlFile = options.cypressConfig.indexHtmlFile let specsPathsSet = getSpecsPathsSet(specs) - // TODO: use async fs methods here - // eslint-disable-next-line no-restricted-syntax - let loader = fs.readFileSync(INIT_FILEPATH, 'utf8') + + // Load the init file asynchronously with proper error handling + const loadInitFile = async (): Promise => { + try { + const content = await fs.readFile(INIT_FILEPATH, 'utf8') + + debug(`Successfully loaded init file from ${INIT_FILEPATH}`) + + return content + } catch (error) { + debug(`Failed to load init file from ${INIT_FILEPATH}:`, error) + throw new Error(`Failed to load Cypress init file: ${error instanceof Error ? error.message : 'Unknown error'}`) + } + } + + const getLoaderPromise = () => { + if (!loaderPromise) { + loaderPromise = loadInitFile().catch((err) => { + loaderPromise = null + throw err + }) + } + + return loaderPromise + } devServerEvents.on('dev-server:specs:changed', ({ specs, options }: { specs: Spec[], options?: { neededForJustInTimeCompile: boolean }}) => { if (options?.neededForJustInTimeCompile) { @@ -79,7 +102,7 @@ export const Cypress = ( debug('resolved the indexHtmlPath as', indexHtmlPath, 'from', indexHtmlFile) - let indexHtmlContent = await fs.promises.readFile(indexHtmlPath, { encoding: 'utf8' }) + let indexHtmlContent = await fs.readFile(indexHtmlPath, { encoding: 'utf8' }) // Inject the script tags indexHtmlContent = indexHtmlContent.replace( @@ -92,6 +115,9 @@ export const Cypress = ( // find last index const endOfBody = indexHtmlContent.lastIndexOf('') + // Get the loader content asynchronously + const loader = await getLoaderPromise() + // insert the script in the end of the body const newHtml = ` ${indexHtmlContent.substring(0, endOfBody)}