Skip to content

Commit 2d0b2e1

Browse files
kerwanpJulien-R44
andauthored
feat: consider missing import as dynamic (#14)
Co-authored-by: Julien Ripouteau <[email protected]>
1 parent 57c15f4 commit 2d0b2e1

File tree

3 files changed

+32
-3
lines changed

3 files changed

+32
-3
lines changed

packages/hot_hook/src/dynamic_import_checker.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import { parseImports } from 'parse-imports'
77
* Otherwise we will throw an error since we cannot make the file reloadable
88
*
99
* We are caching the results to avoid reading the same file multiple times
10+
*
11+
* When no import is found for the given specifier we assume that it is imported using a dynamic specifier.
1012
*/
1113
export class DynamicImportChecker {
1214
private cache: Map<string, Map<string, boolean>> = new Map()
@@ -20,10 +22,14 @@ export class DynamicImportChecker {
2022
const parentCode = await readFile(parentPath, 'utf-8')
2123
const imports = [...(await parseImports(parentCode))]
2224

23-
const isFileDynamicallyImportedFromParent = imports.some((importStatement) => {
24-
return importStatement.isDynamicImport && importStatement.moduleSpecifier.value === specifier
25+
const matchingImport = imports.find((importStatement) => {
26+
return importStatement.moduleSpecifier.value === specifier
2527
})
2628

29+
const isFileDynamicallyImportedFromParent = matchingImport
30+
? matchingImport.isDynamicImport
31+
: true
32+
2733
const currentCache = this.cache.get(cacheKey) ?? new Map()
2834
this.cache.set(cacheKey, currentCache.set(specifier, isFileDynamicallyImportedFromParent))
2935

packages/hot_hook/src/loader.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,15 @@ export class HotHookLoader {
9797
debug('File change %s', relativeFilePath)
9898

9999
const filePath = pathResolve(relativeFilePath)
100-
const realFilePath = await realpath(filePath)
100+
const realFilePath = await realpath(filePath).catch(() => null)
101+
102+
/**
103+
* Realpath throws an error when the file does not exist.
104+
*/
105+
if (!realFilePath) {
106+
debug('Could not resolve realFilePath %s', filePath)
107+
return this.#dependencyTree.remove(filePath)
108+
}
101109

102110
/**
103111
* First check if file still exists. If not, we must remove it from the

packages/hot_hook/tests/dynamic_import_checker.spec.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,19 @@ test.group('Dynamic Import Checker', () => {
2525
assert.isTrue(await checker.ensureFileIsImportedDynamicallyFromParent(path, './bla'))
2626
assert.isTrue(await checker.ensureFileIsImportedDynamicallyFromParent(path, '#app/aliases-bla'))
2727
})
28+
29+
test('Consider missing specifier as dynamically imported', async ({ assert, fs }) => {
30+
await fs.create(
31+
'app.ts',
32+
`
33+
import './foo'
34+
await import('./bla')
35+
`,
36+
)
37+
38+
const checker = new DynamicImportChecker()
39+
const path = join(fs.basePath, 'app.ts')
40+
41+
assert.isTrue(await checker.ensureFileIsImportedDynamicallyFromParent(path, './unknown'))
42+
})
2843
})

0 commit comments

Comments
 (0)