mirror of
https://github.com/withastro/astro.git
synced 2024-12-30 22:03:56 -05:00
fix(astro): static entrypoints build with path with several '.astro' (#10302)
* fix(astro): static entrypoints build with path with several '.astro' * feat: improve replacement logic * fix: logic * chore: improve changeset * chore: move test * Update util.ts * Update .changeset/stale-ducks-protect.md Co-authored-by: Florian Lefebvre <contact@florian-lefebvre.dev> --------- Co-authored-by: Emanuele Stoppa <my.burning@gmail.com>
This commit is contained in:
parent
347d3629b8
commit
992537e79f
5 changed files with 42 additions and 34 deletions
5
.changeset/stale-ducks-protect.md
Normal file
5
.changeset/stale-ducks-protect.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"astro": patch
|
||||
---
|
||||
|
||||
Fixes an issue that causes static entrypoints build to fail because of the path in certain conditions. Specifically, it failed if the path had an extension (like `.astro`, `.mdx` etc) and such extension would be also within the path (like `./.astro/index.astro`).
|
|
@ -15,10 +15,8 @@ import {
|
|||
getPageDataByComponent,
|
||||
mergeInlineCss,
|
||||
} from './internal.js';
|
||||
import {
|
||||
ASTRO_PAGE_RESOLVED_MODULE_ID,
|
||||
getVirtualModulePageNameFromPath,
|
||||
} from './plugins/plugin-pages.js';
|
||||
import { ASTRO_PAGE_MODULE_ID, ASTRO_PAGE_RESOLVED_MODULE_ID } from './plugins/plugin-pages.js';
|
||||
import { getVirtualModulePageNameFromPath } from './plugins/util.js';
|
||||
import { RESOLVED_SPLIT_MODULE_ID } from './plugins/plugin-ssr.js';
|
||||
import { ASTRO_PAGE_EXTENSION_POST_PATTERN } from './plugins/util.js';
|
||||
import type { PageBuildData, StaticBuildOptions } from './types.js';
|
||||
|
@ -215,7 +213,7 @@ export class BuildPipeline extends Pipeline {
|
|||
// The values of the map are the actual `.mjs` files that are generated during the build
|
||||
|
||||
// Here, we take the component path and transform it in the virtual module name
|
||||
const moduleSpecifier = getVirtualModulePageNameFromPath(path);
|
||||
const moduleSpecifier = getVirtualModulePageNameFromPath(ASTRO_PAGE_MODULE_ID, path);
|
||||
// We retrieve the original JS module
|
||||
const filePath = this.internals.entrySpecifierToBundleMap.get(moduleSpecifier);
|
||||
if (filePath) {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { extname } from 'node:path';
|
||||
import type { Plugin as VitePlugin } from 'vite';
|
||||
import { routeIsRedirect } from '../../redirects/index.js';
|
||||
import { addRollupInput } from '../add-rollup-input.js';
|
||||
|
@ -6,29 +5,13 @@ import { type BuildInternals, eachPageFromAllPages } from '../internal.js';
|
|||
import type { AstroBuildPlugin } from '../plugin.js';
|
||||
import type { StaticBuildOptions } from '../types.js';
|
||||
import { RENDERERS_MODULE_ID } from './plugin-renderers.js';
|
||||
import { ASTRO_PAGE_EXTENSION_POST_PATTERN, getPathFromVirtualModulePageName } from './util.js';
|
||||
import { getPathFromVirtualModulePageName, getVirtualModulePageNameFromPath } from './util.js';
|
||||
|
||||
export const ASTRO_PAGE_MODULE_ID = '@astro-page:';
|
||||
export const ASTRO_PAGE_RESOLVED_MODULE_ID = '\0' + ASTRO_PAGE_MODULE_ID;
|
||||
|
||||
/**
|
||||
* 1. We add a fixed prefix, which is used as virtual module naming convention;
|
||||
* 2. We replace the dot that belongs extension with an arbitrary string.
|
||||
*
|
||||
* @param path
|
||||
*/
|
||||
export function getVirtualModulePageNameFromPath(path: string) {
|
||||
// we mask the extension, so this virtual file
|
||||
// so rollup won't trigger other plugins in the process
|
||||
const extension = extname(path);
|
||||
return `${ASTRO_PAGE_MODULE_ID}${path.replace(
|
||||
extension,
|
||||
extension.replace('.', ASTRO_PAGE_EXTENSION_POST_PATTERN)
|
||||
)}`;
|
||||
}
|
||||
|
||||
export function getVirtualModulePageIdFromPath(path: string) {
|
||||
const name = getVirtualModulePageNameFromPath(path);
|
||||
const name = getVirtualModulePageNameFromPath(ASTRO_PAGE_MODULE_ID, path);
|
||||
return '\x00' + name;
|
||||
}
|
||||
|
||||
|
@ -43,7 +26,7 @@ function vitePluginPages(opts: StaticBuildOptions, internals: BuildInternals): V
|
|||
if (routeIsRedirect(pageData.route)) {
|
||||
continue;
|
||||
}
|
||||
inputs.add(getVirtualModulePageNameFromPath(path));
|
||||
inputs.add(getVirtualModulePageNameFromPath(ASTRO_PAGE_MODULE_ID, path));
|
||||
}
|
||||
|
||||
return addRollupInput(options, Array.from(inputs));
|
||||
|
|
|
@ -44,20 +44,20 @@ export function extendManualChunks(outputOptions: OutputOptions, hooks: ExtendMa
|
|||
export const ASTRO_PAGE_EXTENSION_POST_PATTERN = '@_@';
|
||||
|
||||
/**
|
||||
* 1. We add a fixed prefix, which is used as virtual module naming convention;
|
||||
* 2. We replace the dot that belongs extension with an arbitrary string.
|
||||
* Prevents Rollup from triggering other plugins in the process by masking the extension (hence the virtual file).
|
||||
*
|
||||
* 1. We add a fixed prefix, which is used as virtual module naming convention
|
||||
* 2. If the path has an extension (at the end of the path), we replace the dot that belongs to the extension with an arbitrary string.
|
||||
*
|
||||
* @param virtualModulePrefix
|
||||
* @param path
|
||||
*/
|
||||
export function getVirtualModulePageNameFromPath(virtualModulePrefix: string, path: string) {
|
||||
// we mask the extension, so this virtual file
|
||||
// so rollup won't trigger other plugins in the process
|
||||
const extension = extname(path);
|
||||
return `${virtualModulePrefix}${path.replace(
|
||||
extension,
|
||||
extension.replace('.', ASTRO_PAGE_EXTENSION_POST_PATTERN)
|
||||
)}`;
|
||||
return virtualModulePrefix +
|
||||
(extension.startsWith('.')
|
||||
? path.slice(0, -extension.length) + extension.replace('.', ASTRO_PAGE_EXTENSION_POST_PATTERN)
|
||||
: path);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -3,14 +3,18 @@ import { before, describe, it } from 'node:test';
|
|||
import { load as cheerioLoad } from 'cheerio';
|
||||
import testAdapter from './test-adapter.js';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
import { dirname } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { mkdirSync, writeFileSync } from 'node:fs';
|
||||
|
||||
describe('Dynamic pages in SSR', () => {
|
||||
/** @type {import('./test-utils').Fixture} */
|
||||
let fixture;
|
||||
|
||||
before(async () => {
|
||||
const root = './fixtures/ssr-dynamic/';
|
||||
fixture = await loadFixture({
|
||||
root: './fixtures/ssr-dynamic/',
|
||||
root,
|
||||
output: 'server',
|
||||
integrations: [
|
||||
{
|
||||
|
@ -21,6 +25,18 @@ describe('Dynamic pages in SSR', () => {
|
|||
pattern: '/path-alias/[id]',
|
||||
entrypoint: './src/pages/api/products/[id].js',
|
||||
});
|
||||
|
||||
const entrypoint = fileURLToPath(
|
||||
new URL(`${root}.astro/test.astro`, import.meta.url)
|
||||
);
|
||||
console.log(entrypoint)
|
||||
mkdirSync(dirname(entrypoint), { recursive: true });
|
||||
writeFileSync(entrypoint, '<h1>Index</h1>');
|
||||
|
||||
injectRoute({
|
||||
pattern: '/test',
|
||||
entrypoint,
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -80,4 +96,10 @@ describe('Dynamic pages in SSR', () => {
|
|||
const favicon = await matchRoute('/favicon.ico');
|
||||
assert.equal(favicon, undefined);
|
||||
});
|
||||
|
||||
it('injectRoute entrypoint should not fail build if containing the extension several times in the path', async () => {
|
||||
const html = await fetchHTML('/test');
|
||||
const $ = cheerioLoad(html);
|
||||
assert.equal($('h1').text(), 'Index');
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue