mirror of
https://github.com/withastro/astro.git
synced 2025-02-03 22:29:08 -05:00
Move getStaticPaths call to happen during generation (#4047)
* Move getStaticPaths call to happen during generation * Adds a changeset * Update routing-priority.test.js * revert test change, clarify test purpose * Keep track of paths that have already been built Co-authored-by: Fred K. Schott <fkschott@gmail.com>
This commit is contained in:
parent
adf8cde10f
commit
453c026aa7
10 changed files with 143 additions and 88 deletions
5
.changeset/old-stingrays-smoke.md
Normal file
5
.changeset/old-stingrays-smoke.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Perf: move getStaticPaths call during the build to during page generation
|
|
@ -9,8 +9,9 @@ import type {
|
||||||
EndpointHandler,
|
EndpointHandler,
|
||||||
SSRLoadedRenderer,
|
SSRLoadedRenderer,
|
||||||
} from '../../@types/astro';
|
} from '../../@types/astro';
|
||||||
|
import * as colors from 'kleur/colors';
|
||||||
import type { BuildInternals } from '../../core/build/internal.js';
|
import type { BuildInternals } from '../../core/build/internal.js';
|
||||||
import { joinPaths, prependForwardSlash, removeLeadingForwardSlash } from '../../core/path.js';
|
import { joinPaths, prependForwardSlash, removeLeadingForwardSlash, removeTrailingForwardSlash } from '../../core/path.js';
|
||||||
import type { RenderOptions } from '../../core/render/core';
|
import type { RenderOptions } from '../../core/render/core';
|
||||||
import { BEFORE_HYDRATION_SCRIPT_ID } from '../../vite-plugin-scripts/index.js';
|
import { BEFORE_HYDRATION_SCRIPT_ID } from '../../vite-plugin-scripts/index.js';
|
||||||
import { call as callEndpoint } from '../endpoint/index.js';
|
import { call as callEndpoint } from '../endpoint/index.js';
|
||||||
|
@ -23,6 +24,8 @@ import { getOutFile, getOutFolder } from './common.js';
|
||||||
import { eachPageData, getPageDataByComponent } from './internal.js';
|
import { eachPageData, getPageDataByComponent } 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';
|
||||||
|
import { callGetStaticPaths, RouteCache, RouteCacheEntry } from '../render/route-cache.js';
|
||||||
|
import { matchRoute } from '../routing/match.js';
|
||||||
|
|
||||||
// Render is usually compute, which Node.js can't parallelize well.
|
// Render is usually compute, which Node.js can't parallelize well.
|
||||||
// In real world testing, dropping from 10->1 showed a notiable perf
|
// In real world testing, dropping from 10->1 showed a notiable perf
|
||||||
|
@ -89,10 +92,8 @@ export function chunkIsPage(
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function generatePages(
|
export async function generatePages(
|
||||||
result: RollupOutput,
|
|
||||||
opts: StaticBuildOptions,
|
opts: StaticBuildOptions,
|
||||||
internals: BuildInternals,
|
internals: BuildInternals,
|
||||||
facadeIdToPageDataMap: Map<string, PageBuildData>
|
|
||||||
) {
|
) {
|
||||||
const timer = performance.now();
|
const timer = performance.now();
|
||||||
info(opts.logging, null, `\n${bgGreen(black(' generating static routes '))}`);
|
info(opts.logging, null, `\n${bgGreen(black(' generating static routes '))}`);
|
||||||
|
@ -102,19 +103,20 @@ export async function generatePages(
|
||||||
const outFolder = ssr ? opts.buildConfig.server : opts.astroConfig.outDir;
|
const outFolder = ssr ? opts.buildConfig.server : 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>;
|
||||||
|
|
||||||
for (const pageData of eachPageData(internals)) {
|
for (const pageData of eachPageData(internals)) {
|
||||||
await generatePage(opts, internals, pageData, ssrEntry);
|
await generatePage(opts, internals, pageData, ssrEntry, builtPaths);
|
||||||
}
|
}
|
||||||
info(opts.logging, null, dim(`Completed in ${getTimeStat(timer, performance.now())}.\n`));
|
info(opts.logging, null, dim(`Completed in ${getTimeStat(timer, performance.now())}.\n`));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function generatePage(
|
async function generatePage(
|
||||||
//output: OutputChunk,
|
|
||||||
opts: StaticBuildOptions,
|
opts: StaticBuildOptions,
|
||||||
internals: BuildInternals,
|
internals: BuildInternals,
|
||||||
pageData: PageBuildData,
|
pageData: PageBuildData,
|
||||||
ssrEntry: SingleFileBuiltModule
|
ssrEntry: SingleFileBuiltModule,
|
||||||
|
builtPaths: Set<string>,
|
||||||
) {
|
) {
|
||||||
let timeStart = performance.now();
|
let timeStart = performance.now();
|
||||||
const renderers = ssrEntry.renderers;
|
const renderers = ssrEntry.renderers;
|
||||||
|
@ -148,18 +150,89 @@ async function generatePage(
|
||||||
const icon = pageData.route.type === 'page' ? green('▶') : magenta('λ');
|
const icon = pageData.route.type === 'page' ? green('▶') : magenta('λ');
|
||||||
info(opts.logging, null, `${icon} ${pageData.route.component}`);
|
info(opts.logging, null, `${icon} ${pageData.route.component}`);
|
||||||
|
|
||||||
for (let i = 0; i < pageData.paths.length; i++) {
|
// Get paths for the route, calling getStaticPaths if needed.
|
||||||
const path = pageData.paths[i];
|
const paths = await getPathsForRoute(pageData, pageModule, opts, builtPaths);
|
||||||
|
|
||||||
|
for (let i = 0; i < paths.length; i++) {
|
||||||
|
const path = paths[i];
|
||||||
await generatePath(path, opts, generationOptions);
|
await generatePath(path, opts, generationOptions);
|
||||||
const timeEnd = performance.now();
|
const timeEnd = performance.now();
|
||||||
const timeChange = getTimeStat(timeStart, timeEnd);
|
const timeChange = getTimeStat(timeStart, timeEnd);
|
||||||
const timeIncrease = `(+${timeChange})`;
|
const timeIncrease = `(+${timeChange})`;
|
||||||
const filePath = getOutputFilename(opts.astroConfig, path);
|
const filePath = getOutputFilename(opts.astroConfig, path);
|
||||||
const lineIcon = i === pageData.paths.length - 1 ? '└─' : '├─';
|
const lineIcon = i === paths.length - 1 ? '└─' : '├─';
|
||||||
info(opts.logging, null, ` ${cyan(lineIcon)} ${dim(filePath)} ${dim(timeIncrease)}`);
|
info(opts.logging, null, ` ${cyan(lineIcon)} ${dim(filePath)} ${dim(timeIncrease)}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getPathsForRoute(
|
||||||
|
pageData: PageBuildData,
|
||||||
|
mod: ComponentInstance,
|
||||||
|
opts: StaticBuildOptions,
|
||||||
|
builtPaths: Set<string>,
|
||||||
|
): Promise<Array<string>> {
|
||||||
|
let paths: Array<string> = [];
|
||||||
|
if(pageData.route.pathname) {
|
||||||
|
paths.push(pageData.route.pathname);
|
||||||
|
builtPaths.add(pageData.route.pathname);
|
||||||
|
} else {
|
||||||
|
const route = pageData.route;
|
||||||
|
const result = await callGetStaticPaths({
|
||||||
|
mod,
|
||||||
|
route: pageData.route,
|
||||||
|
isValidate: false,
|
||||||
|
logging: opts.logging,
|
||||||
|
ssr: opts.astroConfig.output === 'server'
|
||||||
|
})
|
||||||
|
.then((_result) => {
|
||||||
|
const label = _result.staticPaths.length === 1 ? 'page' : 'pages';
|
||||||
|
debug(
|
||||||
|
'build',
|
||||||
|
`├── ${colors.bold(colors.green('✔'))} ${route.component} → ${colors.magenta(
|
||||||
|
`[${_result.staticPaths.length} ${label}]`
|
||||||
|
)}`
|
||||||
|
);
|
||||||
|
return _result;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
debug('build', `├── ${colors.bold(colors.red('✗'))} ${route.component}`);
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Save the route cache so it doesn't get called again
|
||||||
|
opts.routeCache.set(route, result);
|
||||||
|
|
||||||
|
paths = result.staticPaths
|
||||||
|
.map((staticPath) => staticPath.params && route.generate(staticPath.params))
|
||||||
|
.filter((staticPath) => {
|
||||||
|
// Remove empty or undefined paths
|
||||||
|
if (!staticPath) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The path hasn't been built yet, include it
|
||||||
|
if (!builtPaths.has(removeTrailingForwardSlash(staticPath))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The path was already built once. Check the manifest to see if
|
||||||
|
// this route takes priority for the final URL.
|
||||||
|
// NOTE: The same URL may match multiple routes in the manifest.
|
||||||
|
// Routing priority needs to be verified here for any duplicate
|
||||||
|
// paths to ensure routing priority rules are enforced in the final build.
|
||||||
|
const matchedRoute = matchRoute(staticPath, opts.manifest);
|
||||||
|
return matchedRoute === route;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add each path to the builtPaths set, to avoid building it again later.
|
||||||
|
for(const staticPath of paths) {
|
||||||
|
builtPaths.add(removeTrailingForwardSlash(staticPath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
interface GeneratePathOptions {
|
interface GeneratePathOptions {
|
||||||
pageData: PageBuildData;
|
pageData: PageBuildData;
|
||||||
internals: BuildInternals;
|
internals: BuildInternals;
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
import type { ViteDevServer } from 'vite';
|
import type { ViteDevServer } from 'vite';
|
||||||
import type { AstroConfig, ComponentInstance, ManifestData, RouteData } from '../../@types/astro';
|
import type { AstroConfig, ManifestData } from '../../@types/astro';
|
||||||
import type { LogOptions } from '../logger/core';
|
import type { LogOptions } from '../logger/core';
|
||||||
import { info } from '../logger/core.js';
|
import { info } from '../logger/core.js';
|
||||||
import type { AllPagesData } from './types';
|
import type { AllPagesData } from './types';
|
||||||
|
|
||||||
import * as colors from 'kleur/colors';
|
import * as colors from 'kleur/colors';
|
||||||
import { fileURLToPath } from 'url';
|
|
||||||
import { debug } from '../logger/core.js';
|
import { debug } from '../logger/core.js';
|
||||||
import { removeTrailingForwardSlash } from '../path.js';
|
import { RouteCache } from '../render/route-cache.js';
|
||||||
import { callGetStaticPaths, RouteCache, RouteCacheEntry } from '../render/route-cache.js';
|
|
||||||
import { matchRoute } from '../routing/match.js';
|
|
||||||
|
|
||||||
export interface CollectPagesDataOptions {
|
export interface CollectPagesDataOptions {
|
||||||
astroConfig: AstroConfig;
|
astroConfig: AstroConfig;
|
||||||
|
@ -30,7 +27,7 @@ export interface CollectPagesDataResult {
|
||||||
export async function collectPagesData(
|
export async function collectPagesData(
|
||||||
opts: CollectPagesDataOptions
|
opts: CollectPagesDataOptions
|
||||||
): Promise<CollectPagesDataResult> {
|
): Promise<CollectPagesDataResult> {
|
||||||
const { astroConfig, logging, manifest, origin, routeCache, viteServer } = opts;
|
const { astroConfig, manifest } = opts;
|
||||||
|
|
||||||
const assets: Record<string, string> = {};
|
const assets: Record<string, string> = {};
|
||||||
const allPages: AllPagesData = {};
|
const allPages: AllPagesData = {};
|
||||||
|
@ -61,7 +58,6 @@ export async function collectPagesData(
|
||||||
allPages[route.component] = {
|
allPages[route.component] = {
|
||||||
component: route.component,
|
component: route.component,
|
||||||
route,
|
route,
|
||||||
paths: [route.pathname],
|
|
||||||
moduleSpecifier: '',
|
moduleSpecifier: '',
|
||||||
css: new Set(),
|
css: new Set(),
|
||||||
hoistedScript: undefined,
|
hoistedScript: undefined,
|
||||||
|
@ -80,49 +76,9 @@ export async function collectPagesData(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// dynamic route:
|
// dynamic route:
|
||||||
const result = await getStaticPathsForRoute(opts, route)
|
|
||||||
.then((_result) => {
|
|
||||||
const label = _result.staticPaths.length === 1 ? 'page' : 'pages';
|
|
||||||
debug(
|
|
||||||
'build',
|
|
||||||
`├── ${colors.bold(colors.green('✔'))} ${route.component} → ${colors.magenta(
|
|
||||||
`[${_result.staticPaths.length} ${label}]`
|
|
||||||
)}`
|
|
||||||
);
|
|
||||||
return _result;
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
debug('build', `├── ${colors.bold(colors.red('✗'))} ${route.component}`);
|
|
||||||
throw err;
|
|
||||||
});
|
|
||||||
const finalPaths = result.staticPaths
|
|
||||||
.map((staticPath) => staticPath.params && route.generate(staticPath.params))
|
|
||||||
.filter((staticPath) => {
|
|
||||||
// Remove empty or undefined paths
|
|
||||||
if (!staticPath) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The path hasn't been built yet, include it
|
|
||||||
if (!builtPaths.has(removeTrailingForwardSlash(staticPath))) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The path was already built once. Check the manifest to see if
|
|
||||||
// this route takes priority for the final URL.
|
|
||||||
// NOTE: The same URL may match multiple routes in the manifest.
|
|
||||||
// Routing priority needs to be verified here for any duplicate
|
|
||||||
// paths to ensure routing priority rules are enforced in the final build.
|
|
||||||
const matchedRoute = matchRoute(staticPath, manifest);
|
|
||||||
return matchedRoute === route;
|
|
||||||
});
|
|
||||||
|
|
||||||
finalPaths.map((staticPath) => builtPaths.add(removeTrailingForwardSlash(staticPath)));
|
|
||||||
|
|
||||||
allPages[route.component] = {
|
allPages[route.component] = {
|
||||||
component: route.component,
|
component: route.component,
|
||||||
route,
|
route,
|
||||||
paths: finalPaths,
|
|
||||||
moduleSpecifier: '',
|
moduleSpecifier: '',
|
||||||
css: new Set(),
|
css: new Set(),
|
||||||
hoistedScript: undefined,
|
hoistedScript: undefined,
|
||||||
|
@ -133,16 +89,3 @@ export async function collectPagesData(
|
||||||
|
|
||||||
return { assets, allPages };
|
return { assets, allPages };
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getStaticPathsForRoute(
|
|
||||||
opts: CollectPagesDataOptions,
|
|
||||||
route: RouteData
|
|
||||||
): Promise<RouteCacheEntry> {
|
|
||||||
const { astroConfig, logging, routeCache, ssr, viteServer } = opts;
|
|
||||||
if (!viteServer) throw new Error(`vite.createServer() not called!`);
|
|
||||||
const filePath = new URL(`./${route.component}`, astroConfig.root);
|
|
||||||
const mod = (await viteServer.ssrLoadModule(fileURLToPath(filePath))) as ComponentInstance;
|
|
||||||
const result = await callGetStaticPaths({ mod, route, isValidate: false, logging, ssr });
|
|
||||||
routeCache.set(route, result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import glob from 'fast-glob';
|
import glob from 'fast-glob';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import { bgGreen, bgMagenta, black, dim } from 'kleur/colors';
|
import { bgGreen, bgMagenta, black, dim } from 'kleur/colors';
|
||||||
import type { RollupOutput } from 'rollup';
|
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import * as vite from 'vite';
|
import * as vite from 'vite';
|
||||||
import { BuildInternals, createBuildInternals } from '../../core/build/internal.js';
|
import { BuildInternals, createBuildInternals } from '../../core/build/internal.js';
|
||||||
|
@ -72,7 +71,7 @@ Example:
|
||||||
// Build your project (SSR application code, assets, client JS, etc.)
|
// Build your project (SSR application code, assets, client JS, etc.)
|
||||||
timer.ssr = performance.now();
|
timer.ssr = performance.now();
|
||||||
info(opts.logging, 'build', `Building ${astroConfig.output} entrypoints...`);
|
info(opts.logging, 'build', `Building ${astroConfig.output} entrypoints...`);
|
||||||
const ssrResult = (await ssrBuild(opts, internals, pageInput)) as RollupOutput;
|
await ssrBuild(opts, internals, pageInput);
|
||||||
info(opts.logging, 'build', dim(`Completed in ${getTimeStat(timer.ssr, performance.now())}.`));
|
info(opts.logging, 'build', dim(`Completed in ${getTimeStat(timer.ssr, performance.now())}.`));
|
||||||
|
|
||||||
const rendererClientEntrypoints = opts.astroConfig._ctx.renderers
|
const rendererClientEntrypoints = opts.astroConfig._ctx.renderers
|
||||||
|
@ -93,7 +92,7 @@ Example:
|
||||||
timer.generate = performance.now();
|
timer.generate = performance.now();
|
||||||
if (astroConfig.output === 'static') {
|
if (astroConfig.output === 'static') {
|
||||||
try {
|
try {
|
||||||
await generatePages(ssrResult, opts, internals, facadeIdToPageDataMap);
|
await generatePages(opts, internals);
|
||||||
} finally {
|
} finally {
|
||||||
await cleanSsrOutput(opts);
|
await cleanSsrOutput(opts);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ export type ViteID = string;
|
||||||
|
|
||||||
export interface PageBuildData {
|
export interface PageBuildData {
|
||||||
component: ComponentPath;
|
component: ComponentPath;
|
||||||
paths: string[];
|
|
||||||
route: RouteData;
|
route: RouteData;
|
||||||
moduleSpecifier: string;
|
moduleSpecifier: string;
|
||||||
css: Set<string>;
|
css: Set<string>;
|
||||||
|
|
|
@ -52,14 +52,17 @@ describe('getStaticPaths - 404 behavior', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getStaticPaths - route params type validation', () => {
|
describe('getStaticPaths - route params type validation', () => {
|
||||||
let fixture;
|
let fixture, devServer;
|
||||||
let devServer;
|
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
fixture = await loadFixture({ root: './fixtures/astro-get-static-paths/' });
|
fixture = await loadFixture({ root: './fixtures/astro-get-static-paths/' });
|
||||||
devServer = await fixture.startDevServer();
|
devServer = await fixture.startDevServer();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
after(async () => {
|
||||||
|
await devServer.stop();
|
||||||
|
});
|
||||||
|
|
||||||
it('resolves 200 on matching static path - string params', async () => {
|
it('resolves 200 on matching static path - string params', async () => {
|
||||||
// route provided with { params: { year: "2022", slug: "post-2" }}
|
// route provided with { params: { year: "2022", slug: "post-2" }}
|
||||||
const res = await fixture.fetch('/blog/2022/post-1');
|
const res = await fixture.fetch('/blog/2022/post-1');
|
||||||
|
|
30
packages/astro/test/fixtures/lit-element/src/pages/[page].astro
vendored
Normal file
30
packages/astro/test/fixtures/lit-element/src/pages/[page].astro
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
---
|
||||||
|
import {MyElement} from '../components/my-element.js';
|
||||||
|
export async function getStaticPaths() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
params: { page: 1 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
params: { page: 2 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
params: { page: 3 }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
const { page } = Astro.params
|
||||||
|
---
|
||||||
|
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<title>Posts Page {page}</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Welcome to page {page}</h1>
|
||||||
|
<MyElement />
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -1,4 +1,5 @@
|
||||||
---
|
---
|
||||||
|
// This route should take priority over src/pages/[lang]/index.astro
|
||||||
---
|
---
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
|
@ -7,6 +8,7 @@
|
||||||
<title>Routing</title>
|
<title>Routing</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>de/index.astro</h1>
|
<h1>de/index.astro (priority)</h1>
|
||||||
|
<p>de</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -80,4 +80,9 @@ describe('LitElement test', function () {
|
||||||
// has named slot content in lightdom
|
// has named slot content in lightdom
|
||||||
expect($(namedSlot).text()).to.equal('named');
|
expect($(namedSlot).text()).to.equal('named');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Is able to build when behind getStaticPaths', async () => {
|
||||||
|
const dynamicPage = await fixture.readFile('/1/index.html');
|
||||||
|
expect(dynamicPage.length).to.be.greaterThan(0);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -103,7 +103,7 @@ describe('Routing priority', () => {
|
||||||
const html = await fixture.readFile('/de/index.html');
|
const html = await fixture.readFile('/de/index.html');
|
||||||
const $ = cheerioLoad(html);
|
const $ = cheerioLoad(html);
|
||||||
|
|
||||||
expect($('h1').text()).to.equal('de/index.astro');
|
expect($('h1').text()).to.equal('de/index.astro (priority)');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('matches /en to [lang]/index.astro', async () => {
|
it('matches /en to [lang]/index.astro', async () => {
|
||||||
|
@ -169,28 +169,24 @@ describe('Routing priority', () => {
|
||||||
const html = await fixture.fetch('/de').then((res) => res.text());
|
const html = await fixture.fetch('/de').then((res) => res.text());
|
||||||
const $ = cheerioLoad(html);
|
const $ = cheerioLoad(html);
|
||||||
|
|
||||||
expect($('h1').text()).to.equal('de/index.astro');
|
expect($('h1').text()).to.equal('de/index.astro (priority)');
|
||||||
});
|
expect($('p').text()).to.equal('de');
|
||||||
|
|
||||||
it('matches /de to de/index.astro', async () => {
|
|
||||||
const html = await fixture.fetch('/de').then((res) => res.text());
|
|
||||||
const $ = cheerioLoad(html);
|
|
||||||
|
|
||||||
expect($('h1').text()).to.equal('de/index.astro');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('matches /de/ to de/index.astro', async () => {
|
it('matches /de/ to de/index.astro', async () => {
|
||||||
const html = await fixture.fetch('/de/').then((res) => res.text());
|
const html = await fixture.fetch('/de/').then((res) => res.text());
|
||||||
const $ = cheerioLoad(html);
|
const $ = cheerioLoad(html);
|
||||||
|
|
||||||
expect($('h1').text()).to.equal('de/index.astro');
|
expect($('h1').text()).to.equal('de/index.astro (priority)');
|
||||||
|
expect($('p').text()).to.equal('de');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('matches /de/index.html to de/index.astro', async () => {
|
it('matches /de/index.html to de/index.astro', async () => {
|
||||||
const html = await fixture.fetch('/de/index.html').then((res) => res.text());
|
const html = await fixture.fetch('/de/index.html').then((res) => res.text());
|
||||||
const $ = cheerioLoad(html);
|
const $ = cheerioLoad(html);
|
||||||
|
|
||||||
expect($('h1').text()).to.equal('de/index.astro');
|
expect($('h1').text()).to.equal('de/index.astro (priority)');
|
||||||
|
expect($('p').text()).to.equal('de');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('matches /en to [lang]/index.astro', async () => {
|
it('matches /en to [lang]/index.astro', async () => {
|
||||||
|
|
Loading…
Add table
Reference in a new issue