Skip to content

Commit bc0c49d

Browse files
committed
chore: changes from review
1 parent 848faee commit bc0c49d

File tree

1 file changed

+64
-47
lines changed

1 file changed

+64
-47
lines changed

packages/runtime/src/helpers/watcher.ts

Lines changed: 64 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,69 @@ import { promises } from 'fs'
22
import { join } from 'path'
33

44
import { build } from '@netlify/esbuild'
5-
import { watch } from 'chokidar'
5+
import { FSWatcher, watch } from 'chokidar'
66

7-
const fileList = (watched: Record<string, Array<string>>) =>
7+
const toFileList = (watched: Record<string, Array<string>>) =>
88
Object.entries(watched).flatMap(([dir, files]) => files.map((file) => join(dir, file)))
99

10+
/**
11+
* Compile the middleware file using esbuild
12+
*/
13+
14+
const buildMiddlewareFile = async (entryPoints: Array<string>, base: string) => {
15+
try {
16+
await build({
17+
entryPoints,
18+
outfile: join(base, '.netlify', 'middleware.js'),
19+
bundle: true,
20+
format: 'esm',
21+
target: 'esnext',
22+
})
23+
} catch (error) {
24+
console.error(error)
25+
}
26+
}
27+
28+
/**
29+
* We only compile middleware if there's exactly one file. If there's more than one, we log a warning and don't compile.
30+
*/
31+
const shouldFilesBeCompiled = (watchedFiles: Array<string>, isFirstRun: boolean) => {
32+
if (watchedFiles.length === 0) {
33+
if (!isFirstRun) {
34+
// Only log on subsequent builds, because having it on first build makes it seem like a warning, when it's a normal state
35+
console.log('No middleware found')
36+
}
37+
return false
38+
}
39+
if (watchedFiles.length > 1) {
40+
console.log('Multiple middleware files found:')
41+
console.log(watchedFiles.join('\n'))
42+
console.log('This is not supported.')
43+
return false
44+
}
45+
return true
46+
}
47+
48+
const updateWatchedFiles = async (watcher: FSWatcher, base: string, isFirstRun = false) => {
49+
try {
50+
// Start by deleting the old file. If we error out, we don't want to leave the old file around
51+
await promises.unlink(join(base, '.netlify', 'middleware.js'))
52+
} catch {
53+
// Ignore, because it's fine if it didn't exist
54+
}
55+
// The list of watched files is an object with the directory as the key and an array of files as the value.
56+
// We need to flatten this into a list of files
57+
const watchedFiles = toFileList(watcher.getWatched())
58+
59+
if (!shouldFilesBeCompiled(watchedFiles, isFirstRun)) {
60+
return
61+
}
62+
63+
console.log(`${isFirstRun ? 'Building' : 'Rebuilding'} middleware ${watchedFiles[0]}...`)
64+
await buildMiddlewareFile(watchedFiles, base)
65+
console.log('...done')
66+
}
67+
1068
const start = async (base: string) => {
1169
const watcher = watch(['middleware.js', 'middleware.ts', 'src/middleware.js', 'src/middleware.ts'], {
1270
// Try and ensure renames just emit one event
@@ -16,65 +74,24 @@ const start = async (base: string) => {
1674
cwd: base,
1775
})
1876

19-
const update = async (initial = false) => {
20-
try {
21-
// Start by deleting the old file. If we error out, we don't want to leave the old file around
22-
await promises.unlink(join(base, '.netlify', 'middleware.js'))
23-
} catch {
24-
// Ignore, because it's fine if it didn't exist
25-
}
26-
// The list of watched files is an object with the directory as the key and an array of files as the value.
27-
// We need to flatten this into a list of files
28-
const watchedFiles = fileList(watcher.getWatched())
29-
if (watchedFiles.length === 0) {
30-
if (!initial) {
31-
// Only log on subsequent builds, because having it on first build makes it seem like a warning, when it's a normal state
32-
console.log('No middleware found')
33-
}
34-
return
35-
}
36-
if (watchedFiles.length > 1) {
37-
console.log('Multiple middleware files found:')
38-
console.log(watchedFiles.join('\n'))
39-
console.log('This is not supported.')
40-
// Return without compiling anything
41-
return
42-
}
43-
console.log(`${initial ? 'Building' : 'Rebuilding'} middleware ${watchedFiles[0]}...`)
44-
try {
45-
await build({
46-
entryPoints: watchedFiles,
47-
outfile: join(base, '.netlify', 'middleware.js'),
48-
bundle: true,
49-
format: 'esm',
50-
target: 'esnext',
51-
})
52-
} catch (error) {
53-
console.error(error)
54-
return
55-
}
56-
57-
console.log('...done')
58-
}
59-
6077
try {
6178
watcher
6279
.on('change', (path) => {
6380
console.log(`File ${path} has been changed`)
64-
update()
81+
updateWatchedFiles(watcher, base)
6582
})
6683
.on('add', (path) => {
6784
console.log(`File ${path} has been added`)
68-
update()
85+
updateWatchedFiles(watcher, base)
6986
})
7087
.on('unlink', (path) => {
7188
console.log(`File ${path} has been removed`)
72-
update()
89+
updateWatchedFiles(watcher, base)
7390
})
7491
.on('ready', () => {
7592
console.log('Initial scan complete. Ready for changes')
7693
// This only happens on the first scan
77-
update(true)
94+
updateWatchedFiles(watcher, base, true)
7895
})
7996
await new Promise((resolve) => {
8097
watcher.on('close', resolve)

0 commit comments

Comments
 (0)