0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-03-24 23:21:57 -05:00

fix(actions): resolve actions when there aren't user actions (#11525)

* fix(actions): pass path as input

* revert code

* chore: apply suggestions
This commit is contained in:
Emanuele Stoppa 2024-07-22 13:15:34 +01:00 committed by GitHub
parent dfbca06dda
commit 80681318c6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 68 additions and 10 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Fixes a case where the build was failing when `experimental.actions` was enabled, an adapter was in use, and there were not actions inside the user code base.

View file

@ -1,3 +1,6 @@
export const VIRTUAL_MODULE_ID = 'astro:actions';
export const RESOLVED_VIRTUAL_MODULE_ID = '\0' + VIRTUAL_MODULE_ID;
export const ACTIONS_TYPES_FILE = 'actions.d.ts';
export const VIRTUAL_INTERNAL_MODULE_ID = 'astro:internal-actions';
export const RESOLVED_VIRTUAL_INTERNAL_MODULE_ID = '\0astro:internal-actions';
export const NOOP_ACTIONS = '\0noop-actions';

View file

@ -1,12 +1,25 @@
import fsMod from 'node:fs';
import type { Plugin as VitePlugin } from 'vite';
import type { AstroIntegration } from '../@types/astro.js';
import type { AstroIntegration, AstroSettings } from '../@types/astro.js';
import { ActionsWithoutServerOutputError } from '../core/errors/errors-data.js';
import { AstroError } from '../core/errors/errors.js';
import { isServerLikeOutput, viteID } from '../core/util.js';
import { ACTIONS_TYPES_FILE, RESOLVED_VIRTUAL_MODULE_ID, VIRTUAL_MODULE_ID } from './consts.js';
import {
ACTIONS_TYPES_FILE,
NOOP_ACTIONS,
RESOLVED_VIRTUAL_INTERNAL_MODULE_ID,
RESOLVED_VIRTUAL_MODULE_ID,
VIRTUAL_INTERNAL_MODULE_ID,
VIRTUAL_MODULE_ID,
} from './consts.js';
export default function astroActions({ fs = fsMod }: { fs?: typeof fsMod }): AstroIntegration {
export default function astroActions({
fs = fsMod,
settings,
}: {
fs?: typeof fsMod;
settings: AstroSettings;
}): AstroIntegration {
return {
name: VIRTUAL_MODULE_ID,
hooks: {
@ -22,10 +35,7 @@ export default function astroActions({ fs = fsMod }: { fs?: typeof fsMod }): Ast
);
params.updateConfig({
vite: {
define: {
'import.meta.env.ACTIONS_PATH': stringifiedActionsImport,
},
plugins: [vitePluginActions(fs)],
plugins: [vitePluginUserActions({ settings }), vitePluginActions(fs)],
},
});
@ -50,6 +60,42 @@ export default function astroActions({ fs = fsMod }: { fs?: typeof fsMod }): Ast
};
}
/**
* This plugin is responsible to load the known file `actions/index.js` / `actions.js`
* If the file doesn't exist, it returns an empty object.
* @param settings
*/
export function vitePluginUserActions({ settings }: { settings: AstroSettings }): VitePlugin {
let resolvedActionsId: string;
return {
name: '@astro/plugin-actions',
async resolveId(id) {
if (id === NOOP_ACTIONS) {
return NOOP_ACTIONS;
}
if (id === VIRTUAL_INTERNAL_MODULE_ID) {
const resolvedModule = await this.resolve(
`${decodeURI(new URL('actions', settings.config.srcDir).pathname)}`
);
if (!resolvedModule) {
return NOOP_ACTIONS;
}
resolvedActionsId = resolvedModule.id;
return RESOLVED_VIRTUAL_INTERNAL_MODULE_ID;
}
},
load(id) {
if (id === NOOP_ACTIONS) {
return 'export const server = {}';
} else if (id === RESOLVED_VIRTUAL_INTERNAL_MODULE_ID) {
return `export { server } from '${resolvedActionsId}';`;
}
},
};
}
const vitePluginActions = (fs: typeof fsMod): VitePlugin => ({
name: VIRTUAL_MODULE_ID,
enforce: 'pre',

View file

@ -12,14 +12,16 @@ export type MaybePromise<T> = T | Promise<T>;
/**
* Get server-side action based on the route path.
* Imports from `import.meta.env.ACTIONS_PATH`, which maps to
* Imports from the virtual module `astro:internal-actions`, which maps to
* the user's `src/actions/index.ts` file at build-time.
*/
export async function getAction(
path: string
): Promise<((param: unknown) => MaybePromise<unknown>) | undefined> {
const pathKeys = path.replace('/_actions/', '').split('.');
let { server: actionLookup } = await import(import.meta.env.ACTIONS_PATH);
// @ts-expect-error virtual module
let { server: actionLookup } = await import('astro:internal-actions');
for (const key of pathKeys) {
if (!(key in actionLookup)) {
return undefined;

View file

@ -119,7 +119,7 @@ export async function runHookConfigSetup({
}
if (settings.config.experimental?.actions) {
const { default: actionsIntegration } = await import('../actions/index.js');
settings.config.integrations.push(actionsIntegration({ fs }));
settings.config.integrations.push(actionsIntegration({ fs, settings }));
}
let updatedConfig: AstroConfig = { ...settings.config };
@ -230,9 +230,11 @@ export async function runHookConfigSetup({
const exts = (input.flat(Infinity) as string[]).map((ext) => `.${ext.replace(/^\./, '')}`);
updatedSettings.pageExtensions.push(...exts);
}
function addContentEntryType(contentEntryType: ContentEntryType) {
updatedSettings.contentEntryTypes.push(contentEntryType);
}
function addDataEntryType(dataEntryType: DataEntryType) {
updatedSettings.dataEntryTypes.push(dataEntryType);
}