Handle builds with outDir outside of cwd (#4736)
This commit is contained in:
parent
a36d51d433
commit
13ca686ea1
4 changed files with 32 additions and 5 deletions
5
.changeset/kind-rats-lay.md
Normal file
5
.changeset/kind-rats-lay.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Handle builds with outDir outside of current working directory
|
|
@ -1,8 +1,10 @@
|
||||||
import npath from 'path';
|
import npath from 'path';
|
||||||
|
import { fileURLToPath, pathToFileURL } from 'url';
|
||||||
import type { AstroConfig, RouteType } from '../../@types/astro';
|
import type { AstroConfig, RouteType } from '../../@types/astro';
|
||||||
import { appendForwardSlash } from '../../core/path.js';
|
import { appendForwardSlash } from '../../core/path.js';
|
||||||
|
|
||||||
const STATUS_CODE_PAGES = new Set(['/404', '/500']);
|
const STATUS_CODE_PAGES = new Set(['/404', '/500']);
|
||||||
|
const FALLBACK_OUT_DIR_NAME = './.astro/';
|
||||||
|
|
||||||
function getOutRoot(astroConfig: AstroConfig): URL {
|
function getOutRoot(astroConfig: AstroConfig): URL {
|
||||||
return new URL('./', astroConfig.outDir);
|
return new URL('./', astroConfig.outDir);
|
||||||
|
@ -59,3 +61,16 @@ export function getOutFile(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures the `outDir` is within `process.cwd()`. If not it will fallback to `<cwd>/.astro`.
|
||||||
|
* This is used for static `ssrBuild` so the output can access node_modules when we import
|
||||||
|
* the output files. A hardcoded fallback dir is fine as it would be cleaned up after build.
|
||||||
|
*/
|
||||||
|
export function getOutDirWithinCwd(outDir: URL): URL {
|
||||||
|
if (fileURLToPath(outDir).startsWith(process.cwd())) {
|
||||||
|
return outDir;
|
||||||
|
} else {
|
||||||
|
return new URL(FALLBACK_OUT_DIR_NAME, pathToFileURL(process.cwd() + npath.sep));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ import { createLinkStylesheetElementSet, createModuleScriptsSet } from '../rende
|
||||||
import { createRequest } from '../request.js';
|
import { createRequest } from '../request.js';
|
||||||
import { matchRoute } from '../routing/match.js';
|
import { matchRoute } from '../routing/match.js';
|
||||||
import { getOutputFilename } from '../util.js';
|
import { getOutputFilename } from '../util.js';
|
||||||
import { getOutFile, getOutFolder } from './common.js';
|
import { getOutDirWithinCwd, getOutFile, getOutFolder } from './common.js';
|
||||||
import { eachPageData, getPageDataByComponent, sortedCSS } from './internal.js';
|
import { eachPageData, getPageDataByComponent, sortedCSS } from './internal.js';
|
||||||
import type { PageBuildData, SingleFileBuiltModule, StaticBuildOptions } from './types';
|
import type { PageBuildData, SingleFileBuiltModule, StaticBuildOptions } from './types';
|
||||||
import { getTimeStat } from './util.js';
|
import { getTimeStat } from './util.js';
|
||||||
|
@ -103,7 +103,7 @@ export async function generatePages(opts: StaticBuildOptions, internals: BuildIn
|
||||||
|
|
||||||
const ssr = opts.astroConfig.output === 'server';
|
const ssr = opts.astroConfig.output === 'server';
|
||||||
const serverEntry = opts.buildConfig.serverEntry;
|
const serverEntry = opts.buildConfig.serverEntry;
|
||||||
const outFolder = ssr ? opts.buildConfig.server : opts.astroConfig.outDir;
|
const outFolder = ssr ? opts.buildConfig.server : getOutDirWithinCwd(opts.astroConfig.outDir);
|
||||||
const ssrEntryURL = new URL('./' + serverEntry + `?time=${Date.now()}`, outFolder);
|
const ssrEntryURL = new URL('./' + serverEntry + `?time=${Date.now()}`, outFolder);
|
||||||
const ssrEntry = await import(ssrEntryURL.toString());
|
const ssrEntry = await import(ssrEntryURL.toString());
|
||||||
const builtPaths = new Set<string>();
|
const builtPaths = new Set<string>();
|
||||||
|
|
|
@ -10,6 +10,7 @@ import { runHookBuildSetup } from '../../integrations/index.js';
|
||||||
import { PAGE_SCRIPT_ID } from '../../vite-plugin-scripts/index.js';
|
import { PAGE_SCRIPT_ID } from '../../vite-plugin-scripts/index.js';
|
||||||
import type { ViteConfigWithSSR } from '../create-vite';
|
import type { ViteConfigWithSSR } from '../create-vite';
|
||||||
import { info } from '../logger/core.js';
|
import { info } from '../logger/core.js';
|
||||||
|
import { getOutDirWithinCwd } from './common.js';
|
||||||
import { generatePages } from './generate.js';
|
import { generatePages } from './generate.js';
|
||||||
import { trackPageData } from './internal.js';
|
import { trackPageData } from './internal.js';
|
||||||
import type { PageBuildData, StaticBuildOptions } from './types';
|
import type { PageBuildData, StaticBuildOptions } from './types';
|
||||||
|
@ -110,7 +111,7 @@ Learn more: https://docs.astro.build/en/guides/server-side-rendering/
|
||||||
async function ssrBuild(opts: StaticBuildOptions, internals: BuildInternals, input: Set<string>) {
|
async function ssrBuild(opts: StaticBuildOptions, internals: BuildInternals, input: Set<string>) {
|
||||||
const { astroConfig, viteConfig } = opts;
|
const { astroConfig, viteConfig } = opts;
|
||||||
const ssr = astroConfig.output === 'server';
|
const ssr = astroConfig.output === 'server';
|
||||||
const out = ssr ? opts.buildConfig.server : astroConfig.outDir;
|
const out = ssr ? opts.buildConfig.server : getOutDirWithinCwd(astroConfig.outDir);
|
||||||
|
|
||||||
const viteBuildConfig: ViteConfigWithSSR = {
|
const viteBuildConfig: ViteConfigWithSSR = {
|
||||||
...viteConfig,
|
...viteConfig,
|
||||||
|
@ -245,13 +246,19 @@ async function clientBuild(
|
||||||
}
|
}
|
||||||
|
|
||||||
async function cleanSsrOutput(opts: StaticBuildOptions) {
|
async function cleanSsrOutput(opts: StaticBuildOptions) {
|
||||||
|
const out = getOutDirWithinCwd(opts.astroConfig.outDir);
|
||||||
|
// Clean out directly if the outDir is outside of root
|
||||||
|
if (out.toString() !== opts.astroConfig.outDir.toString()) {
|
||||||
|
await fs.promises.rm(out, { recursive: true });
|
||||||
|
return;
|
||||||
|
}
|
||||||
// The SSR output is all .mjs files, the client output is not.
|
// The SSR output is all .mjs files, the client output is not.
|
||||||
const files = await glob('**/*.mjs', {
|
const files = await glob('**/*.mjs', {
|
||||||
cwd: fileURLToPath(opts.astroConfig.outDir),
|
cwd: fileURLToPath(out),
|
||||||
});
|
});
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
files.map(async (filename) => {
|
files.map(async (filename) => {
|
||||||
const url = new URL(filename, opts.astroConfig.outDir);
|
const url = new URL(filename, out);
|
||||||
await fs.promises.rm(url);
|
await fs.promises.rm(url);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue