summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Bjorn Lu <bjornlu.dev@gmail.com> 2022-09-14 21:24:35 +0800
committerGravatar GitHub <noreply@github.com> 2022-09-14 21:24:35 +0800
commit13ca686ea18346a68db6af37348ee6d50719350d (patch)
treea5bdad0538281b39870106a43d3c7efa3b52d6fd
parenta36d51d433af48c0859840bd468d3a6af65b0b0a (diff)
downloadastro-13ca686ea18346a68db6af37348ee6d50719350d.tar.gz
astro-13ca686ea18346a68db6af37348ee6d50719350d.tar.zst
astro-13ca686ea18346a68db6af37348ee6d50719350d.zip
Handle builds with outDir outside of cwd (#4736)
-rw-r--r--.changeset/kind-rats-lay.md5
-rw-r--r--packages/astro/src/core/build/common.ts15
-rw-r--r--packages/astro/src/core/build/generate.ts4
-rw-r--r--packages/astro/src/core/build/static-build.ts13
4 files changed, 32 insertions, 5 deletions
diff --git a/.changeset/kind-rats-lay.md b/.changeset/kind-rats-lay.md
new file mode 100644
index 000000000..9278f6d6e
--- /dev/null
+++ b/.changeset/kind-rats-lay.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Handle builds with outDir outside of current working directory
diff --git a/packages/astro/src/core/build/common.ts b/packages/astro/src/core/build/common.ts
index 8b57334d8..94c96a263 100644
--- a/packages/astro/src/core/build/common.ts
+++ b/packages/astro/src/core/build/common.ts
@@ -1,8 +1,10 @@
import npath from 'path';
+import { fileURLToPath, pathToFileURL } from 'url';
import type { AstroConfig, RouteType } from '../../@types/astro';
import { appendForwardSlash } from '../../core/path.js';
const STATUS_CODE_PAGES = new Set(['/404', '/500']);
+const FALLBACK_OUT_DIR_NAME = './.astro/';
function getOutRoot(astroConfig: AstroConfig): URL {
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));
+ }
+}
diff --git a/packages/astro/src/core/build/generate.ts b/packages/astro/src/core/build/generate.ts
index b6ebf4697..378409c5a 100644
--- a/packages/astro/src/core/build/generate.ts
+++ b/packages/astro/src/core/build/generate.ts
@@ -28,7 +28,7 @@ import { createLinkStylesheetElementSet, createModuleScriptsSet } from '../rende
import { createRequest } from '../request.js';
import { matchRoute } from '../routing/match.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 type { PageBuildData, SingleFileBuiltModule, StaticBuildOptions } from './types';
import { getTimeStat } from './util.js';
@@ -103,7 +103,7 @@ export async function generatePages(opts: StaticBuildOptions, internals: BuildIn
const ssr = opts.astroConfig.output === 'server';
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 ssrEntry = await import(ssrEntryURL.toString());
const builtPaths = new Set<string>();
diff --git a/packages/astro/src/core/build/static-build.ts b/packages/astro/src/core/build/static-build.ts
index e471f6652..0e91dc548 100644
--- a/packages/astro/src/core/build/static-build.ts
+++ b/packages/astro/src/core/build/static-build.ts
@@ -10,6 +10,7 @@ import { runHookBuildSetup } from '../../integrations/index.js';
import { PAGE_SCRIPT_ID } from '../../vite-plugin-scripts/index.js';
import type { ViteConfigWithSSR } from '../create-vite';
import { info } from '../logger/core.js';
+import { getOutDirWithinCwd } from './common.js';
import { generatePages } from './generate.js';
import { trackPageData } from './internal.js';
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>) {
const { astroConfig, viteConfig } = opts;
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 = {
...viteConfig,
@@ -245,13 +246,19 @@ async function clientBuild(
}
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.
const files = await glob('**/*.mjs', {
- cwd: fileURLToPath(opts.astroConfig.outDir),
+ cwd: fileURLToPath(out),
});
await Promise.all(
files.map(async (filename) => {
- const url = new URL(filename, opts.astroConfig.outDir);
+ const url = new URL(filename, out);
await fs.promises.rm(url);
})
);