Skip to content

Commit f07433d

Browse files
teemingcCopilot
authored andcommitted
fix: export Netlify config separately from the serverless function (sveltejs#15335)
This PR ensures the Netlify `config `export can be detected by exporting it directly from the instrumented file. Previously, it was not exported at all. I've also tried adding it as an export to `builder.instrument` but the Netlify dev server could not read the `config` export when it's dynamically imported and awaited alongside the serverless function. --- ### Please don't delete this checklist! Before submitting the PR, please make sure you do the following: - [ ] It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs - [x] This message body should clearly illustrate what problems it solves. - [x] Ideally, include a test that fails without this PR but passes with it. ### Tests - [x] Run the tests with `pnpm test` and lint the project with `pnpm lint` and `pnpm check` ### Changesets - [x] If your PR makes a change that should be noted in one or more packages' changelogs, generate a changeset by running `pnpm changeset` and following the prompts. Changesets that add features should be `minor` and those that fix bugs should be `patch`. Please prefix changeset messages with `feat:`, `fix:`, or `chore:`. ### Edits - [x] Please ensure that 'Allow edits from maintainers' is checked. PRs without this option may be closed.
1 parent 255bb09 commit f07433d

File tree

4 files changed

+72
-20
lines changed

4 files changed

+72
-20
lines changed

.changeset/four-cougars-own.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/adapter-netlify': patch
3+
---
4+
5+
fix: export Netlify config directly from the instrumented serverless function

packages/adapter-netlify/index.js

Lines changed: 60 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -191,16 +191,16 @@ async function generate_edge_functions({ builder }) {
191191
outfile: '.netlify/edge-functions/render.js',
192192
...esbuild_config
193193
}),
194-
builder.hasServerInstrumentationFile?.() &&
194+
builder.hasServerInstrumentationFile() &&
195195
esbuild.build({
196196
entryPoints: [`${builder.getServerDirectory()}/instrumentation.server.js`],
197197
outfile: '.netlify/edge/instrumentation.server.js',
198198
...esbuild_config
199199
})
200200
]);
201201

202-
if (builder.hasServerInstrumentationFile?.()) {
203-
builder.instrument?.({
202+
if (builder.hasServerInstrumentationFile()) {
203+
builder.instrument({
204204
entrypoint: '.netlify/edge-functions/render.js',
205205
instrumentation: '.netlify/edge/instrumentation.server.js',
206206
start: '.netlify/edge/start.js'
@@ -274,37 +274,43 @@ function generate_lambda_functions({ builder, publish, split }) {
274274
routes
275275
});
276276

277-
const fn = `import { init } from '../serverless.js';\n\nexport default init(${manifest});\n\nexport const config = {\n\tpath: "${pattern}",\n\texcludedPath: "/.netlify/*",\n\tpreferStatic: true\n};\n`;
277+
const fn = generate_serverless_function_module(manifest);
278+
const config = generate_config_export(pattern);
278279

279-
writeFileSync(`.netlify/functions-internal/${name}.mjs`, fn);
280-
if (builder.hasServerInstrumentationFile?.()) {
281-
builder.instrument?.({
280+
if (builder.hasServerInstrumentationFile()) {
281+
writeFileSync(`.netlify/functions-internal/${name}.mjs`, fn);
282+
builder.instrument({
282283
entrypoint: `.netlify/functions-internal/${name}.mjs`,
283284
instrumentation: '.netlify/server/instrumentation.server.js',
284285
start: `.netlify/functions-start/${name}.start.mjs`,
285286
module: {
286-
exports: ['default']
287+
generateText: generate_traced_module(config)
287288
}
288289
});
290+
} else {
291+
writeFileSync(`.netlify/functions-internal/${name}.mjs`, `${fn}\n${config}`);
289292
}
290293
}
291294
} else {
292295
const manifest = builder.generateManifest({
293296
relativePath: '../server'
294297
});
295298

296-
const fn = `import { init } from '../serverless.js';\n\nexport default init(${manifest});\n\nexport const config = {\n\tpath: "/*",\n\texcludedPath: "/.netlify/*",\n\tpreferStatic: true\n};\n`;
299+
const fn = generate_serverless_function_module(manifest);
300+
const config = generate_config_export('/*');
297301

298-
writeFileSync(`.netlify/functions-internal/${FUNCTION_PREFIX}render.mjs`, fn);
299-
if (builder.hasServerInstrumentationFile?.()) {
300-
builder.instrument?.({
302+
if (builder.hasServerInstrumentationFile()) {
303+
writeFileSync(`.netlify/functions-internal/${FUNCTION_PREFIX}render.mjs`, fn);
304+
builder.instrument({
301305
entrypoint: `.netlify/functions-internal/${FUNCTION_PREFIX}render.mjs`,
302306
instrumentation: '.netlify/server/instrumentation.server.js',
303307
start: `.netlify/functions-start/${FUNCTION_PREFIX}render.start.mjs`,
304308
module: {
305-
exports: ['default']
309+
generateText: generate_traced_module(config)
306310
}
307311
});
312+
} else {
313+
writeFileSync(`.netlify/functions-internal/${FUNCTION_PREFIX}render.mjs`, `${fn}\n${config}`);
308314
}
309315
}
310316

@@ -386,3 +392,44 @@ function matches(a, b) {
386392
return b.length === 1 && b[0].rest;
387393
}
388394
}
395+
396+
/**
397+
* @param {string} manifest
398+
* @returns {string}
399+
*/
400+
function generate_serverless_function_module(manifest) {
401+
return `\
402+
import { init } from '../serverless.js';
403+
404+
export default init(${manifest});
405+
`;
406+
}
407+
408+
/**
409+
* @param {string} pattern
410+
* @returns {string}
411+
*/
412+
function generate_config_export(pattern) {
413+
return `\
414+
export const config = {
415+
path: "${pattern}",
416+
excludedPath: "/.netlify/*",
417+
preferStatic: true
418+
};
419+
`;
420+
}
421+
422+
/**
423+
* @param {string} config
424+
* @returns {(opts: { instrumentation: string; start: string }) => string}
425+
*/
426+
function generate_traced_module(config) {
427+
return ({ instrumentation, start }) => {
428+
return `\
429+
import './${instrumentation}';
430+
const { default: _0 } = await import('./${start}');
431+
export { _0 as default };
432+
433+
${config}`;
434+
};
435+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,9 @@
11
[build]
22
publish = "build"
3+
4+
# TODO: remove this after we refactor to the Netlify frameworks API
5+
# we are purposely misusing the user functions config to discover our framework
6+
# build output because our adapter still outputs using an older API but the new
7+
# Netlify dev server adheres to the new API
8+
[functions]
9+
directory = ".netlify/functions-internal"

packages/adapter-netlify/test/apps/basic/netlify/functions/render.mjs

Lines changed: 0 additions & 7 deletions
This file was deleted.

0 commit comments

Comments
 (0)