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

Add CLI option to ignore invalid functions #867

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 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
5 changes: 5 additions & 0 deletions .changeset/hot-forks-try.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@cloudflare/next-on-pages': minor
---

Add `force` CLI option to ignore invalid functions
10 changes: 9 additions & 1 deletion packages/next-on-pages/src/buildApplication/buildApplication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export async function buildApplication({
watch,
outdir: outputDir,
customEntrypoint,
force,
}: Pick<
CliOptions,
| 'skipBuild'
Expand All @@ -38,6 +39,7 @@ export async function buildApplication({
| 'watch'
| 'outdir'
| 'customEntrypoint'
| 'force'
>) {
const pm = await getPackageManager();

Expand Down Expand Up @@ -87,6 +89,7 @@ export async function buildApplication({
disableChunksDedup,
disableWorkerMinification,
customEntrypoint,
force,
});

const totalBuildTime = ((Date.now() - buildStartTime) / 1000).toFixed(2);
Expand All @@ -99,9 +102,13 @@ async function prepareAndBuildWorker(
disableChunksDedup,
disableWorkerMinification,
customEntrypoint,
force,
}: Pick<
CliOptions,
'disableChunksDedup' | 'disableWorkerMinification' | 'customEntrypoint'
| 'disableChunksDedup'
| 'disableWorkerMinification'
| 'customEntrypoint'
| 'force'
>,
): Promise<void> {
let vercelConfig: VercelConfig;
Expand Down Expand Up @@ -137,6 +144,7 @@ async function prepareAndBuildWorker(
nopDistDir,
disableChunksDedup,
vercelConfig,
ignoreInvalidFunctions: force,
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export type ProcessVercelFunctionsOpts = {
nopDistDir: string;
disableChunksDedup?: boolean;
vercelConfig: VercelConfig;
ignoreInvalidFunctions: boolean;
};

export type ProcessedVercelFunctions = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { isUsingAppRouter, isUsingPagesRouter } from '../getVercelConfig';
type InvalidFunctionsOpts = Pick<
ProcessVercelFunctionsOpts,
'functionsDir' | 'vercelConfig'
>;
> & { ignoreInvalidFunctions?: boolean };

/**
* Checks if there are any invalid functions from the Vercel build output.
Expand Down Expand Up @@ -46,7 +46,10 @@ export async function checkInvalidFunctions(
await tryToFixInvalidFuncsWithValidIndexAlternative(collectedFunctions);
await tryToFixInvalidDynamicISRFuncs(collectedFunctions);

if (collectedFunctions.invalidFunctions.size > 0) {
if (
collectedFunctions.invalidFunctions.size > 0 &&
!opts.ignoreInvalidFunctions
Copy link
Contributor

Choose a reason for hiding this comment

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

my concern with this approach is that people may find and use --force because they get this error, without actually accounting for the routes properly... In your case, you want to host these routes elsewhere, but I imagine there'll be people who don't realise they need to actually specify these routes should execute somewhere else, and expect it to just work by forcing a build.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same. I don't enjoy the thought of forcing a build.

I worry that the alternative of trying to better evaluate the next.config to determine if the function is actually invalid may be fraught with difficulty (I've not looked too closely, so I'll defer to your judgement). Is this what you had in mind?

Would printing a warning instead of exiting be sufficient? So the errors aren't swept under the rug.

From a connotation perspective, I find force to be ok, but I'm happy to rename the argument as well

) {
await printInvalidFunctionsErrorMessage(
collectedFunctions.invalidFunctions,
);
Expand Down
2 changes: 2 additions & 0 deletions packages/next-on-pages/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ program
'--custom-entrypoint <path>',
'Wrap the generated worker for your application in a custom worker entrypoint',
)
.option('-f, --force', 'Ignore checks for edge runtime compatibility', false)
.enablePositionalOptions(false)
.version(
nextOnPagesVersion,
Expand All @@ -79,6 +80,7 @@ export type CliOptions = {
info?: boolean;
outdir: string;
customEntrypoint?: string;
force: boolean;
};

export function parseCliArgs(): CliOptions {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -341,4 +341,54 @@ describe('checkInvalidFunctions', () => {
mockedConsoleError.restore();
mockedConsoleWarn.restore();
});

test('should ignore invalid functions when opted in', async () => {
const processExitMock = vi
.spyOn(process, 'exit')
.mockImplementation(async () => undefined as never);

const { collectedFunctions, restoreFsMock } = await collectFunctionsFrom({
functions: {
'[dynamic-1].func': prerenderFuncDir,
'edge-route.func': edgeFuncDir,
},
});

const opts = {
functionsDir,
outputDir: resolve('.vercel/output/static'),
vercelConfig: { version: 3 as const },
ignoreInvalidFunctions: true,
};

await processEdgeFunctions(collectedFunctions);
await processPrerenderFunctions(collectedFunctions, opts);
await checkInvalidFunctions(collectedFunctions, opts);
restoreFsMock();

const {
edgeFunctions,
prerenderedFunctions,
invalidFunctions,
ignoredFunctions,
} = collectedFunctions;

expect(edgeFunctions.size).toEqual(1);
expect(prerenderedFunctions.size).toEqual(0);
expect(invalidFunctions.size).toEqual(1);
expect(ignoredFunctions.size).toEqual(0);

expect(getRouteInfo(edgeFunctions, 'edge-route.func')).toEqual({
path: '/edge-route',
overrides: [],
});

expect([...invalidFunctions.keys()]).toEqual([
resolve(functionsDir, '[dynamic-1].func'),
]);

expect(processExitMock).not.toBeCalled();

processExitMock.mockRestore();
});
});
Loading