No 👏 more 👏 server 👏 restarts 👏 on 👏 config 👏 changes (#4578)

* feat: restart config on add, remove, update

* fix: reload for root project configs only

* fix: throw when userConfigPath can't resolve

* chore: changeset

* wip: remove normalizePath before writeFile

* refactor: invalidateWithCache -> isConfigReload

* wip: mustExist?

* debug: config loaded successfully

* debug: more logs

* debug: MORE logging

* fix: normalize resolved config path

* debug: yet MORE logging

* chore: bump proload

* fix: use file path, not URL.pathname

* Revert "wip: mustExist?"

This reverts commit 8ca8662132532dcdc9fd120868e615ddc60f498e.

* chore: remove console log

* feat: cleanup restart message, better invalid config handling

* chore: update lockfile

* chore: fix types

* fix: throw helpful error when config does not exist

* docs: remove "restart dev server" from integrations

* docs: make sure to restart -> try restarting

Co-authored-by: Nate Moore <nate@astro.build>
This commit is contained in:
Ben Holmes 2022-09-09 11:58:16 -04:00 committed by GitHub
parent b6dd8b595c
commit c706d845eb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 153 additions and 122 deletions

View file

@ -0,0 +1,5 @@
---
'astro': minor
---
Restart dev server when config file is added, updated, or removed

View file

@ -106,7 +106,7 @@
"@babel/plugin-transform-react-jsx": "^7.17.12", "@babel/plugin-transform-react-jsx": "^7.17.12",
"@babel/traverse": "^7.18.2", "@babel/traverse": "^7.18.2",
"@babel/types": "^7.18.4", "@babel/types": "^7.18.4",
"@proload/core": "^0.3.2", "@proload/core": "^0.3.3",
"@proload/plugin-tsm": "^0.2.1", "@proload/plugin-tsm": "^0.2.1",
"@types/babel__core": "^7.1.19", "@types/babel__core": "^7.1.19",
"@types/html-escaper": "^3.0.0", "@types/html-escaper": "^3.0.0",

View file

@ -1,14 +1,15 @@
/* eslint-disable no-console */ /* eslint-disable no-console */
import type { Arguments as Flags } from 'yargs-parser'
import * as colors from 'kleur/colors'; import * as colors from 'kleur/colors';
import yargs from 'yargs-parser'; import yargs from 'yargs-parser';
import { z } from 'zod'; import { z } from 'zod';
import { normalizePath } from 'vite';
import add from '../core/add/index.js'; import add from '../core/add/index.js';
import build from '../core/build/index.js'; import build from '../core/build/index.js';
import { openConfig } from '../core/config.js'; import { openConfig, resolveConfigPath, resolveFlags, resolveRoot } from '../core/config.js';
import devServer from '../core/dev/index.js'; import devServer from '../core/dev/index.js';
import { collectErrorMetadata } from '../core/errors.js'; import { collectErrorMetadata } from '../core/errors.js';
import { debug, info, LogOptions, warn } from '../core/logger/core.js'; import { debug, error, info, LogOptions, warn } from '../core/logger/core.js';
import { enableVerboseLogging, nodeLogDestination } from '../core/logger/node.js'; import { enableVerboseLogging, nodeLogDestination } from '../core/logger/node.js';
import { formatConfigErrorMessage, formatErrorMessage, printHelp } from '../core/messages.js'; import { formatConfigErrorMessage, formatErrorMessage, printHelp } from '../core/messages.js';
import preview from '../core/preview/index.js'; import preview from '../core/preview/index.js';
@ -18,6 +19,8 @@ import { eventConfigError, eventError, telemetry } from '../events/index.js';
import { check } from './check/index.js'; import { check } from './check/index.js';
import { openInBrowser } from './open.js'; import { openInBrowser } from './open.js';
import * as telemetryHandler from './telemetry.js'; import * as telemetryHandler from './telemetry.js';
import { appendForwardSlash } from '../core/path.js';
import { pathToFileURL } from 'url'
type Arguments = yargs.Arguments; type Arguments = yargs.Arguments;
type CLICommand = type CLICommand =
@ -81,6 +84,16 @@ function resolveCommand(flags: Arguments): CLICommand {
return 'help'; return 'help';
} }
async function handleConfigError(e: any, { cwd, flags, logging }: { cwd?: string; flags?: Flags, logging: LogOptions }) {
const path = await resolveConfigPath({ cwd, flags });
if (e instanceof Error) {
if (path) {
error(logging, 'astro', `Unable to load ${colors.bold(path)}\n`);
}
console.error(formatErrorMessage(collectErrorMetadata(e, path ? pathToFileURL(path) : undefined)) + '\n')
}
}
/** /**
* Run the given command with the given flags. * Run the given command with the given flags.
* NOTE: This function provides no error handling, so be sure * NOTE: This function provides no error handling, so be sure
@ -132,12 +145,16 @@ async function runCommand(cmd: string, flags: yargs.Arguments) {
} }
} }
let { astroConfig, userConfig, userConfigPath } = await openConfig({ let { astroConfig, userConfig } = await openConfig({
cwd: root, cwd: root,
flags, flags,
cmd, cmd,
logging, logging,
}); }).catch(async (e) => {
await handleConfigError(e, { cwd: root, flags, logging })
return {} as any;
});
if (!astroConfig) return;
telemetry.record(event.eventCliSession(cmd, userConfig, flags)); telemetry.record(event.eventCliSession(cmd, userConfig, flags));
// Common CLI Commands: // Common CLI Commands:
@ -145,33 +162,56 @@ async function runCommand(cmd: string, flags: yargs.Arguments) {
// by the end of this switch statement. // by the end of this switch statement.
switch (cmd) { switch (cmd) {
case 'dev': { case 'dev': {
async function startDevServer() { async function startDevServer({ isRestart = false }: { isRestart?: boolean } = {}) {
const { watcher, stop } = await devServer(astroConfig, { logging, telemetry }); const { watcher, stop } = await devServer(astroConfig, { logging, telemetry, isRestart });
let restartInFlight = false;
const configFlag = resolveFlags(flags).config;
const configFlagPath = configFlag
? await resolveConfigPath({ cwd: root, flags })
: undefined;
const resolvedRoot = appendForwardSlash(resolveRoot(root));
watcher.on('change', logRestartServerOnConfigChange); const handleServerRestart = (logMsg: string) =>
watcher.on('unlink', logRestartServerOnConfigChange); async function (changedFile: string) {
function logRestartServerOnConfigChange(changedFile: string) { if (
if (userConfigPath === changedFile) { !restartInFlight &&
warn(logging, 'astro', 'Astro config updated. Restart server to see changes!'); (configFlag
} ? // If --config is specified, only watch changes for this file
} configFlagPath && normalizePath(configFlagPath) === normalizePath(changedFile)
: // Otherwise, watch for any astro.config.* file changes in project root
new RegExp(
`${normalizePath(resolvedRoot)}.*astro\.config\.((mjs)|(cjs)|(js)|(ts))$`
).test(normalizePath(changedFile)))
) {
restartInFlight = true;
console.clear()
try {
const newConfig = await openConfig({
cwd: root,
flags,
cmd,
logging,
isConfigReload: true,
});
info(logging, 'astro', logMsg + '\n');
astroConfig = newConfig.astroConfig;
await stop();
await startDevServer({ isRestart: true });
} catch (e) {
await handleConfigError(e, { cwd: root, flags, logging })
await stop();
info(logging, 'astro', 'Continuing with previous valid configuration\n');
await startDevServer({ isRestart: true });
watcher.on('add', async function restartServerOnNewConfigFile(addedFile: string) { }
// if there was not a config before, attempt to resolve
if (!userConfigPath && addedFile.includes('astro.config')) {
const addedConfig = await openConfig({ cwd: root, flags, cmd, logging });
if (addedConfig.userConfigPath) {
info(logging, 'astro', 'Astro config detected. Restarting server...');
astroConfig = addedConfig.astroConfig;
userConfig = addedConfig.userConfig;
userConfigPath = addedConfig.userConfigPath;
await stop();
await startDevServer();
} }
} };
});
watcher.on('change', handleServerRestart('Configuration updated. Restarting...'));
watcher.on('unlink', handleServerRestart('Configuration removed. Restarting...'));
watcher.on('add', handleServerRestart('Configuration added. Restarting...'));
} }
await startDevServer(); await startDevServer({ isRestart: false });
return await new Promise(() => {}); // lives forever return await new Promise(() => {}); // lives forever
} }

View file

@ -10,7 +10,7 @@ import preferredPM from 'preferred-pm';
import prompts from 'prompts'; import prompts from 'prompts';
import { fileURLToPath, pathToFileURL } from 'url'; import { fileURLToPath, pathToFileURL } from 'url';
import type yargs from 'yargs-parser'; import type yargs from 'yargs-parser';
import { resolveConfigURL } from '../config.js'; import { resolveConfigPath } from '../config.js';
import { debug, info, LogOptions } from '../logger/core.js'; import { debug, info, LogOptions } from '../logger/core.js';
import * as msg from '../messages.js'; import * as msg from '../messages.js';
import { printHelp } from '../messages.js'; import { printHelp } from '../messages.js';
@ -97,7 +97,8 @@ export default async function add(names: string[], { cwd, flags, logging, teleme
} }
let configURL: URL | undefined; let configURL: URL | undefined;
const root = pathToFileURL(cwd ? path.resolve(cwd) : process.cwd()); const root = pathToFileURL(cwd ? path.resolve(cwd) : process.cwd());
configURL = await resolveConfigURL({ cwd, flags }); const rawConfigPath = await resolveConfigPath({ cwd, flags });
configURL = rawConfigPath ? pathToFileURL(rawConfigPath) : undefined;
applyPolyfill(); applyPolyfill();
if (configURL) { if (configURL) {

View file

@ -3,6 +3,7 @@ import type * as Postcss from 'postcss';
import type { ILanguageRegistration, IThemeRegistration, Theme } from 'shiki'; import type { ILanguageRegistration, IThemeRegistration, Theme } from 'shiki';
import type { Arguments as Flags } from 'yargs-parser'; import type { Arguments as Flags } from 'yargs-parser';
import type { AstroConfig, AstroUserConfig, CLIFlags, ViteUserConfig } from '../@types/astro'; import type { AstroConfig, AstroUserConfig, CLIFlags, ViteUserConfig } from '../@types/astro';
import fs from 'fs';
import load, { ProloadError, resolve } from '@proload/core'; import load, { ProloadError, resolve } from '@proload/core';
import loadTypeScript from '@proload/plugin-tsm'; import loadTypeScript from '@proload/plugin-tsm';
@ -361,7 +362,7 @@ export async function validateConfig(
} }
/** Convert the generic "yargs" flag object into our own, custom TypeScript object. */ /** Convert the generic "yargs" flag object into our own, custom TypeScript object. */
function resolveFlags(flags: Partial<Flags>): CLIFlags { export function resolveFlags(flags: Partial<Flags>): CLIFlags {
return { return {
root: typeof flags.root === 'string' ? flags.root : undefined, root: typeof flags.root === 'string' ? flags.root : undefined,
site: typeof flags.site === 'string' ? flags.site : undefined, site: typeof flags.site === 'string' ? flags.site : undefined,
@ -373,6 +374,10 @@ function resolveFlags(flags: Partial<Flags>): CLIFlags {
}; };
} }
export function resolveRoot(cwd?: string): string {
return cwd ? path.resolve(cwd) : process.cwd();
}
/** Merge CLI flags & user config object (CLI flags take priority) */ /** Merge CLI flags & user config object (CLI flags take priority) */
function mergeCLIFlags(astroConfig: AstroUserConfig, flags: CLIFlags, cmd: string) { function mergeCLIFlags(astroConfig: AstroUserConfig, flags: CLIFlags, cmd: string) {
astroConfig.server = astroConfig.server || {}; astroConfig.server = astroConfig.server || {};
@ -398,6 +403,8 @@ interface LoadConfigOptions {
cmd: string; cmd: string;
validate?: boolean; validate?: boolean;
logging: LogOptions; logging: LogOptions;
/** Invalidate when reloading a previously loaded config */
isConfigReload?: boolean;
} }
/** /**
@ -405,10 +412,10 @@ interface LoadConfigOptions {
* Note: currently the same as loadConfig but only returns the `filePath` * Note: currently the same as loadConfig but only returns the `filePath`
* instead of the resolved config * instead of the resolved config
*/ */
export async function resolveConfigURL( export async function resolveConfigPath(
configOptions: Pick<LoadConfigOptions, 'cwd' | 'flags'> configOptions: Pick<LoadConfigOptions, 'cwd' | 'flags'>
): Promise<URL | undefined> { ): Promise<string | undefined> {
const root = configOptions.cwd ? path.resolve(configOptions.cwd) : process.cwd(); const root = resolveRoot(configOptions.cwd);
const flags = resolveFlags(configOptions.flags || {}); const flags = resolveFlags(configOptions.flags || {});
let userConfigPath: string | undefined; let userConfigPath: string | undefined;
@ -419,19 +426,23 @@ export async function resolveConfigURL(
// Resolve config file path using Proload // Resolve config file path using Proload
// If `userConfigPath` is `undefined`, Proload will search for `astro.config.[cm]?[jt]s` // If `userConfigPath` is `undefined`, Proload will search for `astro.config.[cm]?[jt]s`
const configPath = await resolve('astro', { try {
mustExist: false, const configPath = await resolve('astro', {
cwd: root, mustExist: !!userConfigPath,
filePath: userConfigPath, cwd: root,
}); filePath: userConfigPath,
if (configPath) { });
return pathToFileURL(configPath); return configPath;
} catch (e) {
if (e instanceof ProloadError && flags.config) {
throw new Error(`Unable to resolve --config "${flags.config}"! Does the file exist?`);
}
throw e
} }
} }
interface OpenConfigResult { interface OpenConfigResult {
userConfig: AstroUserConfig; userConfig: AstroUserConfig;
userConfigPath: string | undefined;
astroConfig: AstroConfig; astroConfig: AstroConfig;
flags: CLIFlags; flags: CLIFlags;
root: string; root: string;
@ -439,22 +450,13 @@ interface OpenConfigResult {
/** Load a configuration file, returning both the userConfig and astroConfig */ /** Load a configuration file, returning both the userConfig and astroConfig */
export async function openConfig(configOptions: LoadConfigOptions): Promise<OpenConfigResult> { export async function openConfig(configOptions: LoadConfigOptions): Promise<OpenConfigResult> {
const root = configOptions.cwd ? path.resolve(configOptions.cwd) : process.cwd(); const root = resolveRoot(configOptions.cwd);
const flags = resolveFlags(configOptions.flags || {}); const flags = resolveFlags(configOptions.flags || {});
let userConfig: AstroUserConfig = {}; let userConfig: AstroUserConfig = {};
let userConfigPath: string | undefined;
if (flags?.config) { const config = await tryLoadConfig(configOptions, flags, root);
userConfigPath = /^\.*\//.test(flags.config) ? flags.config : `./${flags.config}`;
userConfigPath = fileURLToPath(
new URL(userConfigPath, appendForwardSlash(pathToFileURL(root).toString()))
);
}
const config = await tryLoadConfig(configOptions, flags, userConfigPath, root);
if (config) { if (config) {
userConfig = config.value; userConfig = config.value;
userConfigPath = config.filePath;
} }
const astroConfig = await resolveConfig( const astroConfig = await resolveConfig(
userConfig, userConfig,
@ -467,7 +469,6 @@ export async function openConfig(configOptions: LoadConfigOptions): Promise<Open
return { return {
astroConfig, astroConfig,
userConfig, userConfig,
userConfigPath,
flags, flags,
root, root,
}; };
@ -481,16 +482,37 @@ interface TryLoadConfigResult {
async function tryLoadConfig( async function tryLoadConfig(
configOptions: LoadConfigOptions, configOptions: LoadConfigOptions,
flags: CLIFlags, flags: CLIFlags,
userConfigPath: string | undefined,
root: string root: string
): Promise<TryLoadConfigResult | undefined> { ): Promise<TryLoadConfigResult | undefined> {
let finallyCleanup = async () => {};
try { try {
// Automatically load config file using Proload let configPath = await resolveConfigPath({
// If `userConfigPath` is `undefined`, Proload will search for `astro.config.[cm]?[jt]s` cwd: configOptions.cwd,
flags: configOptions.flags,
});
if (!configPath) return undefined;
if (configOptions.isConfigReload) {
// Hack: Write config to temporary file at project root
// This invalidates and reloads file contents when using ESM imports or "resolve"
const tempConfigPath = path.join(
root,
`.temp.${Date.now()}.config${path.extname(configPath)}`
);
await fs.promises.writeFile(tempConfigPath, await fs.promises.readFile(configPath));
finallyCleanup = async () => {
try {
await fs.promises.unlink(tempConfigPath);
} catch {
/** file already removed */
}
};
configPath = tempConfigPath;
}
const config = await load('astro', { const config = await load('astro', {
mustExist: !!userConfigPath, mustExist: !!configPath,
cwd: root, cwd: root,
filePath: userConfigPath, filePath: configPath,
}); });
return config as TryLoadConfigResult; return config as TryLoadConfigResult;
@ -499,28 +521,32 @@ async function tryLoadConfig(
throw new Error(`Unable to resolve --config "${flags.config}"! Does the file exist?`); throw new Error(`Unable to resolve --config "${flags.config}"! Does the file exist?`);
} }
const configURL = await resolveConfigURL(configOptions); const configPath = await resolveConfigPath(configOptions);
if (!configURL) { if (!configPath) {
throw e; throw e;
} }
// Fallback to use Vite DevServer // Fallback to use Vite DevServer
const viteServer = await vite.createServer({ const viteServer = await vite.createServer({
server: { middlewareMode: true, hmr: false }, server: { middlewareMode: true, hmr: false },
optimizeDeps: { entries: [] },
clearScreen: false,
appType: 'custom', appType: 'custom',
}); });
try { try {
const mod = await viteServer.ssrLoadModule(fileURLToPath(configURL)); const mod = await viteServer.ssrLoadModule(configPath);
if (mod?.default) { if (mod?.default) {
return { return {
value: mod.default, value: mod.default,
filePath: fileURLToPath(configURL), filePath: configPath,
}; };
} }
} finally { } finally {
await viteServer.close(); await viteServer.close();
} }
} finally {
await finallyCleanup();
} }
} }
@ -529,19 +555,11 @@ async function tryLoadConfig(
* @deprecated * @deprecated
*/ */
export async function loadConfig(configOptions: LoadConfigOptions): Promise<AstroConfig> { export async function loadConfig(configOptions: LoadConfigOptions): Promise<AstroConfig> {
const root = configOptions.cwd ? path.resolve(configOptions.cwd) : process.cwd(); const root = resolveRoot(configOptions.cwd);
const flags = resolveFlags(configOptions.flags || {}); const flags = resolveFlags(configOptions.flags || {});
let userConfig: AstroUserConfig = {}; let userConfig: AstroUserConfig = {};
let userConfigPath: string | undefined;
if (flags?.config) { const config = await tryLoadConfig(configOptions, flags, root);
userConfigPath = /^\.*\//.test(flags.config) ? flags.config : `./${flags.config}`;
userConfigPath = fileURLToPath(
new URL(userConfigPath, appendForwardSlash(pathToFileURL(root).toString()))
);
}
const config = await tryLoadConfig(configOptions, flags, userConfigPath, root);
if (config) { if (config) {
userConfig = config.value; userConfig = config.value;
} }

View file

@ -18,6 +18,7 @@ import { apply as applyPolyfill } from '../polyfill.js';
export interface DevOptions { export interface DevOptions {
logging: LogOptions; logging: LogOptions;
telemetry: AstroTelemetry; telemetry: AstroTelemetry;
isRestart?: boolean;
} }
export interface DevServer { export interface DevServer {
@ -33,6 +34,7 @@ export default async function dev(config: AstroConfig, options: DevOptions): Pro
await options.telemetry.record([]); await options.telemetry.record([]);
config = await runHookConfigSetup({ config, command: 'dev', logging: options.logging }); config = await runHookConfigSetup({ config, command: 'dev', logging: options.logging });
const { host, port } = config.server; const { host, port } = config.server;
const { isRestart = false } = options;
// The client entrypoint for renderers. Since these are imported dynamically // The client entrypoint for renderers. Since these are imported dynamically
// we need to tell Vite to preoptimize them. // we need to tell Vite to preoptimize them.
@ -66,6 +68,7 @@ export default async function dev(config: AstroConfig, options: DevOptions): Pro
devServerAddressInfo, devServerAddressInfo,
site, site,
https: !!viteConfig.server?.https, https: !!viteConfig.server?.https,
isRestart
}) })
); );

View file

@ -58,12 +58,14 @@ export function devStart({
config, config,
https, https,
site, site,
isRestart = false
}: { }: {
startupTime: number; startupTime: number;
devServerAddressInfo: AddressInfo; devServerAddressInfo: AddressInfo;
config: AstroConfig; config: AstroConfig;
https: boolean; https: boolean;
site: URL | undefined; site: URL | undefined;
isRestart?: boolean
}): string { }): string {
// PACKAGE_VERSION is injected at build-time // PACKAGE_VERSION is injected at build-time
const version = process.env.PACKAGE_VERSION ?? '0.0.0'; const version = process.env.PACKAGE_VERSION ?? '0.0.0';
@ -106,7 +108,7 @@ export function devStart({
const messages = [ const messages = [
`${emoji('🚀 ', '')}${bgGreen(black(` astro `))} ${green(`v${version}`)} ${dim( `${emoji('🚀 ', '')}${bgGreen(black(` astro `))} ${green(`v${version}`)} ${dim(
`started in ${Math.round(startupTime)}ms` `${isRestart ? 're' : ''}started in ${Math.round(startupTime)}ms`
)}`, )}`,
'', '',
local, local,

View file

@ -125,6 +125,7 @@ export async function handleHotUpdate(
// TODO: Svelte files should be marked as `isSelfAccepting` but they don't appear to be // TODO: Svelte files should be marked as `isSelfAccepting` but they don't appear to be
const isSelfAccepting = mods.every((m) => m.isSelfAccepting || m.url.endsWith('.svelte')); const isSelfAccepting = mods.every((m) => m.isSelfAccepting || m.url.endsWith('.svelte'));
if (isSelfAccepting) { if (isSelfAccepting) {
if (/astro\.config\.[cm][jt]s$/.test(file)) return mods;
info(logging, 'astro', msg.hmr({ file })); info(logging, 'astro', msg.hmr({ file }));
} else { } else {
info(logging, 'astro', msg.reload({ file })); info(logging, 'astro', msg.reload({ file }));

View file

@ -25,8 +25,6 @@ yarn astro add alpinejs
pnpm astro add alpinejs pnpm astro add alpinejs
``` ```
Finally, in the terminal window running Astro, press `CTRL+C` and then restart the dev server.
If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below. If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
### Manual Install ### Manual Install
@ -56,8 +54,6 @@ export default defineConfig({
}); });
``` ```
Finally, restart the dev server.
## Usage ## Usage
Once the integration is installed, you can use [Alpine.js](https://alpinejs.dev/) directives and syntax inside any Astro component. The Alpine.js script is automatically added and enabled on every page of your website. Once the integration is installed, you can use [Alpine.js](https://alpinejs.dev/) directives and syntax inside any Astro component. The Alpine.js script is automatically added and enabled on every page of your website.

View file

@ -36,8 +36,6 @@ yarn astro add image
pnpm astro add image pnpm astro add image
``` ```
Finally, in the terminal window running Astro, press `CTRL+C` and then restart the dev server.
If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below. If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
### Manual Install ### Manual Install
@ -58,7 +56,6 @@ export default {
integrations: [image()], integrations: [image()],
} }
``` ```
Then, restart the dev server.
### Update `env.d.ts` ### Update `env.d.ts`
@ -469,7 +466,7 @@ const imageUrl = 'https://www.google.com/images/branding/googlelogo/2x/googlelog
``` ```
## Troubleshooting ## Troubleshooting
- If your installation doesn't seem to be working, make sure to restart the dev server. - If your installation doesn't seem to be working, try restarting the dev server.
- If you edit and save a file and don't see your site update accordingly, try refreshing the page. - If you edit and save a file and don't see your site update accordingly, try refreshing the page.
- If refreshing the page doesn't update your preview, or if a new installation doesn't seem to be working, then restart the dev server. - If refreshing the page doesn't update your preview, or if a new installation doesn't seem to be working, then restart the dev server.

View file

@ -23,8 +23,6 @@ yarn astro add lit
pnpm astro add lit pnpm astro add lit
``` ```
Finally, in the terminal window running Astro, press `CTRL+C` and then restart the dev server.
If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below. If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
### Install dependencies manually ### Install dependencies manually

View file

@ -33,8 +33,6 @@ yarn astro add mdx
pnpm astro add mdx pnpm astro add mdx
``` ```
Finally, in the terminal window running Astro, press `CTRL+C` and then restart the dev server.
If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below. If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
### Manual Install ### Manual Install
@ -59,8 +57,6 @@ export default defineConfig({
}); });
``` ```
Finally, restart the dev server.
## Usage ## Usage
You can [add MDX pages to your project](https://docs.astro.build/en/guides/markdown-content/#markdown-and-mdx-pages) by adding `.mdx` files within your `src/pages/` directory. You can [add MDX pages to your project](https://docs.astro.build/en/guides/markdown-content/#markdown-and-mdx-pages) by adding `.mdx` files within your `src/pages/` directory.

View file

@ -35,8 +35,6 @@ yarn astro add partytown
pnpm astro add partytown pnpm astro add partytown
``` ```
Finally, in the terminal window running Astro, press `CTRL+C` and then restart the dev server.
If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below. If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
### Manual Install ### Manual Install
@ -59,7 +57,6 @@ export default defineConfig({
}) })
``` ```
Then, restart the dev server.
## Usage ## Usage

View file

@ -35,8 +35,6 @@ yarn astro add preact
pnpm astro add preact pnpm astro add preact
``` ```
Finally, in the terminal window running Astro, press `CTRL+C` and then restart the dev server.
If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below. If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
### Manual Install ### Manual Install
@ -67,8 +65,6 @@ export default defineConfig({
}); });
``` ```
Finally, restart the dev server.
## Usage ## Usage
To use your first Preact component in Astro, head to our [UI framework documentation][astro-ui-frameworks]. You'll explore: To use your first Preact component in Astro, head to our [UI framework documentation][astro-ui-frameworks]. You'll explore:

View file

@ -29,8 +29,6 @@ yarn astro add prefetch
pnpm astro add prefetch pnpm astro add prefetch
``` ```
Finally, in the terminal window running Astro, press `CTRL+C` and then restart the dev server.
If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below. If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
### Manual Install ### Manual Install
@ -52,7 +50,6 @@ export default {
} }
``` ```
Then, restart the dev server.
## Usage ## Usage
@ -94,7 +91,7 @@ export default {
``` ```
## Troubleshooting ## Troubleshooting
- If your installation doesn't seem to be working, make sure to restart the dev server. - If your installation doesn't seem to be working, try restarting the dev server.
- If a link doesn't seem to be prefetching, make sure that the link is pointing to a page on the same domain and matches the integration's `selector` option. - If a link doesn't seem to be prefetching, make sure that the link is pointing to a page on the same domain and matches the integration's `selector` option.
For help, check out the `#support-threads` channel on [Discord](https://astro.build/chat). Our friendly Support Squad members are here to help! For help, check out the `#support-threads` channel on [Discord](https://astro.build/chat). Our friendly Support Squad members are here to help!

View file

@ -23,8 +23,6 @@ yarn astro add react
pnpm astro add react pnpm astro add react
``` ```
Finally, in the terminal window running Astro, press `CTRL+C` and then restart the dev server.
If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below. If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
### Install dependencies manually ### Install dependencies manually

View file

@ -35,8 +35,6 @@ yarn astro add sitemap
pnpm astro add sitemap pnpm astro add sitemap
``` ```
Finally, in the terminal window running Astro, press `CTRL+C` and then restart the dev server.
If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below. If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
### Manual Install ### Manual Install
@ -59,7 +57,6 @@ export default defineConfig({
}) })
``` ```
Then, restart the dev server.
## Usage ## Usage

View file

@ -23,8 +23,6 @@ yarn astro add solid
pnpm astro add solid pnpm astro add solid
``` ```
Finally, in the terminal window running Astro, press `CTRL+C` and then restart the dev server.
If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below. If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
### Install dependencies manually ### Install dependencies manually

View file

@ -23,8 +23,6 @@ yarn astro add svelte
pnpm astro add svelte pnpm astro add svelte
``` ```
Finally, in the terminal window running Astro, press `CTRL+C` and then restart the dev server.
If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below. If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
### Install dependencies manually ### Install dependencies manually

View file

@ -38,8 +38,6 @@ yarn astro add tailwind
pnpm astro add tailwind pnpm astro add tailwind
``` ```
Finally, in the terminal window running Astro, press `CTRL+C` and then restart the dev server.
If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below. If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
### Manual Install ### Manual Install
@ -61,7 +59,6 @@ export default {
} }
``` ```
Then, restart the dev server.
## Usage ## Usage
@ -154,7 +151,7 @@ module.exports = {
- [Browse Astro Tailwind projects on GitHub](https://github.com/search?q=%22%40astrojs%2Ftailwind%22+filename%3Apackage.json&type=Code) for more examples! - [Browse Astro Tailwind projects on GitHub](https://github.com/search?q=%22%40astrojs%2Ftailwind%22+filename%3Apackage.json&type=Code) for more examples!
## Troubleshooting ## Troubleshooting
- If your installation doesn't seem to be working, make sure to restart the dev server. - If your installation doesn't seem to be working, try restarting the dev server.
- If you edit and save a file and don't see your site update accordingly, try refreshing the page. - If you edit and save a file and don't see your site update accordingly, try refreshing the page.
- If refreshing the page doesn't update your preview, or if a new installation doesn't seem to be working, then restart the dev server. - If refreshing the page doesn't update your preview, or if a new installation doesn't seem to be working, then restart the dev server.

View file

@ -33,8 +33,6 @@ yarn astro add turbolinks
pnpm astro add turbolinks pnpm astro add turbolinks
``` ```
Finally, in the terminal window running Astro, press `CTRL+C` and then restart the dev server.
If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below. If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
### Install dependencies manually ### Install dependencies manually

View file

@ -23,8 +23,6 @@ yarn astro add vue
pnpm astro add vue pnpm astro add vue
``` ```
Finally, in the terminal window running Astro, press `CTRL+C` and then restart the dev server.
If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below. If you run into any issues, [feel free to report them to us on GitHub](https://github.com/withastro/astro/issues) and try the manual installation steps below.
### Install dependencies manually ### Install dependencies manually

View file

@ -350,7 +350,7 @@ importers:
'@babel/traverse': ^7.18.2 '@babel/traverse': ^7.18.2
'@babel/types': ^7.18.4 '@babel/types': ^7.18.4
'@playwright/test': ^1.22.2 '@playwright/test': ^1.22.2
'@proload/core': ^0.3.2 '@proload/core': ^0.3.3
'@proload/plugin-tsm': ^0.2.1 '@proload/plugin-tsm': ^0.2.1
'@types/babel__core': ^7.1.19 '@types/babel__core': ^7.1.19
'@types/babel__generator': ^7.6.4 '@types/babel__generator': ^7.6.4