Skip to content

Commit

Permalink
Refactor to remove AstroConfig['_ctx'] (#4771)
Browse files Browse the repository at this point in the history
* Refactor to remove AstroConfig['_ctx']

* Fix type error

* Export validateConfig

* Move to an options bag for createSettings

* Move config tests into test/untils/config

* Add a changeste

* fix build
  • Loading branch information
matthewp committed Sep 16, 2022
1 parent 4856763 commit f3a81d8
Show file tree
Hide file tree
Showing 44 changed files with 776 additions and 744 deletions.
5 changes: 5 additions & 0 deletions .changeset/new-llamas-wash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Internal refactor
29 changes: 15 additions & 14 deletions packages/astro/src/@types/astro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import type * as babel from '@babel/core';
import type { AddressInfo } from 'net';
import type { TsConfigJson } from 'tsconfig-resolver';
import type * as vite from 'vite';
import { z } from 'zod';
import type { z } from 'zod';
import type { SerializedSSRManifest } from '../core/app/types';
import type { PageBuildData } from '../core/build/types';
import type { AstroConfigSchema } from '../core/config';
Expand Down Expand Up @@ -871,20 +871,21 @@ 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[];
}

// Private:
// We have a need to pass context based on configured state,
// that is different from the user-exposed configuration.
// TODO: Create an AstroConfig class to manage this, long-term.
_ctx: {
tsConfig: TsConfigJson | undefined;
tsConfigPath: string | undefined;
pageExtensions: string[];
injectedRoutes: InjectedRoute[];
adapter: AstroAdapter | undefined;
renderers: AstroRenderer[];
scripts: { stage: InjectedScriptStage; content: string }[];
};
export interface AstroSettings {
config: AstroConfig;

adapter: AstroAdapter | undefined;
injectedRoutes: InjectedRoute[];
pageExtensions: string[];
renderers: AstroRenderer[];
scripts: {
stage: InjectedScriptStage;
content: string
}[];
tsConfig: TsConfigJson | undefined;
tsConfigPath: string | undefined;
}

