mirror of
https://github.com/withastro/astro.git
synced 2024-12-16 21:46:22 -05:00
Preserve generating routes that end with .mjs (#9374)
This commit is contained in:
parent
26f7023d69
commit
65ddb02711
7 changed files with 76 additions and 39 deletions
5
.changeset/shiny-glasses-care.md
Normal file
5
.changeset/shiny-glasses-care.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Fixes an issue where prerendered route paths that end with `.mjs` were removed from the final build
|
|
@ -198,8 +198,8 @@ class AstroBuilder {
|
|||
viteConfig,
|
||||
};
|
||||
|
||||
const { internals } = await viteBuild(opts);
|
||||
await staticBuild(opts, internals);
|
||||
const { internals, ssrOutputChunkNames } = await viteBuild(opts);
|
||||
await staticBuild(opts, internals, ssrOutputChunkNames);
|
||||
|
||||
// Write any additionally generated assets to disk.
|
||||
this.timer.assetsStart = performance.now();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { Plugin as VitePlugin } from 'vite';
|
||||
import type { Plugin as VitePlugin, Rollup } from 'vite';
|
||||
import type { BuildInternals } from './internal.js';
|
||||
import type { StaticBuildOptions, ViteBuildReturn } from './types.js';
|
||||
|
||||
|
@ -68,7 +68,7 @@ export function createPluginContainer(options: StaticBuildOptions, internals: Bu
|
|||
};
|
||||
},
|
||||
|
||||
async runPostHook(ssrReturn: ViteBuildReturn, clientReturn: ViteBuildReturn | null) {
|
||||
async runPostHook(ssrOutputs: Rollup.RollupOutput[], clientOutputs: Rollup.RollupOutput[]) {
|
||||
const mutations = new Map<
|
||||
string,
|
||||
{
|
||||
|
@ -76,20 +76,6 @@ export function createPluginContainer(options: StaticBuildOptions, internals: Bu
|
|||
code: string;
|
||||
}
|
||||
>();
|
||||
const ssrOutputs: RollupOutputArray = [];
|
||||
const clientOutputs: RollupOutputArray = [];
|
||||
|
||||
if (Array.isArray(ssrReturn)) {
|
||||
ssrOutputs.push(...ssrReturn);
|
||||
} else if ('output' in ssrReturn) {
|
||||
ssrOutputs.push(ssrReturn);
|
||||
}
|
||||
|
||||
if (Array.isArray(clientReturn)) {
|
||||
clientOutputs.push(...clientReturn);
|
||||
} else if (clientReturn && 'output' in clientReturn) {
|
||||
clientOutputs.push(clientReturn);
|
||||
}
|
||||
|
||||
const mutate: MutateChunk = (chunk, targets, newCode) => {
|
||||
chunk.code = newCode;
|
||||
|
|
|
@ -33,7 +33,7 @@ import { RESOLVED_RENDERERS_MODULE_ID } from './plugins/plugin-renderers.js';
|
|||
import { RESOLVED_SPLIT_MODULE_ID, RESOLVED_SSR_VIRTUAL_MODULE_ID } from './plugins/plugin-ssr.js';
|
||||
import { ASTRO_PAGE_EXTENSION_POST_PATTERN } from './plugins/util.js';
|
||||
import type { StaticBuildOptions } from './types.js';
|
||||
import { encodeName, getTimeStat } from './util.js';
|
||||
import { encodeName, getTimeStat, viteBuildReturnToRollupOutputs } from './util.js';
|
||||
|
||||
export async function viteBuild(opts: StaticBuildOptions) {
|
||||
const { allPages, settings } = opts;
|
||||
|
@ -103,7 +103,9 @@ export async function viteBuild(opts: StaticBuildOptions) {
|
|||
// Run client build first, so the assets can be fed into the SSR rendered version.
|
||||
const clientOutput = await clientBuild(opts, internals, clientInput, container);
|
||||
|
||||
await runPostBuildHooks(container, ssrOutput, clientOutput);
|
||||
const ssrOutputs = viteBuildReturnToRollupOutputs(ssrOutput);
|
||||
const clientOutputs = viteBuildReturnToRollupOutputs(clientOutput ?? []);
|
||||
await runPostBuildHooks(container, ssrOutputs, clientOutputs);
|
||||
|
||||
settings.timer.end('Client build');
|
||||
|
||||
|
@ -113,23 +115,38 @@ export async function viteBuild(opts: StaticBuildOptions) {
|
|||
teardown();
|
||||
}
|
||||
|
||||
return { internals };
|
||||
// For static builds, the SSR output output won't be needed anymore after page generation.
|
||||
// We keep track of the names here so we only remove these specific files when finished.
|
||||
const ssrOutputChunkNames: string[] = [];
|
||||
for (const output of ssrOutputs) {
|
||||
for (const chunk of output.output) {
|
||||
if (chunk.type === 'chunk') {
|
||||
ssrOutputChunkNames.push(chunk.fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function staticBuild(opts: StaticBuildOptions, internals: BuildInternals) {
|
||||
return { internals, ssrOutputChunkNames };
|
||||
}
|
||||
|
||||
export async function staticBuild(
|
||||
opts: StaticBuildOptions,
|
||||
internals: BuildInternals,
|
||||
ssrOutputChunkNames: string[]
|
||||
) {
|
||||
const { settings } = opts;
|
||||
switch (true) {
|
||||
case settings.config.output === 'static': {
|
||||
settings.timer.start('Static generate');
|
||||
await generatePages(opts, internals);
|
||||
await cleanServerOutput(opts);
|
||||
await cleanServerOutput(opts, ssrOutputChunkNames);
|
||||
settings.timer.end('Static generate');
|
||||
return;
|
||||
}
|
||||
case isServerLikeOutput(settings.config): {
|
||||
settings.timer.start('Server generate');
|
||||
await generatePages(opts, internals);
|
||||
await cleanStaticOutput(opts, internals);
|
||||
await cleanStaticOutput(opts, internals, ssrOutputChunkNames);
|
||||
opts.logger.info(null, `\n${bgMagenta(black(' finalizing server assets '))}\n`);
|
||||
await ssrMoveAssets(opts);
|
||||
settings.timer.end('Server generate');
|
||||
|
@ -324,10 +341,10 @@ async function clientBuild(
|
|||
|
||||
async function runPostBuildHooks(
|
||||
container: AstroBuildPluginContainer,
|
||||
ssrReturn: Awaited<ReturnType<typeof ssrBuild>>,
|
||||
clientReturn: Awaited<ReturnType<typeof clientBuild>>
|
||||
ssrOutputs: vite.Rollup.RollupOutput[],
|
||||
clientOutputs: vite.Rollup.RollupOutput[]
|
||||
) {
|
||||
const mutations = await container.runPostHook(ssrReturn, clientReturn);
|
||||
const mutations = await container.runPostHook(ssrOutputs, clientOutputs);
|
||||
const config = container.options.settings.config;
|
||||
const build = container.options.settings.config.build;
|
||||
for (const [fileName, mutation] of mutations) {
|
||||
|
@ -347,7 +364,11 @@ async function runPostBuildHooks(
|
|||
* For each statically prerendered page, replace their SSR file with a noop.
|
||||
* This allows us to run the SSR build only once, but still remove dependencies for statically rendered routes.
|
||||
*/
|
||||
async function cleanStaticOutput(opts: StaticBuildOptions, internals: BuildInternals) {
|
||||
async function cleanStaticOutput(
|
||||
opts: StaticBuildOptions,
|
||||
internals: BuildInternals,
|
||||
ssrOutputChunkNames: string[]
|
||||
) {
|
||||
const allStaticFiles = new Set();
|
||||
for (const pageData of eachPageData(internals)) {
|
||||
if (pageData.route.prerender) {
|
||||
|
@ -361,10 +382,8 @@ async function cleanStaticOutput(opts: StaticBuildOptions, internals: BuildInter
|
|||
const out = ssr
|
||||
? opts.settings.config.build.server
|
||||
: getOutDirWithinCwd(opts.settings.config.outDir);
|
||||
// The SSR output is all .mjs files, the client output is not.
|
||||
const files = await glob('**/*.mjs', {
|
||||
cwd: fileURLToPath(out),
|
||||
});
|
||||
// The SSR output chunks for Astro are all .mjs files
|
||||
const files = ssrOutputChunkNames.filter((f) => f.endsWith('.mjs'));
|
||||
|
||||
if (files.length) {
|
||||
await eslexer.init;
|
||||
|
@ -394,14 +413,10 @@ async function cleanStaticOutput(opts: StaticBuildOptions, internals: BuildInter
|
|||
}
|
||||
}
|
||||
|
||||
async function cleanServerOutput(opts: StaticBuildOptions) {
|
||||
async function cleanServerOutput(opts: StaticBuildOptions, ssrOutputChunkNames: string[]) {
|
||||
const out = getOutDirWithinCwd(opts.settings.config.outDir);
|
||||
// The SSR output is all .mjs files, the client output is not.
|
||||
const files = await glob('**/*.mjs', {
|
||||
cwd: fileURLToPath(out),
|
||||
// Important! Also cleanup dotfiles like `node_modules/.pnpm/**`
|
||||
dot: true,
|
||||
});
|
||||
// The SSR output chunks for Astro are all .mjs files
|
||||
const files = ssrOutputChunkNames.filter((f) => f.endsWith('.mjs'));
|
||||
if (files.length) {
|
||||
// Remove all the SSR generated .mjs files
|
||||
await Promise.all(
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import type { Rollup } from 'vite';
|
||||
import type { AstroConfig } from '../../@types/astro.js';
|
||||
import type { ViteBuildReturn } from './types.js';
|
||||
|
||||
export function getTimeStat(timeStart: number, timeEnd: number) {
|
||||
const buildTime = timeEnd - timeStart;
|
||||
|
@ -52,3 +54,15 @@ export function encodeName(name: string): string {
|
|||
|
||||
return name;
|
||||
}
|
||||
|
||||
export function viteBuildReturnToRollupOutputs(
|
||||
viteBuildReturn: ViteBuildReturn
|
||||
): Rollup.RollupOutput[] {
|
||||
const result: Rollup.RollupOutput[] = [];
|
||||
if (Array.isArray(viteBuildReturn)) {
|
||||
result.push(...viteBuildReturn);
|
||||
} else if ('output' in viteBuildReturn) {
|
||||
result.push(viteBuildReturn);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -151,6 +151,13 @@ describe('Astro basics', () => {
|
|||
expect($('body > :nth-child(5)').prop('outerHTML')).to.equal('<textarea>textarea</textarea>');
|
||||
});
|
||||
|
||||
it('Generates pages that end with .mjs', async () => {
|
||||
const content1 = await fixture.readFile('/get-static-paths-with-mjs/example.mjs');
|
||||
expect(content1).to.be.ok;
|
||||
const content2 = await fixture.readFile('/get-static-paths-with-mjs/example.js');
|
||||
expect(content2).to.be.ok;
|
||||
});
|
||||
|
||||
describe('preview', () => {
|
||||
it('returns 200 for valid URLs', async () => {
|
||||
const result = await fixture.fetch('/');
|
||||
|
|
10
packages/astro/test/fixtures/astro-basic/src/pages/get-static-paths-with-mjs/[...file].js
vendored
Normal file
10
packages/astro/test/fixtures/astro-basic/src/pages/get-static-paths-with-mjs/[...file].js
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
export function getStaticPaths() {
|
||||
return [
|
||||
{ params: { file: 'example.mjs' } },
|
||||
{ params: { file: 'example.js' } },
|
||||
];
|
||||
}
|
||||
|
||||
export function GET() {
|
||||
return new Response('console.log("fileContent");')
|
||||
}
|
Loading…
Reference in a new issue