0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-01-13 22:11:20 -05:00

Remove proload for config loading (#5778)

* Refactor resolve and load config

* Add changeset

* Update name

* Remove unnecessary node_env handling

* Fix test

* Update comment
This commit is contained in:
Bjorn Lu 2023-01-07 01:49:18 +08:00 committed by GitHub
parent 54d87af012
commit 49ab4f231c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 65 additions and 128 deletions

View file

@ -0,0 +1,5 @@
---
'astro': major
---
Remove proload to load the Astro config. It will now use NodeJS and Vite to load the config only.

View file

@ -120,8 +120,6 @@
"@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.3",
"@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",
"@types/yargs-parser": "^21.0.0", "@types/yargs-parser": "^21.0.0",

View file

@ -190,7 +190,6 @@ export async function loadContentConfig({
settings: AstroSettings; settings: AstroSettings;
}): Promise<ContentConfig | Error> { }): Promise<ContentConfig | Error> {
const contentPaths = getContentPaths({ srcDir: settings.config.srcDir }); const contentPaths = getContentPaths({ srcDir: settings.config.srcDir });
const nodeEnv = process.env.NODE_ENV;
const tempConfigServer: ViteDevServer = await createServer({ const tempConfigServer: ViteDevServer = await createServer({
root: fileURLToPath(settings.config.root), root: fileURLToPath(settings.config.root),
server: { middlewareMode: true, hmr: false }, server: { middlewareMode: true, hmr: false },
@ -207,9 +206,6 @@ export async function loadContentConfig({
return new NotFoundError('Failed to resolve content config.'); return new NotFoundError('Failed to resolve content config.');
} finally { } finally {
await tempConfigServer.close(); await tempConfigServer.close();
// Reset NODE_ENV to initial value
// Vite's `createServer()` sets NODE_ENV to 'development'!
process.env.NODE_ENV = nodeEnv;
} }
const config = contentConfigParser.safeParse(unparsedConfig); const config = contentConfigParser.safeParse(unparsedConfig);
if (config.success) { if (config.success) {

View file

@ -115,7 +115,7 @@ export function resolveRoot(cwd?: string | URL): string {
} }
/** 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) {
astroConfig.server = astroConfig.server || {}; astroConfig.server = astroConfig.server || {};
astroConfig.markdown = astroConfig.markdown || {}; astroConfig.markdown = astroConfig.markdown || {};
astroConfig.experimental = astroConfig.experimental || {}; astroConfig.experimental = astroConfig.experimental || {};
@ -136,6 +136,23 @@ function mergeCLIFlags(astroConfig: AstroUserConfig, flags: CLIFlags, cmd: strin
return astroConfig; return astroConfig;
} }
async function search(fsMod: typeof fs, root: string) {
const paths = [
'astro.config.mjs',
'astro.config.js',
'astro.config.ts',
'astro.config.mts',
'astro.config.cjs',
'astro.config.cts',
].map((p) => path.join(root, p));
for (const file of paths) {
if (fsMod.existsSync(file)) {
return file;
}
}
}
interface LoadConfigOptions { interface LoadConfigOptions {
cwd?: string; cwd?: string;
flags?: Flags; flags?: Flags;
@ -147,41 +164,36 @@ interface LoadConfigOptions {
fsMod?: typeof fs; fsMod?: typeof fs;
} }
interface ResolveConfigPathOptions {
cwd?: string;
flags?: Flags;
fs: typeof fs;
}
/** /**
* Resolve the file URL of the user's `astro.config.js|cjs|mjs|ts` file * Resolve the file URL of the user's `astro.config.js|cjs|mjs|ts` file
* Note: currently the same as loadConfig but only returns the `filePath`
* instead of the resolved config
*/ */
export async function resolveConfigPath( export async function resolveConfigPath(
configOptions: Pick<LoadConfigOptions, 'cwd' | 'flags'> & { fs: typeof fs } configOptions: ResolveConfigPathOptions
): Promise<string | undefined> { ): Promise<string | undefined> {
const root = resolveRoot(configOptions.cwd); const root = resolveRoot(configOptions.cwd);
const flags = resolveFlags(configOptions.flags || {}); const flags = resolveFlags(configOptions.flags || {});
let userConfigPath: string | undefined;
let userConfigPath: string | undefined;
if (flags?.config) { if (flags?.config) {
userConfigPath = /^\.*\//.test(flags.config) ? flags.config : `./${flags.config}`; userConfigPath = /^\.*\//.test(flags.config) ? flags.config : `./${flags.config}`;
userConfigPath = fileURLToPath(new URL(userConfigPath, `file://${root}/`)); userConfigPath = fileURLToPath(new URL(userConfigPath, `file://${root}/`));
} if (!configOptions.fs.existsSync(userConfigPath)) {
// Resolve config file path using Proload
// If `userConfigPath` is `undefined`, Proload will search for `astro.config.[cm]?[jt]s`
try {
const config = await loadConfigWithVite({
configPath: userConfigPath,
root,
fs: configOptions.fs,
});
return config.filePath;
} catch (e) {
if (flags.config) {
throw new AstroError({ throw new AstroError({
...AstroErrorData.ConfigNotFound, ...AstroErrorData.ConfigNotFound,
message: AstroErrorData.ConfigNotFound.message(flags.config), message: AstroErrorData.ConfigNotFound.message(flags.config),
}); });
} }
throw e; } else {
userConfigPath = await search(configOptions.fs, root);
} }
return userConfigPath;
} }
interface OpenConfigResult { interface OpenConfigResult {
@ -261,22 +273,6 @@ async function tryLoadConfig(
} }
} }
/**
* Attempt to load an `astro.config.mjs` file
* @deprecated
*/
export async function loadConfig(configOptions: LoadConfigOptions): Promise<AstroConfig> {
const root = resolveRoot(configOptions.cwd);
const flags = resolveFlags(configOptions.flags || {});
let userConfig: AstroUserConfig = {};
const config = await tryLoadConfig(configOptions, root);
if (config) {
userConfig = config.value;
}
return resolveConfig(userConfig, root, flags, configOptions.cmd);
}
/** Attempt to resolve an Astro configuration object. Normalize, validate, and return. */ /** Attempt to resolve an Astro configuration object. Normalize, validate, and return. */
export async function resolveConfig( export async function resolveConfig(
userConfig: AstroUserConfig, userConfig: AstroUserConfig,
@ -284,7 +280,7 @@ export async function resolveConfig(
flags: CLIFlags = {}, flags: CLIFlags = {},
cmd: string cmd: string
): Promise<AstroConfig> { ): Promise<AstroConfig> {
const mergedConfig = mergeCLIFlags(userConfig, flags, cmd); const mergedConfig = mergeCLIFlags(userConfig, flags);
const validatedConfig = await validateConfig(mergedConfig, root, cmd); const validatedConfig = await validateConfig(mergedConfig, root, cmd);
return validatedConfig; return validatedConfig;

View file

@ -1,15 +1,7 @@
import type fsType from 'fs'; import type fsType from 'fs';
import npath from 'path';
import { pathToFileURL } from 'url'; import { pathToFileURL } from 'url';
import * as vite from 'vite'; import * as vite from 'vite';
import loadFallbackPlugin from '../../vite-plugin-load-fallback/index.js'; import loadFallbackPlugin from '../../vite-plugin-load-fallback/index.js';
import { AstroError, AstroErrorData } from '../errors/index.js';
// Fallback for legacy
import load from '@proload/core';
import loadTypeScript from '@proload/plugin-tsm';
load.use([loadTypeScript]);
export interface ViteLoader { export interface ViteLoader {
root: string; root: string;
@ -24,8 +16,8 @@ async function createViteLoader(root: string, fs: typeof fsType): Promise<ViteLo
appType: 'custom', appType: 'custom',
ssr: { ssr: {
// NOTE: Vite doesn't externalize linked packages by default. During testing locally, // NOTE: Vite doesn't externalize linked packages by default. During testing locally,
// these dependencies trip up Vite's dev SSR transform. In the future, we should // these dependencies trip up Vite's dev SSR transform. Awaiting upstream feature:
// avoid `vite.createServer` and use `loadConfigFromFile` instead. // https://github.com/vitejs/vite/pull/10939
external: [ external: [
'@astrojs/tailwind', '@astrojs/tailwind',
'@astrojs/mdx', '@astrojs/mdx',
@ -43,40 +35,6 @@ async function createViteLoader(root: string, fs: typeof fsType): Promise<ViteLo
}; };
} }
async function stat(fs: typeof fsType, configPath: string, mustExist: boolean): Promise<boolean> {
try {
await fs.promises.stat(configPath);
return true;
} catch {
if (mustExist) {
throw new AstroError({
...AstroErrorData.ConfigNotFound,
message: AstroErrorData.ConfigNotFound.message(configPath),
});
}
return false;
}
}
async function search(fs: typeof fsType, root: string) {
const paths = [
'astro.config.mjs',
'astro.config.js',
'astro.config.ts',
'astro.config.mts',
'astro.config.cjs',
'astro.config.cjs',
].map((path) => npath.join(root, path));
for (const file of paths) {
// First verify the file event exists
const exists = await stat(fs, file, false);
if (exists) {
return file;
}
}
}
interface LoadConfigWithViteOptions { interface LoadConfigWithViteOptions {
root: string; root: string;
configPath: string | undefined; configPath: string | undefined;
@ -91,35 +49,25 @@ export async function loadConfigWithVite({
value: Record<string, any>; value: Record<string, any>;
filePath?: string; filePath?: string;
}> { }> {
let file: string;
if (configPath) {
// Go ahead and check if the file exists and throw if not.
await stat(fs, configPath, true);
file = configPath;
} else {
const found = await search(fs, root);
if (!found) {
// No config file found, return an empty config that will be populated with defaults // No config file found, return an empty config that will be populated with defaults
if (!configPath) {
return { return {
value: {}, value: {},
filePath: undefined, filePath: undefined,
}; };
} else {
file = found;
}
} }
// Try loading with Node import() // Try loading with Node import()
if (/\.[cm]?js$/.test(file)) { if (/\.[cm]?js$/.test(configPath)) {
try { try {
const config = await import(pathToFileURL(file).toString()); const config = await import(pathToFileURL(configPath).toString());
return { return {
value: config.default ?? {}, value: config.default ?? {},
filePath: file, filePath: configPath,
}; };
} catch { } catch {
// We do not need to keep the error here because with fallback the error will be rethrown // We do not need to keep the error here because with fallback the error will be rethrown
// when/if it fails in Proload. // when/if it fails in Vite.
} }
} }
@ -127,22 +75,10 @@ export async function loadConfigWithVite({
let loader: ViteLoader | undefined; let loader: ViteLoader | undefined;
try { try {
loader = await createViteLoader(root, fs); loader = await createViteLoader(root, fs);
const mod = await loader.viteServer.ssrLoadModule(file); const mod = await loader.viteServer.ssrLoadModule(configPath);
return { return {
value: mod.default ?? {}, value: mod.default ?? {},
filePath: file, filePath: configPath,
};
} catch {
// Try loading with Proload
// TODO deprecate - this is only for legacy compatibility
const res = await load('astro', {
mustExist: true,
cwd: root,
filePath: file,
});
return {
value: res?.value ?? {},
filePath: file,
}; };
} finally { } finally {
if (loader) { if (loader) {

View file

@ -7,7 +7,7 @@ import stripAnsi from 'strip-ansi';
import { fileURLToPath } from 'url'; import { fileURLToPath } from 'url';
import { sync } from '../dist/cli/sync/index.js'; import { sync } from '../dist/cli/sync/index.js';
import build from '../dist/core/build/index.js'; import build from '../dist/core/build/index.js';
import { loadConfig } from '../dist/core/config/config.js'; import { openConfig } from '../dist/core/config/config.js';
import { createSettings } from '../dist/core/config/index.js'; import { createSettings } from '../dist/core/config/index.js';
import dev from '../dist/core/dev/index.js'; import dev from '../dist/core/dev/index.js';
import { nodeLogDestination } from '../dist/core/logger/node.js'; import { nodeLogDestination } from '../dist/core/logger/node.js';
@ -86,7 +86,11 @@ export async function loadFixture(inlineConfig) {
const logging = defaultLogging; const logging = defaultLogging;
// Load the config. // Load the config.
let config = await loadConfig({ cwd: fileURLToPath(cwd), logging }); let { astroConfig: config } = await openConfig({
cwd: fileURLToPath(cwd),
logging,
cmd: 'dev',
});
config = merge(config, { ...inlineConfig, root: cwd }); config = merge(config, { ...inlineConfig, root: cwd });
// HACK: the inline config doesn't run through config validation where these normalizations usually occur // HACK: the inline config doesn't run through config validation where these normalizations usually occur

4
pnpm-lock.yaml generated
View file

@ -397,8 +397,6 @@ 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.3
'@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
'@types/babel__traverse': ^7.17.1 '@types/babel__traverse': ^7.17.1
@ -496,8 +494,6 @@ importers:
'@babel/plugin-transform-react-jsx': 7.20.7_@babel+core@7.20.12 '@babel/plugin-transform-react-jsx': 7.20.7_@babel+core@7.20.12
'@babel/traverse': 7.20.12 '@babel/traverse': 7.20.12
'@babel/types': 7.20.7 '@babel/types': 7.20.7
'@proload/core': 0.3.3
'@proload/plugin-tsm': 0.2.1_@proload+core@0.3.3
'@types/babel__core': 7.1.20 '@types/babel__core': 7.1.20
'@types/html-escaper': 3.0.0 '@types/html-escaper': 3.0.0
'@types/yargs-parser': 21.0.0 '@types/yargs-parser': 21.0.0

View file

@ -1,7 +1,8 @@
import { fileURLToPath } from 'url'; import { fileURLToPath } from 'url';
import v8 from 'v8'; import v8 from 'v8';
import dev from '../../packages/astro/dist/core/dev/index.js'; import dev from '../../packages/astro/dist/core/dev/index.js';
import { loadConfig } from '../../packages/astro/dist/core/config.js'; import { openConfig } from '../../packages/astro/dist/core/config.js';
import { nodeLogDestination } from '../../packages/astro/dist/core/logger/node.js';
import prettyBytes from 'pretty-bytes'; import prettyBytes from 'pretty-bytes';
if (!global.gc) { if (!global.gc) {
@ -14,8 +15,13 @@ const isCI = process.argv.includes('--ci');
/** URL directory containing the entire project. */ /** URL directory containing the entire project. */
const projDir = new URL('./project/', import.meta.url); const projDir = new URL('./project/', import.meta.url);
let config = await loadConfig({ let { astroConfig: config } = await openConfig({
cwd: fileURLToPath(projDir), cwd: fileURLToPath(projDir),
logging: {
dest: nodeLogDestination,
level: 'error',
},
cmd: 'dev',
}); });
const telemetry = { const telemetry = {