From 9942d2e9db36a061f8b3eb6cd8d49256c07d4ebd Mon Sep 17 00:00:00 2001 From: Glenn Reyes Date: Sat, 11 Oct 2025 18:36:40 +0200 Subject: [PATCH 1/4] fix: ignore preview warnings outside email directory --- .../hot-reloading/create-dependency-graph.ts | 36 +++++++++++++++---- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/packages/react-email/src/utils/preview/hot-reloading/create-dependency-graph.ts b/packages/react-email/src/utils/preview/hot-reloading/create-dependency-graph.ts index 8be8721b8c..adec03700d 100644 --- a/packages/react-email/src/utils/preview/hot-reloading/create-dependency-graph.ts +++ b/packages/react-email/src/utils/preview/hot-reloading/create-dependency-graph.ts @@ -42,6 +42,15 @@ const isJavascriptModule = (filePath: string) => { return javascriptExtensions.includes(extensionName); }; +const isInsideDirectory = (baseDirectory: string, targetPath: string) => { + const relativePath = path.relative(baseDirectory, targetPath); + + return ( + relativePath === '' || + (!relativePath.startsWith('..') && !path.isAbsolute(relativePath)) + ); +}; + const checkFileExtensionsUntilItExists = ( pathWithoutExtension: string, ): string | undefined => { @@ -79,6 +88,7 @@ const checkFileExtensionsUntilItExists = ( * so that it doesn't need to recompute the entire dependency graph but only the parts changed. */ export const createDependencyGraph = async (directory: string) => { + const normalizedDirectory = path.resolve(directory); const filePaths = await readAllFilesInsideDirectory(directory); const modulePaths = filePaths.filter(isJavascriptModule); const graph: DependencyGraph = Object.fromEntries( @@ -136,9 +146,16 @@ export const createDependencyGraph = async (directory: string) => { if (pathWithExtension) { pathToDependencyFromDirectory = pathWithExtension; } else { - console.warn( - `Could not find index file for directory at ${pathToDependencyFromDirectory}. This is probably going to cause issues with both hot reloading and your code.`, - ); + if ( + isInsideDirectory( + normalizedDirectory, + pathToDependencyFromDirectory, + ) + ) { + console.warn( + `Could not find index file for directory at ${pathToDependencyFromDirectory}. This is probably going to cause issues with both hot reloading and your code.`, + ); + } } } @@ -163,9 +180,16 @@ export const createDependencyGraph = async (directory: string) => { if (pathWithEnsuredExtension) { pathToDependencyFromDirectory = pathWithEnsuredExtension; } else { - console.warn( - `Could not find file at ${pathToDependencyFromDirectory}`, - ); + if ( + isInsideDirectory( + normalizedDirectory, + pathToDependencyFromDirectory, + ) + ) { + console.warn( + `Could not find file at ${pathToDependencyFromDirectory}`, + ); + } } return pathToDependencyFromDirectory; From 98853666267773b5518dfc9a45ede08da07367e3 Mon Sep 17 00:00:00 2001 From: Glenn Reyes Date: Sat, 11 Oct 2025 18:52:58 +0200 Subject: [PATCH 2/4] test(react-email): cover preview warning guard --- .../create-dependency-graph.spec.ts | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/packages/react-email/src/utils/preview/hot-reloading/create-dependency-graph.spec.ts b/packages/react-email/src/utils/preview/hot-reloading/create-dependency-graph.spec.ts index f8433352f5..e1bddd369a 100644 --- a/packages/react-email/src/utils/preview/hot-reloading/create-dependency-graph.spec.ts +++ b/packages/react-email/src/utils/preview/hot-reloading/create-dependency-graph.spec.ts @@ -143,4 +143,45 @@ import {} from './file-b'; "should remove itself from dependents once it's unlinked", ).not.toContain(pathToTemporaryFile); }); + + it.sequential( + 'should not warn when dependency outside the directory is missing an index file', + async () => { + const pathToOutsideDirectory = path.resolve( + testingDiretctory, + '../.temporary-outside-directory', + ); + const pathToImporter = path.join( + testingDiretctory, + '.temporary-outside-import.ts', + ); + + await fs.mkdir(pathToOutsideDirectory, { recursive: true }); + await fs.writeFile( + pathToImporter, + `import '../.temporary-outside-directory';\n`, + 'utf8', + ); + + const outsideDirectoryModule: DependencyGraph[number] = { + path: pathToOutsideDirectory, + dependencyPaths: [], + dependentPaths: [], + moduleDependencies: [], + }; + + dependencyGraph[pathToOutsideDirectory] = outsideDirectoryModule; + + try { + await updateDependencyGraph('add', pathToImporter); + } finally { + await updateDependencyGraph('unlink', pathToImporter); + await fs.rm(pathToImporter, { force: true }); + delete dependencyGraph[pathToOutsideDirectory]; + if (existsSync(pathToOutsideDirectory)) { + await fs.rm(pathToOutsideDirectory, { recursive: true, force: true }); + } + } + }, + ); }); From 39bb3fc3b57181442d0d36e5bb60418292cfcc97 Mon Sep 17 00:00:00 2001 From: Glenn Reyes Date: Sun, 12 Oct 2025 04:11:50 +0200 Subject: [PATCH 3/4] Update create-dependency-graph.spec.ts Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> --- .../utils/preview/hot-reloading/create-dependency-graph.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-email/src/utils/preview/hot-reloading/create-dependency-graph.spec.ts b/packages/react-email/src/utils/preview/hot-reloading/create-dependency-graph.spec.ts index e1bddd369a..45f0c6375d 100644 --- a/packages/react-email/src/utils/preview/hot-reloading/create-dependency-graph.spec.ts +++ b/packages/react-email/src/utils/preview/hot-reloading/create-dependency-graph.spec.ts @@ -145,7 +145,7 @@ import {} from './file-b'; }); it.sequential( - 'should not warn when dependency outside the directory is missing an index file', + 'does not warn when dependency outside the directory is missing an index file', async () => { const pathToOutsideDirectory = path.resolve( testingDiretctory, From 314323c00486e7ae0f5b6c468e6b67f10891c31e Mon Sep 17 00:00:00 2001 From: Glenn Reyes Date: Thu, 16 Oct 2025 17:11:01 +0200 Subject: [PATCH 4/4] fix: always show warnings for missing files regardless of location --- .../create-dependency-graph.spec.ts | 40 ------------------- .../hot-reloading/create-dependency-graph.ts | 36 +++-------------- 2 files changed, 6 insertions(+), 70 deletions(-) diff --git a/packages/react-email/src/utils/preview/hot-reloading/create-dependency-graph.spec.ts b/packages/react-email/src/utils/preview/hot-reloading/create-dependency-graph.spec.ts index 45f0c6375d..ef90147aa2 100644 --- a/packages/react-email/src/utils/preview/hot-reloading/create-dependency-graph.spec.ts +++ b/packages/react-email/src/utils/preview/hot-reloading/create-dependency-graph.spec.ts @@ -144,44 +144,4 @@ import {} from './file-b'; ).not.toContain(pathToTemporaryFile); }); - it.sequential( - 'does not warn when dependency outside the directory is missing an index file', - async () => { - const pathToOutsideDirectory = path.resolve( - testingDiretctory, - '../.temporary-outside-directory', - ); - const pathToImporter = path.join( - testingDiretctory, - '.temporary-outside-import.ts', - ); - - await fs.mkdir(pathToOutsideDirectory, { recursive: true }); - await fs.writeFile( - pathToImporter, - `import '../.temporary-outside-directory';\n`, - 'utf8', - ); - - const outsideDirectoryModule: DependencyGraph[number] = { - path: pathToOutsideDirectory, - dependencyPaths: [], - dependentPaths: [], - moduleDependencies: [], - }; - - dependencyGraph[pathToOutsideDirectory] = outsideDirectoryModule; - - try { - await updateDependencyGraph('add', pathToImporter); - } finally { - await updateDependencyGraph('unlink', pathToImporter); - await fs.rm(pathToImporter, { force: true }); - delete dependencyGraph[pathToOutsideDirectory]; - if (existsSync(pathToOutsideDirectory)) { - await fs.rm(pathToOutsideDirectory, { recursive: true, force: true }); - } - } - }, - ); }); diff --git a/packages/react-email/src/utils/preview/hot-reloading/create-dependency-graph.ts b/packages/react-email/src/utils/preview/hot-reloading/create-dependency-graph.ts index adec03700d..8be8721b8c 100644 --- a/packages/react-email/src/utils/preview/hot-reloading/create-dependency-graph.ts +++ b/packages/react-email/src/utils/preview/hot-reloading/create-dependency-graph.ts @@ -42,15 +42,6 @@ const isJavascriptModule = (filePath: string) => { return javascriptExtensions.includes(extensionName); }; -const isInsideDirectory = (baseDirectory: string, targetPath: string) => { - const relativePath = path.relative(baseDirectory, targetPath); - - return ( - relativePath === '' || - (!relativePath.startsWith('..') && !path.isAbsolute(relativePath)) - ); -}; - const checkFileExtensionsUntilItExists = ( pathWithoutExtension: string, ): string | undefined => { @@ -88,7 +79,6 @@ const checkFileExtensionsUntilItExists = ( * so that it doesn't need to recompute the entire dependency graph but only the parts changed. */ export const createDependencyGraph = async (directory: string) => { - const normalizedDirectory = path.resolve(directory); const filePaths = await readAllFilesInsideDirectory(directory); const modulePaths = filePaths.filter(isJavascriptModule); const graph: DependencyGraph = Object.fromEntries( @@ -146,16 +136,9 @@ export const createDependencyGraph = async (directory: string) => { if (pathWithExtension) { pathToDependencyFromDirectory = pathWithExtension; } else { - if ( - isInsideDirectory( - normalizedDirectory, - pathToDependencyFromDirectory, - ) - ) { - console.warn( - `Could not find index file for directory at ${pathToDependencyFromDirectory}. This is probably going to cause issues with both hot reloading and your code.`, - ); - } + console.warn( + `Could not find index file for directory at ${pathToDependencyFromDirectory}. This is probably going to cause issues with both hot reloading and your code.`, + ); } } @@ -180,16 +163,9 @@ export const createDependencyGraph = async (directory: string) => { if (pathWithEnsuredExtension) { pathToDependencyFromDirectory = pathWithEnsuredExtension; } else { - if ( - isInsideDirectory( - normalizedDirectory, - pathToDependencyFromDirectory, - ) - ) { - console.warn( - `Could not find file at ${pathToDependencyFromDirectory}`, - ); - } + console.warn( + `Could not find file at ${pathToDependencyFromDirectory}`, + ); } return pathToDependencyFromDirectory;