Compare commits

...

2 commits

Author SHA1 Message Date
Fred K. Schott
54c5900a24 wip 2022-06-25 23:26:00 -07:00
Fred K. Schott
ee5b66e298 wip 2022-06-25 22:22:13 -07:00
30 changed files with 242 additions and 15114 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Update "astro add" output to remove confusing multi-select prompt.

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Update the help output to improve formatting

View file

@ -1,4 +1,8 @@
import { defineConfig } from 'astro/config';
import netlify from "@astrojs/netlify";
// https://astro.build/config
export default defineConfig({});
export default defineConfig({
mode: "static",
});

View file

@ -41,6 +41,7 @@
"./package.json": "./package.json",
"./runtime/*": "./dist/runtime/*",
"./server/*": "./dist/runtime/server/*",
"./adapter-node/server.js": "./dist/adapter-node/server.js",
"./vite-plugin-astro": "./dist/vite-plugin-astro/index.js",
"./vite-plugin-astro/*": "./dist/vite-plugin-astro/*",
"./vite-plugin-astro-postprocess": "./dist/vite-plugin-astro-postprocess/index.js",

View file

@ -78,7 +78,6 @@ export interface BuildConfig {
client: URL;
server: URL;
serverEntry: string;
staticMode: boolean | undefined;
}
/**
@ -589,10 +588,15 @@ export interface AstroUserConfig {
* @type {AstroIntegration}
* @default `undefined`
* @description
* @deprecated
* Add an adapter to build for SSR (server-side rendering). An adapter makes it easy to connect a deployed Astro app to a hosting provider or runtime environment.
*/
adapter?: AstroIntegration;
// TODO: Document
mode?: 'static' | 'server';
/**
* @docs
* @kind heading
@ -720,7 +724,7 @@ export interface AstroConfig extends z.output<typeof AstroConfigSchema> {
// This is a more detailed type than zod validation gives us.
// TypeScript still confirms zod validation matches this type.
integrations: AstroIntegration[];
adapter?: AstroIntegration;
// Private:
// We have a need to pass context based on configured state,
// that is different from the user-exposed configuration.

View file

@ -0,0 +1,9 @@
import { AstroAdapter } from "../@types/astro";
export function getGenericNodeAdapter(): AstroAdapter {
return {
name: 'node',
serverEntrypoint: 'astro/adapter-node/server.js',
exports: ['handler'],
};
}

View file

@ -0,0 +1,44 @@
import { polyfill } from '@astrojs/webapi';
import type { IncomingMessage, ServerResponse } from 'http';
import type { Readable } from 'stream';
import { SSRManifest } from '../@types/astro';
import { NodeApp } from '../core/app/node';
polyfill(globalThis, {
exclude: 'window document',
});
export function createExports(manifest: SSRManifest) {
const app = new NodeApp(manifest);
return {
async handler(req: IncomingMessage, res: ServerResponse, next?: (err?: unknown) => void) {
const route = app.match(req);
if (route) {
try {
const response = await app.render(req);
await writeWebResponse(res, response);
} catch (err: unknown) {
if (next) {
next(err);
} else {
throw err;
}
}
} else if (next) {
return next();
}
},
};
}
async function writeWebResponse(res: ServerResponse, webResponse: Response) {
const { status, headers, body } = webResponse;
res.writeHead(status, Object.fromEntries(headers.entries()));
if (body) {
for await (const chunk of body as unknown as Readable) {
res.write(chunk);
}
}
res.end();
}

View file

@ -1,23 +0,0 @@
import type { AstroAdapter, AstroIntegration } from '../@types/astro';
export function getAdapter(): AstroAdapter {
return {
name: '@astrojs/ssg',
// This one has no server entrypoint and is mostly just an integration
//serverEntrypoint: '@astrojs/ssg/server.js',
};
}
export default function createIntegration(): AstroIntegration {
return {
name: '@astrojs/ssg',
hooks: {
'astro:config:done': ({ setAdapter }) => {
setAdapter(getAdapter());
},
'astro:build:start': ({ buildConfig }) => {
buildConfig.staticMode = true;
},
},
};
}

View file

@ -37,26 +37,27 @@ type CLICommand =
function printAstroHelp() {
printHelp({
commandName: 'astro',
usage: '[command] [...flags]',
headline: 'Futuristic web development tool.',
commands: [
['add', 'Add an integration to your configuration.'],
['docs', "Launch Astro's Doc site directly from the terminal. "],
['dev', 'Run Astro in development mode.'],
['build', 'Build a pre-compiled production-ready site.'],
['preview', 'Preview your build locally before deploying.'],
['check', 'Check your project for errors.'],
['telemetry', 'Enable/disable anonymous data collection.'],
['--version', 'Show the version number and exit.'],
['--help', 'Show this help message.'],
],
flags: [
['--host [optional IP]', 'Expose server on network'],
['--config <path>', 'Specify the path to the Astro config file.'],
['--root <path>', 'Specify the path to the project root folder.'],
['--drafts', 'Include markdown draft pages in the build.'],
['--verbose', 'Enable verbose logging'],
['--silent', 'Disable logging'],
],
tables: {
Commands: [
['add', 'Add an integration.'],
['build', 'Build your project and write it to disk.'],
['check', 'Check your project for errors.'],
['dev', 'Start the development server.'],
['docs', "Open documentation in your web browser."],
['preview', 'Preview your build locally.'],
['telemetry', 'Configure telemetry settings.'],
],
'Global Flags': [
['--config <path>', 'Specify your config file.'],
['--root <path>', 'Specify your project root folder.'],
['--verbose', 'Enable verbose logging.'],
['--silent', 'Disable all logging.'],
['--version', 'Show the version number and exit.'],
['--help', 'Show this help message.'],
],
},
});
}

View file

@ -15,12 +15,14 @@ export async function update(subcommand: string, { flags, telemetry }: Telemetry
if (flags.help || !isValid) {
msg.printHelp({
commandName: 'astro telemetry',
usage: '<enable|disable|reset>',
commands: [
['enable', 'Enable anonymous data collection.'],
['disable', 'Disable anonymous data collection.'],
['reset', 'Reset anonymous data collection settings.'],
],
usage: '[command]',
tables: {
Commands: [
['enable', 'Enable anonymous data collection.'],
['disable', 'Disable anonymous data collection.'],
['reset', 'Reset anonymous data collection settings.'],
],
},
});
return;
}

View file

@ -1,27 +0,0 @@
export const FIRST_PARTY_FRAMEWORKS = [
{ value: 'react', title: 'React' },
{ value: 'preact', title: 'Preact' },
{ value: 'vue', title: 'Vue' },
{ value: 'svelte', title: 'Svelte' },
{ value: 'solid-js', title: 'Solid' },
{ value: 'lit', title: 'Lit' },
];
export const FIRST_PARTY_ADDONS = [
{ value: 'tailwind', title: 'Tailwind' },
{ value: 'turbolinks', title: 'Turbolinks' },
{ value: 'partytown', title: 'Partytown' },
{ value: 'sitemap', title: 'Sitemap' },
];
export const ALIASES = new Map([
['solid', 'solid-js'],
['tailwindcss', 'tailwind'],
]);
export const CONFIG_STUB = `import { defineConfig } from 'astro/config';\n\nexport default defineConfig({});`;
export const TAILWIND_CONFIG_STUB = `/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['./src/**/*.{astro,html,js,jsx,md,svelte,ts,tsx,vue}'],
theme: {
extend: {},
},
plugins: [],
}\n`;

View file

@ -11,14 +11,13 @@ import prompts from 'prompts';
import { fileURLToPath, pathToFileURL } from 'url';
import type yargs from 'yargs-parser';
import { resolveConfigURL } from '../config.js';
import { debug, error, info, LogOptions } from '../logger/core.js';
import { debug, info, LogOptions } from '../logger/core.js';
import * as msg from '../messages.js';
import { printHelp } from '../messages.js';
import { appendForwardSlash } from '../path.js';
import { apply as applyPolyfill } from '../polyfill.js';
import { parseNpmName } from '../util.js';
import { generate, parse, t, visit } from './babel.js';
import * as CONSTS from './consts.js';
import { ensureImport } from './imports.js';
import { wrapDefaultExport } from './wrapper.js';
@ -34,71 +33,77 @@ export interface IntegrationInfo {
packageName: string;
dependencies: [name: string, version: string][];
}
const ALIASES = new Map([
['solid', 'solid-js'],
['tailwindcss', 'tailwind'],
]);
const ASTRO_CONFIG_STUB = `import { defineConfig } from 'astro/config';\n\ndefault defineConfig({});`;
const TAILWIND_CONFIG_STUB = `/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['./src/**/*.{astro,html,js,jsx,md,svelte,ts,tsx,vue}'],
theme: {
extend: {},
},
plugins: [],
}\n`;
export default async function add(names: string[], { cwd, flags, logging, telemetry }: AddOptions) {
if (flags.help) {
if (flags.help || names.length === 0) {
printHelp({
commandName: 'astro add',
usage: '[FLAGS] [INTEGRATIONS...]',
flags: [
['--yes', 'Add the integration without user interaction.'],
['--help', 'Show this help message.'],
],
usage: '[integration]',
tables: {
Flags: [
['--yes', 'Accept all prompts.'],
['--help', 'Show this help message.'],
],
'Recommended: UI Frameworks': [
['react', 'astro add react'],
['preact', 'astro add preact'],
['vue', 'astro add vue'],
['svelte', 'astro add svelte'],
['solid-js', 'astro add solid-js'],
['lit', 'astro add lit'],
],
'Recommended: Hosting': [
['netlify', 'astro add netlify'],
['vercel', 'astro add vercel'],
['cloudflare', 'astro add cloudflare'],
['deno', 'astro add deno'],
],
'Recommended: Integrations': [
['tailwind', 'astro add tailwind'],
['partytown', 'astro add partytown'],
['sitemap', 'astro add sitemap'],
],
},
description: `For more integrations, check out: ${cyan('https://astro.build/integrations')}`,
});
return;
}
let configURL: URL | undefined;
const root = pathToFileURL(cwd ? path.resolve(cwd) : process.cwd());
// TODO: improve error handling for invalid configs
configURL = await resolveConfigURL({ cwd, flags });
if (configURL?.pathname.endsWith('package.json')) {
throw new Error(
`Unable to use astro add with package.json#astro configuration! Try migrating to \`astro.config.mjs\` and try again.`
);
}
applyPolyfill();
// If no integrations were given, prompt the user for some popular ones.
if (names.length === 0) {
const response = await prompts([
{
type: 'multiselect',
name: 'frameworks',
message: 'What frameworks would you like to enable?',
instructions: '\n Space to select. Return to submit',
choices: CONSTS.FIRST_PARTY_FRAMEWORKS,
},
{
type: 'multiselect',
name: 'addons',
message: 'What additional integrations would you like to enable?',
instructions: '\n Space to select. Return to submit',
choices: CONSTS.FIRST_PARTY_ADDONS,
},
]);
names = [...(response.frameworks ?? []), ...(response.addons ?? [])];
}
// If still empty after prompting, exit gracefully.
if (names.length === 0) {
error(logging, null, `No integrations specified.`);
return;
}
// Some packages might have a common alias! We normalize those here.
names = names.map((name) => (CONSTS.ALIASES.has(name) ? CONSTS.ALIASES.get(name)! : name));
if (configURL) {
debug('add', `Found config at ${configURL}`);
} else {
info(logging, 'add', `Unable to locate a config file, generating one for you.`);
configURL = new URL('./astro.config.mjs', appendForwardSlash(root.href));
await fs.writeFile(fileURLToPath(configURL), CONSTS.CONFIG_STUB, { encoding: 'utf-8' });
await fs.writeFile(fileURLToPath(configURL), ASTRO_CONFIG_STUB, { encoding: 'utf-8' });
}
const integrations = await validateIntegrations(names);
// TODO: improve error handling for invalid configs
if (configURL?.pathname.endsWith('package.json')) {
throw new Error(
`Unable to use "astro add" with package.json configuration. Try migrating to \`astro.config.mjs\` and try again.`
);
}
// Some packages might have a common alias! We normalize those here.
const integrationNames = names.map((name) => (ALIASES.has(name) ? ALIASES.get(name)! : name));
const integrations = await validateIntegrations(integrationNames);
let ast: t.File | null = null;
try {
@ -194,7 +199,7 @@ export default async function add(names: string[], { cwd, flags, logging, teleme
if (await askToContinue({ flags })) {
await fs.writeFile(
fileURLToPath(new URL('./tailwind.config.cjs', configURL)),
CONSTS.TAILWIND_CONFIG_STUB,
TAILWIND_CONFIG_STUB,
{ encoding: 'utf-8' }
);
debug('add', `Generated default ./tailwind.config.cjs file`);

View file

@ -18,7 +18,7 @@ import { debug, info } from '../logger/core.js';
import { render } from '../render/core.js';
import { createLinkStylesheetElementSet, createModuleScriptsSet } from '../render/ssr-element.js';
import { createRequest } from '../request.js';
import { getOutputFilename, isBuildingToSSR } from '../util.js';
import { getOutputFilename } from '../util.js';
import { getOutFile, getOutFolder } from './common.js';
import { eachPageData, getPageDataByComponent } from './internal.js';
import type { PageBuildData, SingleFileBuiltModule, StaticBuildOptions } from './types';
@ -97,7 +97,7 @@ export async function generatePages(
const timer = performance.now();
info(opts.logging, null, `\n${bgGreen(black(' generating static routes '))}`);
const ssr = isBuildingToSSR(opts.astroConfig);
const ssr = opts.astroConfig.mode === 'server';
const serverEntry = opts.buildConfig.serverEntry;
const outFolder = ssr ? opts.buildConfig.server : opts.astroConfig.outDir;
const ssrEntryURL = new URL('./' + serverEntry + `?time=${Date.now()}`, outFolder);
@ -207,7 +207,7 @@ async function generatePath(
}
}
const ssr = isBuildingToSSR(opts.astroConfig);
const ssr = opts.astroConfig.mode === 'server';
const url = new URL(opts.astroConfig.base + removeLeadingForwardSlash(pathname), origin);
const options: RenderOptions = {
links,

View file

@ -1,5 +1,5 @@
import type { AstroTelemetry } from '@astrojs/telemetry';
import type { AstroConfig, BuildConfig, ManifestData } from '../../@types/astro';
import type { AstroAdapter, AstroConfig, BuildConfig, ManifestData } from '../../@types/astro';
import type { LogOptions } from '../logger/core';
import fs from 'fs';
@ -14,11 +14,11 @@ import {
} from '../../integrations/index.js';
import { createVite, ViteConfigWithSSR } from '../create-vite.js';
import { fixViteErrorMessage } from '../errors.js';
import { debug, info, levels, timerMessage, warnIfUsingExperimentalSSR } from '../logger/core.js';
import { debug, info, levels, timerMessage } from '../logger/core.js';
import { apply as applyPolyfill } from '../polyfill.js';
import { RouteCache } from '../render/route-cache.js';
import { createRouteManifest } from '../routing/index.js';
import { createSafeError, isBuildingToSSR } from '../util.js';
import { createSafeError } from '../util.js';
import { collectPagesData } from './page-data.js';
import { staticBuild } from './static-build.js';
import { getTimeStat } from './util.js';
@ -79,7 +79,6 @@ class AstroBuilder {
{ astroConfig: this.config, logging, mode: 'build' }
);
await runHookConfigDone({ config: this.config });
warnIfUsingExperimentalSSR(logging, this.config);
const viteServer = await vite.createServer(viteConfig);
debug('build', timerMessage('Vite started', this.timer.viteStart));
return { viteConfig, viteServer };
@ -98,11 +97,21 @@ class AstroBuilder {
client: new URL('./client/', this.config.outDir),
server: new URL('./server/', this.config.outDir),
serverEntry: 'entry.mjs',
staticMode: undefined,
};
await runHookBuildStart({ config: this.config, buildConfig });
info(this.logging, 'build', 'Collecting build information...');
const getPrettyDeployTarget = (adapter: AstroAdapter | undefined) => {
if (adapter?.name === 'node') {
return 'node.js (generic)';
}
if (adapter?.name) {
return adapter?.name;
}
return 'unknown';
}
info(this.logging, 'build', `build target: ${colors.green(this.config.mode)}`);
info(this.logging, 'build', `deploy target: ${colors.green(getPrettyDeployTarget(this.config._ctx.adapter))}`);
info(this.logging, 'build', 'Collecting build info...');
this.timer.loadStart = performance.now();
const { assets, allPages } = await collectPagesData({
astroConfig: this.config,
@ -111,7 +120,7 @@ class AstroBuilder {
origin,
routeCache: this.routeCache,
viteServer,
ssr: isBuildingToSSR(this.config),
ssr: this.config.mode === 'server',
});
debug('build', timerMessage('All pages loaded', this.timer.loadStart));
@ -161,12 +170,11 @@ class AstroBuilder {
});
if (this.logging.level && levels[this.logging.level] <= levels['info']) {
const buildMode = isBuildingToSSR(this.config) ? 'ssr' : 'static';
await this.printStats({
logging: this.logging,
timeStart: this.timer.init,
pageCount: pageNames.length,
buildMode,
buildMode: this.config.mode,
});
}
}
@ -191,7 +199,7 @@ class AstroBuilder {
logging: LogOptions;
timeStart: number;
pageCount: number;
buildMode: 'static' | 'ssr';
buildMode: 'static' | 'server';
}) {
const total = getTimeStat(timeStart, performance.now());

View file

@ -10,7 +10,6 @@ import { debug } from '../logger/core.js';
import { removeTrailingForwardSlash } from '../path.js';
import { callGetStaticPaths, RouteCache, RouteCacheEntry } from '../render/route-cache.js';
import { matchRoute } from '../routing/match.js';
import { isBuildingToSSR } from '../util.js';
export interface CollectPagesDataOptions {
astroConfig: AstroConfig;
@ -36,9 +35,6 @@ export async function collectPagesData(
const assets: Record<string, string> = {};
const allPages: AllPagesData = {};
const builtPaths = new Set<string>();
const buildMode = isBuildingToSSR(astroConfig) ? 'ssr' : 'static';
const dataCollectionLogTimeout = setInterval(() => {
info(opts.logging, 'build', 'The data collection step may take longer for larger projects...');
clearInterval(dataCollectionLogTimeout);
@ -72,7 +68,7 @@ export async function collectPagesData(
};
clearInterval(routeCollectionLogTimeout);
if (buildMode === 'static') {
if (astroConfig.mode === 'static') {
const html = `${route.pathname}`.replace(/\/?$/, '/index.html');
debug(
'build',

View file

@ -11,7 +11,6 @@ import { runHookBuildSetup } from '../../integrations/index.js';
import { rollupPluginAstroBuildCSS } from '../../vite-plugin-build-css/index.js';
import type { ViteConfigWithSSR } from '../create-vite';
import { info } from '../logger/core.js';
import { isBuildingToSSR } from '../util.js';
import { generatePages } from './generate.js';
import { trackPageData } from './internal.js';
import type { PageBuildData, StaticBuildOptions } from './types';
@ -60,9 +59,7 @@ export async function staticBuild(opts: StaticBuildOptions) {
info(
opts.logging,
'build',
isBuildingToSSR(astroConfig)
? 'Building SSR entrypoints...'
: 'Building entrypoints for prerendering...'
`Building ${astroConfig.mode} entrypoints...`
);
const ssrResult = (await ssrBuild(opts, internals, pageInput)) as RollupOutput;
info(opts.logging, 'build', dim(`Completed in ${getTimeStat(timer.ssr, performance.now())}.`));
@ -79,7 +76,7 @@ export async function staticBuild(opts: StaticBuildOptions) {
await clientBuild(opts, internals, clientInput);
timer.generate = performance.now();
if (opts.buildConfig.staticMode) {
if (astroConfig.mode === 'static') {
try {
await generatePages(ssrResult, opts, internals, facadeIdToPageDataMap);
} finally {
@ -96,7 +93,7 @@ export async function staticBuild(opts: StaticBuildOptions) {
async function ssrBuild(opts: StaticBuildOptions, internals: BuildInternals, input: Set<string>) {
const { astroConfig, viteConfig } = opts;
const ssr = isBuildingToSSR(astroConfig);
const ssr = astroConfig.mode === 'server';
const out = ssr ? opts.buildConfig.server : astroConfig.outDir;
const viteBuildConfig: ViteConfigWithSSR = {
@ -140,7 +137,7 @@ async function ssrBuild(opts: StaticBuildOptions, internals: BuildInternals, inp
}),
...(viteConfig.plugins || []),
// SSR needs to be last
isBuildingToSSR(opts.astroConfig) &&
opts.astroConfig.mode === 'server' &&
vitePluginSSR(opts, internals, opts.astroConfig._ctx.adapter!),
vitePluginAnalyzer(opts.astroConfig, internals),
],
@ -171,7 +168,7 @@ async function clientBuild(
) {
const { astroConfig, viteConfig } = opts;
const timer = performance.now();
const ssr = isBuildingToSSR(astroConfig);
const ssr = astroConfig.mode === 'server';
const out = ssr ? opts.buildConfig.client : astroConfig.outDir;
// Nothing to do if there is no client-side JS.
@ -272,7 +269,7 @@ async function copyFiles(fromFolder: URL, toFolder: URL) {
async function ssrMoveAssets(opts: StaticBuildOptions) {
info(opts.logging, 'build', 'Rearranging server assets...');
const serverRoot = opts.buildConfig.staticMode
const serverRoot = opts.astroConfig.mode === 'static'
? opts.buildConfig.client
: opts.buildConfig.server;
const clientRoot = opts.buildConfig.client;

View file

@ -1,6 +1,5 @@
import type { Plugin as VitePlugin } from 'vite';
import { pagesVirtualModuleId, resolvedPagesVirtualModuleId } from '../app/index.js';
import { isBuildingToSSR } from '../util.js';
import { addRollupInput } from './add-rollup-input.js';
import type { BuildInternals } from './internal.js';
import { eachPageData } from './internal.js';
@ -11,7 +10,7 @@ export function vitePluginPages(opts: StaticBuildOptions, internals: BuildIntern
name: '@astro/plugin-build-pages',
options(options) {
if (!isBuildingToSSR(opts.astroConfig)) {
if (opts.astroConfig.mode === 'static') {
return addRollupInput(options, [pagesVirtualModuleId]);
}
},

View file

@ -93,7 +93,6 @@ export const LEGACY_ASTRO_CONFIG_KEYS = new Set([
]);
export const AstroConfigSchema = z.object({
adapter: z.object({ name: z.string(), hooks: z.object({}).passthrough().default({}) }).optional(),
root: z
.string()
.optional()
@ -132,6 +131,10 @@ export const AstroConfigSchema = z.object({
.union([z.literal('always'), z.literal('never'), z.literal('ignore')])
.optional()
.default(ASTRO_CONFIG_DEFAULTS.trailingSlash),
mode: z
.union([z.literal('static'), z.literal('server')])
.optional()
.default('static'),
build: z
.object({
format: z
@ -227,6 +230,9 @@ export const AstroConfigSchema = z.object({
})
.optional()
.default({}),
// Deprecated:
adapter: z.object({ name: z.string(), hooks: z.object({}).passthrough().default({}) }).optional(),
});
/** Turn raw config values into normalized values */

View file

@ -11,7 +11,7 @@ import {
runHookServerStart,
} from '../../integrations/index.js';
import { createVite } from '../create-vite.js';
import { info, LogOptions, warn, warnIfUsingExperimentalSSR } from '../logger/core.js';
import { info, LogOptions, warn } from '../logger/core.js';
import * as msg from '../messages.js';
import { apply as applyPolyfill } from '../polyfill.js';
@ -58,7 +58,6 @@ export default async function dev(config: AstroConfig, options: DevOptions): Pro
{ astroConfig: config, logging: options.logging, mode: 'dev' }
);
await runHookConfigDone({ config });
warnIfUsingExperimentalSSR(options.logging, config);
const viteServer = await vite.createServer(viteConfig);
runHookServerSetup({ config, server: viteServer });
await viteServer.listen(port);

View file

@ -1,13 +1,12 @@
import type { EndpointHandler } from '../../../@types/astro';
import type { SSROptions } from '../../render/dev';
import { preload } from '../../render/dev/index.js';
import { isBuildingToSSR } from '../../util.js';
import { call as callEndpoint } from '../index.js';
export async function call(ssrOpts: SSROptions) {
const [, mod] = await preload(ssrOpts);
return await callEndpoint(mod as unknown as EndpointHandler, {
...ssrOpts,
ssr: isBuildingToSSR(ssrOpts.astroConfig),
ssr: ssrOpts.astroConfig.mode === 'server',
});
}

View file

@ -128,16 +128,3 @@ export function timerMessage(message: string, startTime: number = Date.now()) {
return `${message} ${dim(timeDisplay)}`;
}
/**
* A warning that SSR is experimental. Remove when we can.
*/
export function warnIfUsingExperimentalSSR(opts: LogOptions, config: AstroConfig) {
if (config._ctx.adapter?.serverEntrypoint) {
warn(
opts,
'warning',
bold(`Warning:`),
`SSR support is still experimental and subject to API changes. If using in production, pin your dependencies to prevent accidental breakage.`
);
}
}

View file

@ -126,6 +126,7 @@ export const logger = {
export function enableVerboseLogging() {
//debugPackage.enable('*,-babel');
console.log('ah!');
debug('cli', '--verbose flag enabled! Enabling: DEBUG="*,-babel"');
debug(
'cli',

View file

@ -248,29 +248,28 @@ export function printHelp({
commandName,
headline,
usage,
commands,
flags,
tables,
description,
}: {
commandName: string;
headline?: string;
usage?: string;
commands?: [command: string, help: string][];
flags?: [flag: string, help: string][];
tables?: Record<string, [command: string, help: string][]>;
description?: string,
}) {
const linebreak = () => '';
const title = (label: string) => ` ${bgWhite(black(` ${label} `))}`;
const table = (rows: [string, string][], opts: { padding: number; prefix: string }) => {
const split = rows.some((row) => {
const message = `${opts.prefix}${' '.repeat(opts.padding)}${row[1]}`;
return message.length > process.stdout.columns;
});
const table = (rows: [string, string][], { padding }: { padding: number }) => {
const split = process.stdout.columns < 60;
let raw = '';
for (const row of rows) {
raw += `${opts.prefix}${bold(`${row[0]}`.padStart(opts.padding - opts.prefix.length))}`;
if (split) raw += '\n ';
raw += ' ' + dim(row[1]) + '\n';
if (split) {
raw += ` ${row[0]}\n `;
} else {
raw += `${(`${row[0]}`.padStart(padding))}`;
}
raw += ' ' + dim(row[1]) + '\n';
}
return raw.slice(0, -1); // remove latest \n
@ -291,18 +290,21 @@ export function printHelp({
message.push(linebreak(), ` ${green(commandName)} ${bold(usage)}`);
}
if (commands) {
message.push(
linebreak(),
title('Commands'),
table(commands, { padding: 28, prefix: ` ${commandName || 'astro'} ` })
);
if (tables) {
function calculateTablePadding(rows: [string, string][]) {
return rows.reduce((val, [first]) => Math.max(val, first.length), 0) + 2;
};
const tableEntries = Object.entries(tables);
const padding = Math.max(...tableEntries.map(([, rows]) => calculateTablePadding(rows)));
for (const [tableTitle, tableRows] of tableEntries) {
message.push(linebreak(), title(tableTitle), table(tableRows, { padding }));
}
}
if (flags) {
message.push(linebreak(), title('Flags'), table(flags, { padding: 28, prefix: ' ' }));
if (description) {
message.push(linebreak(), `${description}`);
}
// eslint-disable-next-line no-console
console.log(message.join('\n'));
console.log(message.join('\n') + '\n');
}

View file

@ -11,7 +11,6 @@ import type {
} from '../../../@types/astro';
import { prependForwardSlash } from '../../../core/path.js';
import { LogOptions } from '../../logger/core.js';
import { isBuildingToSSR } from '../../util.js';
import { render as coreRender } from '../core.js';
import { RouteCache } from '../route-cache.js';
import { createModuleScriptElementWithSrcSet } from '../ssr-element.js';
@ -183,7 +182,7 @@ export async function render(
route,
routeCache,
site: astroConfig.site ? new URL(astroConfig.base, astroConfig.site).toString() : undefined,
ssr: isBuildingToSSR(astroConfig),
ssr: astroConfig.mode === 'server',
});
return response;

View file

@ -62,7 +62,7 @@ export function createRequest({
warn(
logging,
'ssg',
`Headers are not exposed in static-site generation (SSG) mode. To enable reading headers you need to set an SSR adapter in your config.`
`Headers are not exposed in static-site generation (SSG) mode. To enable reading headers: set \`mode: "server"\` in your config file.`
);
return _headers;
},

View file

@ -7,12 +7,11 @@ import {
BuildConfig,
RouteData,
} from '../@types/astro.js';
import ssgAdapter from '../adapter-ssg/index.js';
import { getGenericNodeAdapter } from '../adapter-node/index.js';
import type { SerializedSSRManifest } from '../core/app/types';
import type { PageBuildData } from '../core/build/types';
import { mergeConfig } from '../core/config.js';
import type { ViteConfigWithSSR } from '../core/create-vite.js';
import { isBuildingToSSR } from '../core/util.js';
type Hooks<
Hook extends keyof AstroIntegration['hooks'],
@ -26,9 +25,10 @@ export async function runHookConfigSetup({
config: AstroConfig;
command: 'dev' | 'build';
}): Promise<AstroConfig> {
if (_config.adapter) {
_config.integrations.push(_config.adapter);
}
// DEPRECATED
// if (_config.adapter) {
// _config.integrations.push(_config.adapter);
// }
let updatedConfig: AstroConfig = { ..._config };
for (const integration of _config.integrations) {
@ -86,7 +86,7 @@ export async function runHookConfigDone({ config }: { config: AstroConfig }) {
setAdapter(adapter) {
if (config._ctx.adapter && config._ctx.adapter.name !== adapter.name) {
throw new Error(
`Adapter already set to ${config._ctx.adapter.name}. You can only have one adapter.`
`Integration "${integration.name}" conflicts with "${config._ctx.adapter.name}". You can only configure one deployment integration.`
);
}
config._ctx.adapter = adapter;
@ -94,22 +94,13 @@ export async function runHookConfigDone({ config }: { config: AstroConfig }) {
});
}
}
// Call the default adapter
if (!config._ctx.adapter) {
const integration = ssgAdapter();
config.integrations.push(integration);
if (integration?.hooks?.['astro:config:done']) {
await integration.hooks['astro:config:done']({
config,
setAdapter(adapter) {
config._ctx.adapter = adapter;
},
});
}
}
// Call the default adapter
if (!config._ctx.adapter && config.mode === 'server') {
config._ctx.adapter = getGenericNodeAdapter();
}
}
export async function runHookServerSetup({
export async function runHookServerSetup({
config,
server,
}: {
@ -209,7 +200,7 @@ export async function runHookBuildDone({
pages: string[];
routes: RouteData[];
}) {
const dir = isBuildingToSSR(config) ? buildConfig.client : config.outDir;
const dir = config.mode === 'server' ? buildConfig.client : config.outDir;
for (const integration of config.integrations) {
if (integration?.hooks?.['astro:build:done']) {

View file

@ -15,7 +15,7 @@ import { preload, ssr } from '../core/render/dev/index.js';
import { RouteCache } from '../core/render/route-cache.js';
import { createRequest } from '../core/request.js';
import { createRouteManifest, matchRoute } from '../core/routing/index.js';
import { createSafeError, isBuildingToSSR, resolvePages } from '../core/util.js';
import { createSafeError, resolvePages } from '../core/util.js';
import notFoundTemplate, { subpathNotUsedTemplate } from '../template/4xx.js';
import serverErrorTemplate from '../template/5xx.js';
@ -188,7 +188,7 @@ async function handleRequest(
const site = config.site ? new URL(config.base, config.site) : undefined;
const devRoot = site ? site.pathname : '/';
const origin = `${viteServer.config.server.https ? 'https' : 'http'}://${req.headers.host}`;
const buildingToSSR = isBuildingToSSR(config);
const buildingToSSR = config.mode === 'server';
// Ignore `.html` extensions and `index.html` in request URLS to ensure that
// routing behavior matches production builds. This supports both file and directory
// build formats, and is necessary based on how the manifest tracks build targets.
@ -257,7 +257,7 @@ async function handleRequest(
routeCache,
pathname: rootRelativeUrl,
logging,
ssr: isBuildingToSSR(config),
ssr: config.mode === 'server',
});
if (paramsAndPropsRes === GetParamsAndPropsError.NoMatchingStaticPath) {
warn(

View file

@ -30,8 +30,6 @@ export default function vercelStatic(): AstroIntegration {
);
}
buildConfig.staticMode = true;
// Ensure to have `.vercel/output` empty.
// This is because, when building to static, outDir = .vercel/output/static/,
// so .vercel/output itself won't get cleaned.

View file

@ -1,5 +1,5 @@
export { pathToPosix } from './lib/utils';
export { AbortController, AbortSignal, alert, atob, Blob, btoa, ByteLengthQueuingStrategy, cancelAnimationFrame, cancelIdleCallback, CanvasRenderingContext2D, CharacterData, clearTimeout, Comment, CountQueuingStrategy, CSSStyleSheet, CustomElementRegistry, CustomEvent, Document, DocumentFragment, DOMException, Element, Event, EventTarget, fetch, File, FormData, Headers, HTMLBodyElement, HTMLCanvasElement, HTMLDivElement, HTMLDocument, HTMLElement, HTMLHeadElement, HTMLHtmlElement, HTMLImageElement, HTMLSpanElement, HTMLStyleElement, HTMLTemplateElement, HTMLUnknownElement, Image, ImageData, IntersectionObserver, MediaQueryList, MutationObserver, Node, NodeFilter, NodeIterator, OffscreenCanvas, ReadableByteStreamController, ReadableStream, ReadableStreamBYOBReader, ReadableStreamBYOBRequest, ReadableStreamDefaultController, ReadableStreamDefaultReader, Request, requestAnimationFrame, requestIdleCallback, ResizeObserver, Response, setTimeout, ShadowRoot, structuredClone, StyleSheet, Text, TransformStream, TreeWalker, URLPattern, Window, WritableStream, WritableStreamDefaultController, WritableStreamDefaultWriter } from './mod.js';
export { AbortController, AbortSignal, alert, atob, Blob, btoa, ByteLengthQueuingStrategy, cancelAnimationFrame, cancelIdleCallback, CanvasRenderingContext2D, CharacterData, clearTimeout, Comment, CountQueuingStrategy, CSSStyleSheet, CustomElementRegistry, CustomEvent, Document, DocumentFragment, DOMException, Element, Event, EventTarget, fetch, File, FormData, Headers, HTMLBodyElement, HTMLCanvasElement, HTMLDivElement, HTMLDocument, HTMLElement, HTMLHeadElement, HTMLHtmlElement, HTMLImageElement, HTMLSpanElement, HTMLStyleElement, HTMLTemplateElement, HTMLUnknownElement, Image, ImageData, IntersectionObserver, MediaQueryList, MutationObserver, Node, NodeFilter, NodeIterator, OffscreenCanvas, ReadableByteStreamController, ReadableStream, ReadableStreamBYOBReader, ReadableStreamBYOBRequest, ReadableStreamDefaultController, ReadableStreamDefaultReader, Request, requestAnimationFrame, requestIdleCallback, ResizeObserver, Response, setTimeout, ShadowRoot, structuredClone, StyleSheet, Text, TransformStream, TreeWalker, URLPattern, Window, WritableStream, WritableStreamDefaultController, WritableStreamDefaultWriter, } from './mod.js';
export declare const polyfill: {
(target: any, options?: PolyfillOptions): any;
internals(target: any, name: string): any;

File diff suppressed because it is too large Load diff