mirror of
https://github.com/withastro/astro.git
synced 2025-01-06 22:10:10 -05:00
Bugfix: fix getStaticPaths() cache miss (#1602)
This commit is contained in:
parent
d1f42353e8
commit
e1b52506f7
4 changed files with 50 additions and 56 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
import type { InputHTMLOptions } from '@web/rollup-plugin-html';
|
||||||
import type { AstroConfig, ComponentInstance, GetStaticPathsResult, ManifestData, RouteCache, RouteData, RSSResult } from '../../@types/astro-core';
|
import type { AstroConfig, ComponentInstance, GetStaticPathsResult, ManifestData, RouteCache, RouteData, RSSResult } from '../../@types/astro-core';
|
||||||
import type { LogOptions } from '../logger';
|
import type { LogOptions } from '../logger';
|
||||||
|
|
||||||
|
@ -69,49 +70,46 @@ class AstroBuilder {
|
||||||
const viteServer = await vite.createServer(viteConfig);
|
const viteServer = await vite.createServer(viteConfig);
|
||||||
|
|
||||||
// 2. get all routes
|
// 2. get all routes
|
||||||
const allPages: Promise<{ html: string; name: string }>[] = [];
|
const input: InputHTMLOptions[] = [];
|
||||||
const assets: Record<string, string> = {}; // additional assets to be written
|
const assets: Record<string, string> = {}; // additional assets to be written
|
||||||
await Promise.all(
|
for (const route of this.manifest.routes) {
|
||||||
this.manifest.routes.map(async (route) => {
|
const { pathname } = route;
|
||||||
const { pathname } = route;
|
const filePath = new URL(`./${route.component}`, this.config.projectRoot);
|
||||||
const filePath = new URL(`./${route.component}`, this.config.projectRoot);
|
// static pages (note: should these be )
|
||||||
// static pages
|
if (pathname) {
|
||||||
if (pathname) {
|
input.push(
|
||||||
allPages.push(
|
await ssr({ astroConfig: this.config, filePath, logging, mode: 'production', origin, route, routeCache: this.routeCache, pathname, viteServer }).then((html) => ({
|
||||||
ssr({ astroConfig: this.config, filePath, logging, mode: 'production', origin, route, routeCache: this.routeCache, pathname, viteServer }).then((html) => ({
|
html,
|
||||||
html,
|
name: pathname.replace(/\/?$/, '/index.html').replace(/^\//, ''),
|
||||||
name: pathname.replace(/\/?$/, '/index.html').replace(/^\//, ''),
|
}))
|
||||||
}))
|
);
|
||||||
|
}
|
||||||
|
// dynamic pages
|
||||||
|
else {
|
||||||
|
const staticPaths = await this.getStaticPathsForRoute(route, viteServer);
|
||||||
|
// handle RSS (TODO: improve this?)
|
||||||
|
if (staticPaths.rss && staticPaths.rss.xml) {
|
||||||
|
const rssFile = new URL(staticPaths.rss.url.replace(/^\/?/, './'), this.config.dist);
|
||||||
|
if (assets[fileURLToPath(rssFile)]) {
|
||||||
|
throw new Error(
|
||||||
|
`[getStaticPaths] RSS feed ${staticPaths.rss.url} already exists.\nUse \`rss(data, {url: '...'})\` to choose a unique, custom URL. (${route.component})`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
assets[fileURLToPath(rssFile)] = staticPaths.rss.xml;
|
||||||
|
}
|
||||||
|
// TODO: throw error if conflict
|
||||||
|
for (const staticPath of staticPaths.paths) {
|
||||||
|
input.push(
|
||||||
|
await ssr({ astroConfig: this.config, filePath, logging, mode: 'production', origin, route, routeCache: this.routeCache, pathname: staticPath, viteServer }).then(
|
||||||
|
(html) => ({
|
||||||
|
html,
|
||||||
|
name: staticPath.replace(/\/?$/, '/index.html').replace(/^\//, ''),
|
||||||
|
})
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// dynamic pages
|
}
|
||||||
else {
|
}
|
||||||
const staticPaths = await this.getStaticPathsForRoute(route, viteServer);
|
|
||||||
// handle RSS (TODO: improve this?)
|
|
||||||
if (staticPaths.rss && staticPaths.rss.xml) {
|
|
||||||
const rssFile = new URL(staticPaths.rss.url.replace(/^\/?/, './'), this.config.dist);
|
|
||||||
if (assets[fileURLToPath(rssFile)]) {
|
|
||||||
throw new Error(
|
|
||||||
`[getStaticPaths] RSS feed ${staticPaths.rss.url} already exists.\nUse \`rss(data, {url: '...'})\` to choose a unique, custom URL. (${route.component})`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
assets[fileURLToPath(rssFile)] = staticPaths.rss.xml;
|
|
||||||
}
|
|
||||||
// TODO: throw error if conflict
|
|
||||||
staticPaths.paths.forEach((staticPath) => {
|
|
||||||
allPages.push(
|
|
||||||
ssr({ astroConfig: this.config, filePath, logging, mode: 'production', origin, route, routeCache: this.routeCache, pathname: staticPath, viteServer }).then(
|
|
||||||
(html) => ({
|
|
||||||
html,
|
|
||||||
name: staticPath.replace(/\/?$/, '/index.html').replace(/^\//, ''),
|
|
||||||
})
|
|
||||||
)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
const input = await Promise.all(allPages);
|
|
||||||
|
|
||||||
// 3. build with Vite
|
// 3. build with Vite
|
||||||
await vite.build({
|
await vite.build({
|
||||||
|
@ -177,6 +175,7 @@ class AstroBuilder {
|
||||||
validateGetStaticPathsModule(mod);
|
validateGetStaticPathsModule(mod);
|
||||||
const rss = generateRssFunction(this.config.buildOptions.site, route);
|
const rss = generateRssFunction(this.config.buildOptions.site, route);
|
||||||
const staticPaths: GetStaticPathsResult = (await mod.getStaticPaths!({ paginate: generatePaginateFunction(route), rss: rss.generator })).flat();
|
const staticPaths: GetStaticPathsResult = (await mod.getStaticPaths!({ paginate: generatePaginateFunction(route), rss: rss.generator })).flat();
|
||||||
|
this.routeCache[route.component] = staticPaths;
|
||||||
validateGetStaticPathsResult(staticPaths, this.logging);
|
validateGetStaticPathsResult(staticPaths, this.logging);
|
||||||
return {
|
return {
|
||||||
paths: staticPaths.map((staticPath) => staticPath.params && route.generate(staticPath.params)).filter(Boolean),
|
paths: staticPaths.map((staticPath) => staticPath.params && route.generate(staticPath.params)).filter(Boolean),
|
||||||
|
|
|
@ -77,10 +77,10 @@ export async function ssr({ astroConfig, filePath, logging, mode, origin, pathna
|
||||||
// Important this happens before load module in case a renderer provides polyfills.
|
// Important this happens before load module in case a renderer provides polyfills.
|
||||||
const renderers = await resolveRenderers(viteServer, astroConfig.renderers);
|
const renderers = await resolveRenderers(viteServer, astroConfig.renderers);
|
||||||
|
|
||||||
// 1.5. load module
|
// 2. load module
|
||||||
const mod = (await viteServer.ssrLoadModule(fileURLToPath(filePath))) as ComponentInstance;
|
const mod = (await viteServer.ssrLoadModule(fileURLToPath(filePath))) as ComponentInstance;
|
||||||
|
|
||||||
// 2. handle dynamic routes
|
// 3. handle dynamic routes
|
||||||
let params: Params = {};
|
let params: Params = {};
|
||||||
let pageProps: Props = {};
|
let pageProps: Props = {};
|
||||||
if (route && !route.pathname) {
|
if (route && !route.pathname) {
|
||||||
|
@ -91,9 +91,8 @@ export async function ssr({ astroConfig, filePath, logging, mode, origin, pathna
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
validateGetStaticPathsModule(mod);
|
validateGetStaticPathsModule(mod);
|
||||||
routeCache[route.component] =
|
if (!routeCache[route.component]) {
|
||||||
routeCache[route.component] ||
|
routeCache[route.component] = await (
|
||||||
(
|
|
||||||
await mod.getStaticPaths!({
|
await mod.getStaticPaths!({
|
||||||
paginate: generatePaginateFunction(route),
|
paginate: generatePaginateFunction(route),
|
||||||
rss: () => {
|
rss: () => {
|
||||||
|
@ -101,6 +100,7 @@ export async function ssr({ astroConfig, filePath, logging, mode, origin, pathna
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
).flat();
|
).flat();
|
||||||
|
}
|
||||||
validateGetStaticPathsResult(routeCache[route.component], logging);
|
validateGetStaticPathsResult(routeCache[route.component], logging);
|
||||||
const routePathParams: GetStaticPathsResult = routeCache[route.component];
|
const routePathParams: GetStaticPathsResult = routeCache[route.component];
|
||||||
const matchedStaticPath = routePathParams.find(({ params: _params }) => JSON.stringify(_params) === JSON.stringify(params));
|
const matchedStaticPath = routePathParams.find(({ params: _params }) => JSON.stringify(_params) === JSON.stringify(params));
|
||||||
|
@ -110,7 +110,7 @@ export async function ssr({ astroConfig, filePath, logging, mode, origin, pathna
|
||||||
pageProps = { ...matchedStaticPath.props } || {};
|
pageProps = { ...matchedStaticPath.props } || {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. render page
|
// 4. render page
|
||||||
const Component = await mod.default;
|
const Component = await mod.default;
|
||||||
if (!Component) throw new Error(`Expected an exported Astro component but received typeof ${typeof Component}`);
|
if (!Component) throw new Error(`Expected an exported Astro component but received typeof ${typeof Component}`);
|
||||||
|
|
||||||
|
@ -144,12 +144,12 @@ export async function ssr({ astroConfig, filePath, logging, mode, origin, pathna
|
||||||
|
|
||||||
let html = await renderPage(result, Component, pageProps, null);
|
let html = await renderPage(result, Component, pageProps, null);
|
||||||
|
|
||||||
// 4. modify response
|
// 5. modify response
|
||||||
if (mode === 'development') {
|
if (mode === 'development') {
|
||||||
html = await viteServer.transformIndexHtml(fileURLToPath(filePath), html, pathname);
|
html = await viteServer.transformIndexHtml(fileURLToPath(filePath), html, pathname);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. finish
|
// 6. finish
|
||||||
return html;
|
return html;
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
viteServer.ssrFixStacktrace(e);
|
viteServer.ssrFixStacktrace(e);
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
/**
|
|
||||||
* UNCOMMENT: fix "Error: can only be called once!"
|
|
||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
import { loadFixture } from './test-utils';
|
import { loadFixture } from './test-utils.js';
|
||||||
|
|
||||||
let fixture;
|
let fixture;
|
||||||
|
|
||||||
|
@ -22,6 +20,3 @@ describe('getStaticPaths()', () => {
|
||||||
expect(true).to.equal(true);
|
expect(true).to.equal(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
*/
|
|
||||||
|
|
||||||
it.skip('is skipped', () => {});
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
export function getStaticPaths({paginate}) {
|
export function getStaticPaths({ paginate }) {
|
||||||
if (globalThis.isCalledOnce) {
|
if (globalThis.isCalledOnce) {
|
||||||
throw new Error("Can only be called once!");
|
throw new Error("Can only be called once!");
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ export function getStaticPaths({paginate}) {
|
||||||
{params: {test: 'c'}},
|
{params: {test: 'c'}},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
const { params} = Astro.request;
|
const { params } = Astro.request;
|
||||||
---
|
---
|
||||||
|
|
||||||
<html>
|
<html>
|
||||||
|
|
Loading…
Reference in a new issue