Skip to content

Commit

Permalink
fix(next): do not generate conflicting lambdas when using basePath wi…
Browse files Browse the repository at this point in the history
…th app router (#10738)

When using `basePath` with statically generated routes, the builder
currently generates lambdas for the root route that conflict with the
prerender functions generated.

E.g. if we have `basePath: "test"` and a root route at: `app/page.js`,
this is currently the output:

```
test
test.rsc
test/index
test/index.rsc
```

The result is that visiting the deployed app at `/test` renders an
incomplete page. On the other hand visiting `/test/index` outputs the
expected markup.

It seems like the intent is that we want to delete the lambdas that
conflict with the prerender functions. I've updated the lambda name
generation logic when doing the deleting to line up with how the lambda
names are generated initially.
  • Loading branch information
BRKalow committed Nov 3, 2023
1 parent c0efce2 commit 33cc8e0
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/silver-rice-rescue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@vercel/next': patch
---

Fixes a case where using `basePath` along with static generation would output a lambda that conflicts with the root route.
5 changes: 4 additions & 1 deletion packages/next/src/server-build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1132,7 +1132,10 @@ export async function serverBuild({
route = normalizeLocalePath(route, routesManifest.i18n.locales).pathname;
}
delete lambdas[
path.posix.join('.', entryDirectory, route === '/' ? 'index' : route)
normalizeIndexOutput(
path.posix.join('./', entryDirectory, route === '/' ? '/index' : route),
true
)
];
});

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const Layout = ({ children }) => {
return (
<html>
<body>{children}</body>
</html>
);
};

export default Layout;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const Home = () => {
return <div>Home</div>;
};

export default Home;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
basePath: '/test',
};

module.exports = nextConfig;
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"dependencies": {
"next": "canary",
"react": "latest",
"react-dom": "latest"
},
"ignoreNextjsUpdates": true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"version": 2,
"builds": [{ "src": "package.json", "use": "@vercel/next" }]
}
23 changes: 23 additions & 0 deletions packages/next/test/integration/integration-2.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -441,3 +441,26 @@ it('should handle edge functions in app with basePath', async () => {
expect(lambdas.size).toBe(1);
expect(edgeFunctions.size).toBe(4);
});

it('should not generate lambdas that conflict with static index route in app with basePath', async () => {
const {
buildResult: { output },
} = await runBuildLambda(path.join(__dirname, 'app-router-basepath'));

expect(output['test']).not.toBeDefined();
expect(output['test.rsc']).not.toBeDefined();
expect(output['test/index'].type).toBe('Prerender');
expect(output['test/index.rsc'].type).toBe('Prerender');

expect(output['test/_not-found']).toBeDefined();
expect(output['test/_not-found'].type).toBe('Lambda');

const lambdas = new Set();

for (const item of Object.values(output)) {
if (item.type === 'Lambda') {
lambdas.add(item);
}
}
expect(lambdas.size).toBe(1);
});

0 comments on commit 33cc8e0

Please sign in to comment.