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:
parent
54d87af012
commit
49ab4f231c
8 changed files with 65 additions and 128 deletions
5
.changeset/calm-peas-doubt.md
Normal file
5
.changeset/calm-peas-doubt.md
Normal 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.
|
|
@ -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",
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
4
pnpm-lock.yaml
generated
|
@ -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
|
||||||
|
|
|
@ -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 = {
|
||||||
|
|
Loading…
Add table
Reference in a new issue