diff --git a/packages/hot_hook/src/dynamic_import_checker.ts b/packages/hot_hook/src/dynamic_import_checker.ts index 87d1793..3965018 100644 --- a/packages/hot_hook/src/dynamic_import_checker.ts +++ b/packages/hot_hook/src/dynamic_import_checker.ts @@ -7,6 +7,8 @@ import { parseImports } from 'parse-imports' * Otherwise we will throw an error since we cannot make the file reloadable * * We are caching the results to avoid reading the same file multiple times + * + * When no import is found for the given specifier we assume that it is imported using a dynamic specifier. */ export class DynamicImportChecker { private cache: Map> = new Map() @@ -20,10 +22,14 @@ export class DynamicImportChecker { const parentCode = await readFile(parentPath, 'utf-8') const imports = [...(await parseImports(parentCode))] - const isFileDynamicallyImportedFromParent = imports.some((importStatement) => { - return importStatement.isDynamicImport && importStatement.moduleSpecifier.value === specifier + const matchingImport = imports.find((importStatement) => { + return importStatement.moduleSpecifier.value === specifier }) + const isFileDynamicallyImportedFromParent = matchingImport + ? matchingImport.isDynamicImport + : true + const currentCache = this.cache.get(cacheKey) ?? new Map() this.cache.set(cacheKey, currentCache.set(specifier, isFileDynamicallyImportedFromParent)) diff --git a/packages/hot_hook/src/loader.ts b/packages/hot_hook/src/loader.ts index 09825bd..178a3c6 100644 --- a/packages/hot_hook/src/loader.ts +++ b/packages/hot_hook/src/loader.ts @@ -97,7 +97,15 @@ export class HotHookLoader { debug('File change %s', relativeFilePath) const filePath = pathResolve(relativeFilePath) - const realFilePath = await realpath(filePath) + const realFilePath = await realpath(filePath).catch(() => null) + + /** + * Realpath throws an error when the file does not exist. + */ + if (!realFilePath) { + debug('Could not resolve realFilePath %s', filePath) + return this.#dependencyTree.remove(filePath) + } /** * First check if file still exists. If not, we must remove it from the diff --git a/packages/hot_hook/tests/dynamic_import_checker.spec.ts b/packages/hot_hook/tests/dynamic_import_checker.spec.ts index a7c2c26..ab692b1 100644 --- a/packages/hot_hook/tests/dynamic_import_checker.spec.ts +++ b/packages/hot_hook/tests/dynamic_import_checker.spec.ts @@ -25,4 +25,19 @@ test.group('Dynamic Import Checker', () => { assert.isTrue(await checker.ensureFileIsImportedDynamicallyFromParent(path, './bla')) assert.isTrue(await checker.ensureFileIsImportedDynamicallyFromParent(path, '#app/aliases-bla')) }) + + test('Consider missing specifier as dynamically imported', async ({ assert, fs }) => { + await fs.create( + 'app.ts', + ` + import './foo' + await import('./bla') + `, + ) + + const checker = new DynamicImportChecker() + const path = join(fs.basePath, 'app.ts') + + assert.isTrue(await checker.ensureFileIsImportedDynamicallyFromParent(path, './unknown')) + }) })