Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(astro): static entrypoints build with path with several '.astro' #10302

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/stale-ducks-protect.md
@@ -0,0 +1,5 @@
---
"astro": patch
---

Fixes an issue that causes static entrypoints build to fail when the entrypoint path contains `.astro` times.
florian-lefebvre marked this conversation as resolved.
Show resolved Hide resolved
8 changes: 3 additions & 5 deletions packages/astro/src/core/build/pipeline.ts
Expand Up @@ -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';
Expand Down Expand Up @@ -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) {
Expand Down
23 changes: 3 additions & 20 deletions packages/astro/src/core/build/plugins/plugin-pages.ts
@@ -1,34 +1,17 @@
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';
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;
}

Expand All @@ -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));
Expand Down
10 changes: 6 additions & 4 deletions packages/astro/src/core/build/plugins/util.ts
Expand Up @@ -54,10 +54,12 @@ export function getVirtualModulePageNameFromPath(virtualModulePrefix: string, pa
// 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 === '.astro'
? path.slice(0, -extension.length) + `${ASTRO_PAGE_EXTENSION_POST_PATTERN}astro`
: path)
);
florian-lefebvre marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand Down
@@ -0,0 +1,6 @@
import { defineConfig } from 'astro/config'
import test from './integration.js'

export default defineConfig({
integrations: [test()]
})
@@ -0,0 +1,21 @@
import { writeFileSync, mkdirSync } from "node:fs"
import { fileURLToPath } from "node:url"
import { dirname } from "node:path"

export default function() {
return {
name: '@astrojs/test-integration',
hooks: {
'astro:config:setup': ({ injectRoute, config }) => {
const entrypoint = fileURLToPath(new URL('./.astro/test.astro', config.root))
mkdirSync(dirname(entrypoint), { recursive: true })
writeFileSync(entrypoint, '<h1>Index</h1>')

injectRoute({
pattern: '/',
entrypoint
})
}
}
}
}
florian-lefebvre marked this conversation as resolved.
Show resolved Hide resolved
@@ -0,0 +1,9 @@
{
"name": "@test/integration-inject-route-entrypoint",
"type": "module",
"version": "0.0.0",
"private": true,
"dependencies": {
"astro": "workspace:*"
}
}
17 changes: 17 additions & 0 deletions packages/astro/test/integration-inject-route-entrypoint.test.js
@@ -0,0 +1,17 @@
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import { loadFixture } from './test-utils.js';

describe('Integration injectRoute entrypoint', () => {
it('injectRoute entrypoint should not fail build if containing `.astro` before the extension', async () => {
const fixture = await loadFixture({ root: './fixtures/integration-inject-route-entrypoint/' });

let error = false;
try {
await fixture.build()
} catch (err) {
error = true
}
assert.equal(error, false);
});
});
6 changes: 6 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.