Skip to content

Commit 8c100a6

Browse files
authored
Handle server restart from Vite plugins (#5849)
1 parent e818cc0 commit 8c100a6

3 files changed

Lines changed: 72 additions & 28 deletions

File tree

.changeset/poor-ladybugs-thank.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'astro': patch
3+
---
4+
5+
Handle server restart from Vite plugins

packages/astro/src/core/dev/restart.ts

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -142,45 +142,53 @@ export async function createContainerWithAutomaticRestart({
142142
},
143143
};
144144

145-
function handleServerRestart(logMsg: string) {
145+
async function handleServerRestart(logMsg: string) {
146146
// eslint-disable-next-line @typescript-eslint/no-shadow
147147
const container = restart.container;
148-
return async function (changedFile: string) {
149-
if (shouldRestartContainer(container, changedFile)) {
150-
const { container: newContainer, error } = await restartContainer({
151-
beforeRestart,
152-
container,
153-
flags,
154-
logMsg,
155-
async handleConfigError(err) {
156-
// Send an error message to the client if one is connected.
157-
await handleConfigError(err);
158-
container.viteServer.ws.send({
159-
type: 'error',
160-
err: {
161-
message: err.message,
162-
stack: err.stack || '',
163-
},
164-
});
148+
const { container: newContainer, error } = await restartContainer({
149+
beforeRestart,
150+
container,
151+
flags,
152+
logMsg,
153+
async handleConfigError(err) {
154+
// Send an error message to the client if one is connected.
155+
await handleConfigError(err);
156+
container.viteServer.ws.send({
157+
type: 'error',
158+
err: {
159+
message: err.message,
160+
stack: err.stack || '',
165161
},
166162
});
167-
restart.container = newContainer;
168-
// Add new watches because this is a new container with a new Vite server
169-
addWatches();
170-
resolveRestart(error);
171-
restartComplete = new Promise<Error | null>((resolve) => {
172-
resolveRestart = resolve;
173-
});
163+
},
164+
});
165+
restart.container = newContainer;
166+
// Add new watches because this is a new container with a new Vite server
167+
addWatches();
168+
resolveRestart(error);
169+
restartComplete = new Promise<Error | null>((resolve) => {
170+
resolveRestart = resolve;
171+
});
172+
}
173+
174+
function handleChangeRestart(logMsg: string) {
175+
return async function (changedFile: string) {
176+
if (shouldRestartContainer(restart.container, changedFile)) {
177+
handleServerRestart(logMsg);
174178
}
175179
};
176180
}
177181

178182
// Set up watches
179183
function addWatches() {
180184
const watcher = restart.container.viteServer.watcher;
181-
watcher.on('change', handleServerRestart('Configuration updated. Restarting...'));
182-
watcher.on('unlink', handleServerRestart('Configuration removed. Restarting...'));
183-
watcher.on('add', handleServerRestart('Configuration added. Restarting...'));
185+
watcher.on('change', handleChangeRestart('Configuration updated. Restarting...'));
186+
watcher.on('unlink', handleChangeRestart('Configuration removed. Restarting...'));
187+
watcher.on('add', handleChangeRestart('Configuration added. Restarting...'));
188+
189+
// Restart the Astro dev server instead of Vite's when the API is called by plugins.
190+
// Ignore the `forceOptimize` parameter for now.
191+
restart.container.viteServer.restart = () => handleServerRestart('Restarting...');
184192
}
185193
addWatches();
186194
return restart;

packages/astro/test/units/dev/restart.test.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,4 +180,35 @@ describe('dev container restarts', () => {
180180
await restart.container.close();
181181
}
182182
});
183+
184+
it('Is able to restart on viteServer.restart API call', async () => {
185+
const fs = createFs(
186+
{
187+
'/src/pages/index.astro': ``,
188+
},
189+
root
190+
);
191+
192+
const { astroConfig } = await openConfig({
193+
cwd: root,
194+
flags: {},
195+
cmd: 'dev',
196+
logging: defaultLogging,
197+
});
198+
const settings = createSettings(astroConfig, fileURLToPath(root));
199+
200+
let restart = await createContainerWithAutomaticRestart({
201+
params: { fs, root, settings },
202+
});
203+
await startContainer(restart.container);
204+
expect(isStarted(restart.container)).to.equal(true);
205+
206+
try {
207+
let restartComplete = restart.restarted();
208+
await restart.container.viteServer.restart();
209+
await restartComplete;
210+
} finally {
211+
await restart.container.close();
212+
}
213+
});
183214
});

0 commit comments

Comments
 (0)