Skip to content

Commit ab76a7d

Browse files
committed
Merge remote-tracking branch 'origin/main' into michalpiechowiak/frp-765-migrate-next-runtime-to-use-frameworks-api
2 parents f3b7306 + 325968d commit ab76a7d

File tree

10 files changed

+101
-42
lines changed

10 files changed

+101
-42
lines changed

package-lock.json

+29-29
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
"@netlify/edge-functions": "^2.10.0",
5656
"@netlify/eslint-config-node": "^7.0.1",
5757
"@netlify/functions": "^2.8.1",
58-
"@netlify/serverless-functions-api": "^1.20.0",
58+
"@netlify/serverless-functions-api": "^1.21.0",
5959
"@netlify/zip-it-and-ship-it": "^9.37.3",
6060
"@opentelemetry/api": "^1.8.0",
6161
"@opentelemetry/exporter-trace-otlp-http": "^0.51.0",

src/build/content/server.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -284,9 +284,9 @@ export const copyNextDependencies = async (ctx: PluginContext): Promise<void> =>
284284
await tracer.withActiveSpan('copyNextDependencies', async () => {
285285
const entries = await readdir(ctx.standaloneDir)
286286
const promises: Promise<void>[] = entries.map(async (entry) => {
287-
// copy all except the package.json and distDir (.next) folder as this is handled in a separate function
287+
// copy all except the distDir (.next) folder as this is handled in a separate function
288288
// this will include the node_modules folder as well
289-
if (entry === 'package.json' || entry === ctx.nextDistDir) {
289+
if (entry === ctx.nextDistDir) {
290290
return
291291
}
292292
const src = join(ctx.standaloneDir, entry)

src/build/functions/server.ts

+11-10
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,20 @@ const copyHandlerDependencies = async (ctx: PluginContext) => {
5353
)
5454
}
5555

56+
// We need to create a package.json file with type: module to make sure that the runtime modules
57+
// are handled correctly as ESM modules
58+
promises.push(
59+
writeFile(
60+
join(ctx.serverHandlerRuntimeModulesDir, 'package.json'),
61+
JSON.stringify({ type: 'module' }),
62+
),
63+
)
64+
5665
const fileList = await glob('dist/**/*', { cwd: ctx.pluginDir })
5766

5867
for (const filePath of fileList) {
5968
promises.push(
60-
cp(join(ctx.pluginDir, filePath), join(ctx.serverHandlerDir, '.netlify', filePath), {
69+
cp(join(ctx.pluginDir, filePath), join(ctx.serverHandlerRuntimeModulesDir, filePath), {
6170
recursive: true,
6271
force: true,
6372
}),
@@ -85,13 +94,6 @@ const writeHandlerManifest = async (ctx: PluginContext) => {
8594
)
8695
}
8796

88-
const writePackageMetadata = async (ctx: PluginContext) => {
89-
await writeFile(
90-
join(ctx.serverHandlerRootDir, 'package.json'),
91-
JSON.stringify({ type: 'module' }),
92-
)
93-
}
94-
9597
const applyTemplateVariables = (template: string, variables: Record<string, string>) => {
9698
return Object.entries(variables).reduce((acc, [key, value]) => {
9799
return acc.replaceAll(key, value)
@@ -138,15 +140,14 @@ export const clearStaleServerHandlers = async (ctx: PluginContext) => {
138140
*/
139141
export const createServerHandler = async (ctx: PluginContext) => {
140142
await tracer.withActiveSpan('createServerHandler', async () => {
141-
await mkdir(join(ctx.serverHandlerDir, '.netlify'), { recursive: true })
143+
await mkdir(join(ctx.serverHandlerRuntimeModulesDir), { recursive: true })
142144

143145
await copyNextServerCode(ctx)
144146
await copyNextDependencies(ctx)
145147
await copyHandlerDependencies(ctx)
146148
if (!ctx.useFrameworksAPI) {
147149
await writeHandlerManifest(ctx)
148150
}
149-
await writePackageMetadata(ctx)
150151
await writeHandlerFile(ctx)
151152

152153
await verifyHandlerDirStructure(ctx)

src/build/plugin-context.ts

+4
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,10 @@ export class PluginContext {
233233
return join(this.serverHandlerRootDir, this.distDirParent)
234234
}
235235

236+
get serverHandlerRuntimeModulesDir(): string {
237+
return join(this.serverHandlerDir, '.netlify')
238+
}
239+
236240
get nextServerHandler(): string {
237241
if (this.relativeAppDir.length !== 0) {
238242
return join(this.lambdaWorkingDirectory, '.netlify/dist/run/handlers/server.js')

tests/e2e/simple-app.test.ts

+11
Original file line numberDiff line numberDiff line change
@@ -252,3 +252,14 @@ test('Compressed rewrites are readable', async ({ simple }) => {
252252
expect(resp.headers.get('content-encoding')).toEqual('br')
253253
expect(await resp.text()).toContain('<title>Example Domain</title>')
254254
})
255+
256+
test('can require CJS module that is not bundled', async ({ simple }) => {
257+
const resp = await fetch(`${simple.url}/api/cjs-file-with-js-extension`)
258+
259+
expect(resp.status).toBe(200)
260+
261+
const parsedBody = await resp.json()
262+
263+
expect(parsedBody.notBundledCJSModule.isBundled).toEqual(false)
264+
expect(parsedBody.bundledCJSModule.isBundled).toEqual(true)
265+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
const { parse: pathParse } = require('node:path')
2+
3+
const fileBase = pathParse(__filename).base
4+
5+
module.exports = {
6+
fileBase,
7+
// if fileBase is not the same as this module name, it was bundled
8+
isBundled: fileBase !== 'bundled.cjs',
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { NextResponse } from 'next/server'
2+
import { resolve } from 'node:path'
3+
4+
export async function GET() {
5+
return NextResponse.json({
6+
notBundledCJSModule: __non_webpack_require__(resolve('./cjs-file-with-js-extension.js')),
7+
bundledCJSModule: require('./bundled.cjs'),
8+
})
9+
}
10+
11+
export const dynamic = 'force-dynamic'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
const { parse: pathParse } = require('node:path')
2+
3+
const fileBase = pathParse(__filename).base
4+
5+
module.exports = {
6+
fileBase,
7+
// if fileBase is not the same as this module name, it was bundled
8+
isBundled: fileBase !== 'cjs-file-with-js-extension.js',
9+
}

tests/integration/simple-app.test.ts

+14
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,20 @@ test.skipIf(process.env.NEXT_VERSION !== 'canary')<FixtureTestContext>(
245245
},
246246
)
247247

248+
test<FixtureTestContext>('can require CJS module that is not bundled', async (ctx) => {
249+
await createFixture('simple', ctx)
250+
await runPlugin(ctx)
251+
252+
const response = await invokeFunction(ctx, { url: '/api/cjs-file-with-js-extension' })
253+
254+
expect(response.statusCode).toBe(200)
255+
256+
const parsedBody = JSON.parse(response.body)
257+
258+
expect(parsedBody.notBundledCJSModule.isBundled).toEqual(false)
259+
expect(parsedBody.bundledCJSModule.isBundled).toEqual(true)
260+
})
261+
248262
describe('next patching', async () => {
249263
const { cp: originalCp, appendFile } = (await vi.importActual(
250264
'node:fs/promises',

0 commit comments

Comments
 (0)