export type AsyncRendererComponentFn<U> = (
Expand Down
6 changes: 3 additions & 3 deletions packages/astro/src/cli/check/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable no-console */
import { AstroCheck, DiagnosticSeverity } from '@astrojs/language-server';
import type { AstroConfig } from '../../@types/astro';
import type { AstroSettings } from '../../@types/astro';

import glob from 'fast-glob';
import * as fs from 'fs';
Expand All @@ -16,10 +16,10 @@ interface Result {
hints: number;
}

export async function check(astroConfig: AstroConfig) {
export async function check(settings: AstroSettings) {
console.log(bold('astro check'));

const root = astroConfig.root;
const root = settings.config.root;

const spinner = ora(` Getting diagnostics for Astro files in ${fileURLToPath(root)}…`).start();

Expand Down
30 changes: 21 additions & 9 deletions packages/astro/src/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import yargs from 'yargs-parser';
import { z } from 'zod';
import add from '../core/add/index.js';
import build from '../core/build/index.js';
import { openConfig, resolveConfigPath, resolveFlags, resolveRoot } from '../core/config.js';
import { openConfig, resolveConfigPath, resolveFlags, resolveRoot, createSettings, loadTSConfig } from '../core/config/index.js';
import devServer from '../core/dev/index.js';
import { collectErrorMetadata } from '../core/errors.js';
import { debug, error, info, LogOptions } from '../core/logger/core.js';
Expand Down Expand Up @@ -150,7 +150,7 @@ async function runCommand(cmd: string, flags: yargs.Arguments) {
}
}

let { astroConfig, userConfig } = await openConfig({
let { astroConfig: initialAstroConfig, userConfig: initialUserConfig } = await openConfig({
cwd: root,
flags,
cmd,
Expand All @@ -159,16 +159,22 @@ async function runCommand(cmd: string, flags: yargs.Arguments) {
await handleConfigError(e, { cwd: root, flags, logging });
return {} as any;
});
if (!astroConfig) return;
telemetry.record(event.eventCliSession(cmd, userConfig, flags));
if (!initialAstroConfig) return;
telemetry.record(event.eventCliSession(cmd, initialUserConfig, flags));
let initialTsConfig = loadTSConfig(root);
let settings = createSettings({
config: initialAstroConfig,
tsConfig: initialTsConfig?.config,
tsConfigPath: initialTsConfig?.path,
});

// Common CLI Commands:
// These commands run normally. All commands are assumed to have been handled
// by the end of this switch statement.
switch (cmd) {
case 'dev': {
async function startDevServer({ isRestart = false }: { isRestart?: boolean } = {}) {
const { watcher, stop } = await devServer(astroConfig, { logging, telemetry, isRestart });
const { watcher, stop } = await devServer(settings, { logging, telemetry, isRestart });
let restartInFlight = false;
const configFlag = resolveFlags(flags).config;
const configFlagPath = configFlag
Expand Down Expand Up @@ -199,7 +205,13 @@ async function runCommand(cmd: string, flags: yargs.Arguments) {
isConfigReload: true,
});
info(logging, 'astro', logMsg + '\n');
astroConfig = newConfig.astroConfig;
let astroConfig = newConfig.astroConfig;
let tsconfig = loadTSConfig(root);
settings = createSettings({
config: astroConfig,
tsConfig: tsconfig?.config,
tsConfigPath: tsconfig?.path
});
await stop();
await startDevServer({ isRestart: true });
} catch (e) {
Expand All @@ -220,16 +232,16 @@ async function runCommand(cmd: string, flags: yargs.Arguments) {
}

case 'build': {
return await build(astroConfig, { logging, telemetry });
return await build(settings, { logging, telemetry });
}

case 'check': {
const ret = await check(astroConfig);
const ret = await check(settings);
return process.exit(ret);
}

case 'preview': {
const server = await preview(astroConfig, { logging, telemetry });
const server = await preview(settings, { logging, telemetry });
return await server.closed(); // keep alive until the server is closed
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/core/add/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import preferredPM from 'preferred-pm';
import prompts from 'prompts';
import { fileURLToPath, pathToFileURL } from 'url';
import type yargs from 'yargs-parser';
import { resolveConfigPath } from '../config.js';
import { resolveConfigPath } from '../config/index.js';
import { debug, info, LogOptions } from '../logger/core.js';
import * as msg from '../messages.js';
import { printHelp } from '../messages.js';
Expand Down
63 changes: 32 additions & 31 deletions packages/astro/src/core/build/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { OutputAsset, OutputChunk } from 'rollup';
import { fileURLToPath } from 'url';
import type {
AstroConfig,
AstroSettings,
ComponentInstance,
EndpointHandler,
RouteType,
Expand Down Expand Up @@ -62,10 +63,10 @@ function* throttle(max: number, inPaths: string[]) {
}
}

function shouldSkipDraft(pageModule: ComponentInstance, astroConfig: AstroConfig): boolean {
function shouldSkipDraft(pageModule: ComponentInstance, settings: AstroSettings): boolean {
return (
// Drafts are disabled
!astroConfig.markdown.drafts &&
!settings.config.markdown.drafts &&
// This is a draft post
'frontmatter' in pageModule &&
(pageModule as any).frontmatter?.draft === true
Expand All @@ -74,13 +75,13 @@ function shouldSkipDraft(pageModule: ComponentInstance, astroConfig: AstroConfig

// Gives back a facadeId that is relative to the root.
// ie, src/pages/index.astro instead of /Users/name..../src/pages/index.astro
export function rootRelativeFacadeId(facadeId: string, astroConfig: AstroConfig): string {
return facadeId.slice(fileURLToPath(astroConfig.root).length);
export function rootRelativeFacadeId(facadeId: string, settings: AstroSettings): string {
return facadeId.slice(fileURLToPath(settings.config.root).length);
}

// Determines of a Rollup chunk is an entrypoint page.
export function chunkIsPage(
astroConfig: AstroConfig,
settings: AstroSettings,
output: OutputAsset | OutputChunk,
internals: BuildInternals
) {
Expand All @@ -90,7 +91,7 @@ export function chunkIsPage(
const chunk = output as OutputChunk;
if (chunk.facadeModuleId) {
const facadeToEntryId = prependForwardSlash(
rootRelativeFacadeId(chunk.facadeModuleId, astroConfig)
rootRelativeFacadeId(chunk.facadeModuleId, settings)
);
return internals.entrySpecifierToBundleMap.has(facadeToEntryId);
}
Expand All @@ -101,9 +102,9 @@ export async function generatePages(opts: StaticBuildOptions, internals: BuildIn
const timer = performance.now();
info(opts.logging, null, `\n${bgGreen(black(' generating static routes '))}`);

const ssr = opts.astroConfig.output === 'server';
const ssr = opts.settings.config.output === 'server';
const serverEntry = opts.buildConfig.serverEntry;
const outFolder = ssr ? opts.buildConfig.server : getOutDirWithinCwd(opts.astroConfig.outDir);
const outFolder = ssr ? opts.buildConfig.server : getOutDirWithinCwd(opts.settings.config.outDir);
const ssrEntryURL = new URL('./' + serverEntry + `?time=${Date.now()}`, outFolder);
const ssrEntry = await import(ssrEntryURL.toString());
const builtPaths = new Set<string>();
Expand Down Expand Up @@ -137,7 +138,7 @@ async function generatePage(
);
}

if (shouldSkipDraft(pageModule, opts.astroConfig)) {
if (shouldSkipDraft(pageModule, opts.settings)) {
info(opts.logging, null, `${magenta('⚠️')} Skipping draft ${pageData.route.component}`);
return;
}
Expand All @@ -163,7 +164,7 @@ async function generatePage(
const timeEnd = performance.now();
const timeChange = getTimeStat(timeStart, timeEnd);
const timeIncrease = `(+${timeChange})`;
const filePath = getOutputFilename(opts.astroConfig, path, pageData.route.type);
const filePath = getOutputFilename(opts.settings.config, path, pageData.route.type);
const lineIcon = i === paths.length - 1 ? '└─' : '├─';
info(opts.logging, null, ` ${cyan(lineIcon)} ${dim(filePath)} ${dim(timeIncrease)}`);
}
Expand All @@ -186,7 +187,7 @@ async function getPathsForRoute(
route: pageData.route,
isValidate: false,
logging: opts.logging,
ssr: opts.astroConfig.output === 'server',
ssr: opts.settings.config.output === 'server',
})
.then((_result) => {
const label = _result.staticPaths.length === 1 ? 'page' : 'pages';
Expand Down Expand Up @@ -262,8 +263,8 @@ function shouldAppendForwardSlash(
}

function addPageName(pathname: string, opts: StaticBuildOptions): void {
const trailingSlash = opts.astroConfig.trailingSlash;
const buildFormat = opts.astroConfig.build.format;
const trailingSlash = opts.settings.config.trailingSlash;
const buildFormat = opts.settings.config.build.format;
const pageName = shouldAppendForwardSlash(trailingSlash, buildFormat)
? pathname.replace(/\/?$/, '/').replace(/^\//, '')
: pathname.replace(/^\//, '');
Expand Down Expand Up @@ -303,7 +304,7 @@ async function generatePath(
opts: StaticBuildOptions,
gopts: GeneratePathOptions
) {
const { astroConfig, logging, origin, routeCache } = opts;
const { settings, logging, origin, routeCache } = opts;
const { mod, internals, linkIds, scripts: hoistedScripts, pageData, renderers } = gopts;

// This adds the page name to the array so it can be shown as part of stats.
Expand All @@ -316,26 +317,26 @@ async function generatePath(
// If a base path was provided, append it to the site URL. This ensures that
// all injected scripts and links are referenced relative to the site and subpath.
const site =
astroConfig.base !== '/'
? joinPaths(astroConfig.site?.toString() || 'http://localhost/', astroConfig.base)
: astroConfig.site;
settings.config.base !== '/'
? joinPaths(settings.config.site?.toString() || 'http://localhost/', settings.config.base)
: settings.config.site;
const links = createLinkStylesheetElementSet(linkIds, site);
const scripts = createModuleScriptsSet(hoistedScripts ? [hoistedScripts] : [], site);

if (astroConfig._ctx.scripts.some((script) => script.stage === 'page')) {
if (settings.scripts.some((script) => script.stage === 'page')) {
const hashedFilePath = internals.entrySpecifierToBundleMap.get(PAGE_SCRIPT_ID);
if (typeof hashedFilePath !== 'string') {
throw new Error(`Cannot find the built path for ${PAGE_SCRIPT_ID}`);
}
const src = prependForwardSlash(npath.posix.join(astroConfig.base, hashedFilePath));
const src = prependForwardSlash(npath.posix.join(settings.config.base, hashedFilePath));
scripts.add({
props: { type: 'module', src },
children: '',
});
}

// Add all injected scripts to the page.
for (const script of astroConfig._ctx.scripts) {
for (const script of settings.scripts) {
if (script.stage === 'head-inline') {
scripts.add({
props: {},
Expand All @@ -344,21 +345,21 @@ async function generatePath(
}
}

const ssr = opts.astroConfig.output === 'server';
const ssr = settings.config.output === 'server';
const url = getUrlForPath(
pathname,
opts.astroConfig.base,
opts.settings.config.base,
origin,
opts.astroConfig.build.format,
opts.settings.config.build.format,
pageData.route.type
);
const options: RenderOptions = {
adapterName: undefined,
links,
logging,
markdown: {
...astroConfig.markdown,
isAstroFlavoredMd: astroConfig.legacy.astroFlavoredMarkdown,
...settings.config.markdown,
isAstroFlavoredMd: settings.config.legacy.astroFlavoredMarkdown,
},
mod,
mode: opts.mode,
Expand All @@ -376,14 +377,14 @@ async function generatePath(
}
throw new Error(`Cannot find the built path for ${specifier}`);
}
return prependForwardSlash(npath.posix.join(astroConfig.base, hashedFilePath));
return prependForwardSlash(npath.posix.join(settings.config.base, hashedFilePath));
},
request: createRequest({ url, headers: new Headers(), logging, ssr }),
route: pageData.route,
routeCache,
site: astroConfig.site
? new URL(astroConfig.base, astroConfig.site).toString()
: astroConfig.site,
site: settings.config.site
? new URL(settings.config.base, settings.config.site).toString()
: settings.config.site,
ssr,
streaming: true,
};
Expand All @@ -409,8 +410,8 @@ async function generatePath(
body = await response.text();
}

const outFolder = getOutFolder(astroConfig, pathname, pageData.route.type);
const outFile = getOutFile(astroConfig, outFolder, pathname, pageData.route.type);
const outFolder = getOutFolder(settings.config, pathname, pageData.route.type);
const outFile = getOutFile(settings.config, outFolder, pathname, pageData.route.type);
pageData.route.distURL = outFile;
await fs.promises.mkdir(outFolder, { recursive: true });
await fs.promises.writeFile(outFile, body, encoding ?? 'utf-8');
Expand Down

0 comments on commit f3a81d8

Please sign in to comment.