Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/astro/src/core/build/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export class BuildApp extends BaseApp<BuildPipeline> {

public setOptions(options: StaticBuildOptions) {
this.pipeline.setOptions(options);
this.logger = options.logger;
}

public getOptions() {
Expand Down
2 changes: 2 additions & 0 deletions packages/astro/src/core/build/plugins/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { pluginMiddleware } from './plugin-middleware.js';
import { pluginPrerender } from './plugin-prerender.js';
import { pluginScripts } from './plugin-scripts.js';
import { pluginSSR } from './plugin-ssr.js';
import { pluginNoop } from './plugin-noop.js';

export function getAllBuildPlugins(
internals: BuildInternals,
Expand All @@ -27,5 +28,6 @@ export function getAllBuildPlugins(
pluginPrerender(options, internals),
pluginScripts(internals),
...pluginSSR(options, internals),
pluginNoop(),
].filter(Boolean);
}
5 changes: 4 additions & 1 deletion packages/astro/src/core/build/plugins/plugin-manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ async function buildManifest(
const assetQueryParams = settings.adapter?.client?.assetQueryParams;
const assetQueryString = assetQueryParams ? assetQueryParams.toString() : undefined;

const appendAssetQuery = (pth: string) => assetQueryString ? `${pth}?${assetQueryString}` : pth;

const prefixAssetPath = (pth: string) => {
let result = '';
if (settings.config.build.assetsPrefix) {
Expand Down Expand Up @@ -228,7 +230,7 @@ async function buildManifest(

scripts.push({
type: 'external',
value: src,
value: appendAssetQuery(src),
});
}

Expand All @@ -238,6 +240,7 @@ async function buildManifest(
const styles = pageData.styles
.sort(cssOrder)
.map(({ sheet }) => sheet)
.map((s) => (s.type === 'external' ? { ...s, src: appendAssetQuery(s.src) } : s))
.reduce(mergeInlineCss, []);

routes.push({
Expand Down
33 changes: 33 additions & 0 deletions packages/astro/src/core/build/plugins/plugin-noop.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import type * as vite from 'vite';

export const NOOP_MODULE_ID = 'virtual:astro:noop';
const RESOLVED_NOOP_MODULE_ID = '\0' + NOOP_MODULE_ID;

// An empty module that does nothing. This can be used as a placeholder
// when you just need a module to be in the graph.
// We use this for the client build when there are no client modules,
// because the publicDir copying happens in the client build.
export function pluginNoop(): vite.Plugin {
return {
name: 'plugin-noop',
resolveId(id) {
if(id === NOOP_MODULE_ID) {
return RESOLVED_NOOP_MODULE_ID;
}
},
load(id) {
if(id === RESOLVED_NOOP_MODULE_ID) {
return '';
}
},
generateBundle(_options, bundle) {
// Delete this bundle so that its not written out to disk.
for(const [name, chunk] of Object.entries(bundle)) {
if(chunk.type === 'asset') continue;
if(chunk.facadeModuleId === RESOLVED_NOOP_MODULE_ID) {
delete bundle[name];
}
}
}
}
}
20 changes: 11 additions & 9 deletions packages/astro/src/core/build/static-build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { 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, viteBuildReturnToRollupOutputs } from './util.js';
import { NOOP_MODULE_ID } from './plugins/plugin-noop.js';

const PRERENDER_ENTRY_FILENAME_PREFIX = 'prerender-entry';

Expand Down Expand Up @@ -120,8 +121,6 @@ export async function staticBuild(
*/
async function buildEnvironments(opts: StaticBuildOptions, internals: BuildInternals) {
const { allPages, settings, viteConfig } = opts;
const ssr = settings.buildOutput === 'server';
const out = getServerOutputDirectory(settings);
const routes = Object.values(allPages).flatMap((pageData) => pageData.route);

// Determine if we should use the legacy-dynamic entrypoint
Expand All @@ -141,9 +140,8 @@ async function buildEnvironments(opts: StaticBuildOptions, internals: BuildInter
cssMinify: viteConfig.build?.minify == null ? true : !!viteConfig.build?.minify,
...viteConfig.build,
emptyOutDir: false,
copyPublicDir: false,
manifest: false,
outDir: fileURLToPath(out),
copyPublicDir: !ssr,
rollupOptions: {
...viteConfig.build?.rollupOptions,
// Setting as `exports-only` allows us to safely delete inputs that are only used during prerendering
Expand Down Expand Up @@ -212,7 +210,7 @@ async function buildEnvironments(opts: StaticBuildOptions, internals: BuildInter
prerender: {
build: {
emitAssets: true,
outDir: fileURLToPath(new URL('./.prerender/', out)),
outDir: fileURLToPath(new URL('./.prerender/', getServerOutputDirectory(settings))),
rollupOptions: {
input: 'astro/entrypoints/prerender',
output: {
Expand All @@ -228,9 +226,8 @@ async function buildEnvironments(opts: StaticBuildOptions, internals: BuildInter
build: {
emitAssets: true,
target: 'esnext',
emptyOutDir: false,
outDir: fileURLToPath(getClientOutputDirectory(settings)),
copyPublicDir: ssr,
copyPublicDir: true,
sourcemap: viteConfig.environments?.client?.build?.sourcemap ?? false,
minify: true,
rollupOptions: {
Expand Down Expand Up @@ -282,9 +279,14 @@ async function buildEnvironments(opts: StaticBuildOptions, internals: BuildInter
// are only detected during SSR. We mutate the config here since the builder was already created
// and this is the only way to update the input after instantiation.
internals.clientInput = getClientInput(internals, settings);
if(!internals.clientInput.size) {
// At least 1 input is required to do a build, otherwise Vite throws.
// We need the client build to happen in order to copy over the `public/` folder
// So using the noop plugin here which will give us an input that just gets thrown away.
internals.clientInput.add(NOOP_MODULE_ID);
}
builder.environments.client.config.build.rollupOptions.input = Array.from(internals.clientInput);
const clientOutput =
internals.clientInput.size === 0 ? [] : await builder.build(builder.environments.client);
const clientOutput = await builder.build(builder.environments.client);

return { ssrOutput, prerenderOutput, clientOutput };
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ export function getStaticPaths() {
{ params: { category: "%23something" } },
{ params: { category: "%2Fsomething" } },
{ params: { category: "%3Fsomething" } },
{ params: { category: "%25something" } },
{ params: { category: "[page]" } },
{ params: { category: "你好" } },
]
Expand Down
6 changes: 0 additions & 6 deletions packages/astro/test/params.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,4 @@ describe('Astro.params in static mode', () => {
const $ = cheerio.load(html);
assert.equal($('.category').text(), '%3Fsomething');
});

it("It doesn't encode/decode URI characters such as %25 (%)", async () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is removed because we can no longer support this. The reason this worked before was we used the result of getStaticPaths during static builds directly. Now we produce paths and send the requests through app.render(request), so the params are in the URL. Those params get decoded for security reasons which we fixed in GHSA-hr2q-hp5q-x767

These are not encoded in SSR so they no longer can be in static.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This requires a major changeset, with a thorough explanation of why we can't support this anymore. Worth adding a ticket for that

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added an issue to the board

const html = await fixture.readFile(encodeURI('/%25something/index.html'));
const $ = cheerio.load(html);
assert.equal($('.category').text(), '%25something');
});
});
Loading