-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
index.ts
79 lines (72 loc) · 3.3 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import fs from 'node:fs';
import { createRequire } from 'node:module';
import { fileURLToPath, pathToFileURL } from 'node:url';
import type { AstroInlineConfig, PreviewModule, PreviewServer } from '../../@types/astro.js';
import { AstroIntegrationLogger } from '../../core/logger/core.js';
import { telemetry } from '../../events/index.js';
import { eventCliSession } from '../../events/session.js';
import { runHookConfigDone, runHookConfigSetup } from '../../integrations/index.js';
import { resolveConfig } from '../config/config.js';
import { createNodeLogger } from '../config/logging.js';
import { createSettings } from '../config/settings.js';
import createStaticPreviewServer from './static-preview-server.js';
import { getResolvedHostForHttpServer } from './util.js';
import { ensureProcessNodeEnv } from '../util.js';
/**
* Starts a local server to serve your static dist/ directory. This command is useful for previewing
* your build locally, before deploying it. It is not designed to be run in production.
*
* @experimental The JavaScript API is experimental
*/
export default async function preview(inlineConfig: AstroInlineConfig): Promise<PreviewServer> {
ensureProcessNodeEnv('production');
const logger = createNodeLogger(inlineConfig);
const { userConfig, astroConfig } = await resolveConfig(inlineConfig ?? {}, 'preview');
telemetry.record(eventCliSession('preview', userConfig));
const _settings = await createSettings(astroConfig, fileURLToPath(astroConfig.root));
const settings = await runHookConfigSetup({
settings: _settings,
command: 'preview',
logger: logger,
});
await runHookConfigDone({ settings: settings, logger: logger });
if (settings.config.output === 'static') {
if (!fs.existsSync(settings.config.outDir)) {
const outDirPath = fileURLToPath(settings.config.outDir);
throw new Error(
`[preview] The output directory ${outDirPath} does not exist. Did you run \`astro build\`?`
);
}
const server = await createStaticPreviewServer(settings, logger);
return server;
}
if (!settings.adapter) {
throw new Error(`[preview] No adapter found.`);
}
if (!settings.adapter.previewEntrypoint) {
throw new Error(
`[preview] The ${settings.adapter.name} adapter does not support the preview command.`
);
}
// We need to use require.resolve() here so that advanced package managers like pnpm
// don't treat this as a dependency of Astro itself. This correctly resolves the
// preview entrypoint of the integration package, relative to the user's project root.
const require = createRequire(settings.config.root);
const previewEntrypointUrl = pathToFileURL(
require.resolve(settings.adapter.previewEntrypoint)
).href;
const previewModule = (await import(previewEntrypointUrl)) as Partial<PreviewModule>;
if (typeof previewModule.default !== 'function') {
throw new Error(`[preview] ${settings.adapter.name} cannot preview your app.`);
}
const server = await previewModule.default({
outDir: settings.config.outDir,
client: settings.config.build.client,
serverEntrypoint: new URL(settings.config.build.serverEntry, settings.config.build.server),
host: getResolvedHostForHttpServer(settings.config.server.host),
port: settings.config.server.port,
base: settings.config.base,
logger: new AstroIntegrationLogger(logger.options, settings.adapter.name),
});
return server;
}