Skip to content

Commit 7b1bc45

Browse files
committed
fix: move watcher into subprocess
1 parent 0eb9eb1 commit 7b1bc45

File tree

2 files changed

+88
-76
lines changed

2 files changed

+88
-76
lines changed

packages/runtime/src/helpers/dev.ts

Lines changed: 5 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,11 @@
1-
import { promises } from 'fs'
21
import { join } from 'path'
32

4-
import { OnPreBuild } from '@netlify/build'
5-
import { build } from '@netlify/esbuild'
6-
import { watch } from 'chokidar'
3+
import type { OnPreBuild } from '@netlify/build'
4+
import execa from 'execa'
75

86
import { writeDevEdgeFunction } from './edge'
97
import { patchNextFiles } from './files'
108

11-
const fileList = (watched: Record<string, Array<string>>) =>
12-
Object.entries(watched).flatMap(([dir, files]) => files.map((file) => `${dir}/${file}`))
13-
14-
let watcher
15-
169
// The types haven't been updated yet
1710
export const onPreDev: OnPreBuild = async ({ constants, netlifyConfig }) => {
1811
const base = netlifyConfig.build.base ?? process.cwd()
@@ -21,72 +14,8 @@ export const onPreDev: OnPreBuild = async ({ constants, netlifyConfig }) => {
2114
await patchNextFiles(base)
2215

2316
await writeDevEdgeFunction(constants)
24-
25-
watcher = watch(['middleware.js', 'middleware.ts', 'src/middleware.js', 'src/middleware.ts'], {
26-
persistent: true,
27-
atomic: true,
28-
ignoreInitial: true,
29-
cwd: base,
30-
})
31-
32-
const update = async (initial = false) => {
33-
try {
34-
await promises.unlink(join(base, '.netlify', 'middleware.js'))
35-
} catch {}
36-
37-
const watchedFiles = fileList(watcher.getWatched())
38-
if (watchedFiles.length === 0) {
39-
if (!initial) {
40-
console.log('No middleware found')
41-
}
42-
return
43-
}
44-
if (watchedFiles.length > 1) {
45-
console.log('Multiple middleware files found:')
46-
console.log(watchedFiles.join('\n'))
47-
console.log('This is not supported.')
48-
49-
return
50-
}
51-
console.log(`${initial ? 'Building' : 'Rebuilding'} middleware ${watchedFiles[0]}...`)
52-
try {
53-
await build({
54-
entryPoints: watchedFiles,
55-
outfile: '.next/middleware.js',
56-
bundle: true,
57-
format: 'esm',
58-
target: 'esnext',
59-
})
60-
} catch (error) {
61-
console.error(error)
62-
return
63-
}
64-
65-
console.log('...done')
66-
}
67-
68-
watcher
69-
.on('change', (path) => {
70-
console.log(`File ${path} has been changed`)
71-
update()
72-
})
73-
.on('add', (path) => {
74-
console.log(`File ${path} has been added`)
75-
update()
76-
})
77-
.on('unlink', (path) => {
78-
console.log(`File ${path} has been removed`)
79-
update()
80-
})
81-
.on('ready', () => {
82-
console.log('Initial scan complete. Ready for changes')
83-
update(true)
84-
})
85-
86-
const promise = new Promise<void>((resolve) => {
87-
process.on('SIGINT', () => {
88-
watcher.close()
89-
resolve()
90-
})
17+
// Don't await this or it will never finish
18+
execa.node(join(__dirname, 'watcher.js'), [base], {
19+
stdio: 'inherit',
9120
})
9221
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { promises } from 'fs'
2+
import { join } from 'path'
3+
4+
import { build } from '@netlify/esbuild'
5+
import { watch } from 'chokidar'
6+
7+
const fileList = (watched: Record<string, Array<string>>) =>
8+
Object.entries(watched).flatMap(([dir, files]) => files.map((file) => `${dir}/${file}`))
9+
10+
const start = async (base: string) => {
11+
const watcher = watch(['middleware.js', 'middleware.ts', 'src/middleware.js', 'src/middleware.ts'], {
12+
atomic: true,
13+
ignoreInitial: true,
14+
cwd: base,
15+
})
16+
17+
const update = async (initial = false) => {
18+
try {
19+
await promises.unlink(join(base, '.netlify', 'middleware.js'))
20+
} catch {}
21+
22+
const watchedFiles = fileList(watcher.getWatched())
23+
if (watchedFiles.length === 0) {
24+
if (!initial) {
25+
console.log('No middleware found')
26+
}
27+
return
28+
}
29+
if (watchedFiles.length > 1) {
30+
console.log('Multiple middleware files found:')
31+
console.log(watchedFiles.join('\n'))
32+
console.log('This is not supported.')
33+
34+
return
35+
}
36+
console.log(`${initial ? 'Building' : 'Rebuilding'} middleware ${watchedFiles[0]}...`)
37+
try {
38+
await build({
39+
entryPoints: watchedFiles,
40+
outfile: join(base, '.netlify', 'middleware.js'),
41+
bundle: true,
42+
format: 'esm',
43+
target: 'esnext',
44+
})
45+
} catch (error) {
46+
console.error(error)
47+
return
48+
}
49+
50+
console.log('...done')
51+
}
52+
53+
try {
54+
watcher
55+
.on('change', (path) => {
56+
console.log(`File ${path} has been changed`)
57+
update()
58+
})
59+
.on('add', (path) => {
60+
console.log(`File ${path} has been added`)
61+
update()
62+
})
63+
.on('unlink', (path) => {
64+
console.log(`File ${path} has been removed`)
65+
update()
66+
})
67+
.on('ready', () => {
68+
console.log('Initial scan complete. Ready for changes')
69+
update(true)
70+
})
71+
await new Promise((resolve) => {
72+
watcher.on('close', resolve)
73+
})
74+
} finally {
75+
await watcher.close()
76+
}
77+
}
78+
79+
start(process.argv[2]).catch((error) => {
80+
console.error(error)
81+
// eslint-disable-next-line n/no-process-exit
82+
process.exit(1)
83+
})

0 commit comments

Comments
 (0)