@netlify/plugin-nextjs 5.3.0 → 5.4.0-canary-perf-debug.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,4 @@
1
+ import { enableModuleImportTracing } from '{{cwd}}/.netlify/dist/run/handlers/import-time-debug.cjs'
1
2
  import {
2
3
  createRequestContext,
3
4
  runWithRequestContext,
@@ -10,12 +11,16 @@ process.chdir('{{cwd}}')
10
11
  // Set feature flag for regional blobs
11
12
  process.env.USE_REGIONAL_BLOBS = '{{useRegionalBlobs}}'
12
13
 
14
+ if (process.env.NETLIFY_OTLP_TRACE_EXPORTER_URL || process.env.NETLIFY_NEXT_PERF_DEBUG) {
15
+ tracing.start()
16
+ }
17
+
18
+ if (process.env.NETLIFY_NEXT_PERF_DEBUG) {
19
+ enableModuleImportTracing()
20
+ }
21
+
13
22
  let cachedHandler
14
23
  export default async function (req, context) {
15
- if (process.env.NETLIFY_OTLP_TRACE_EXPORTER_URL) {
16
- tracing.start()
17
- }
18
-
19
24
  const requestContext = createRequestContext(req.headers.get('x-next-debug-logging'))
20
25
  const tracer = getTracer()
21
26
 
@@ -1,3 +1,4 @@
1
+ import { enableModuleImportTracing } from './.netlify/dist/run/handlers/import-time-debug.cjs'
1
2
  import {
2
3
  createRequestContext,
3
4
  runWithRequestContext,
@@ -9,10 +10,15 @@ import tracing from './.netlify/dist/run/handlers/tracing.js'
9
10
  // Set feature flag for regional blobs
10
11
  process.env.USE_REGIONAL_BLOBS = '{{useRegionalBlobs}}'
11
12
 
13
+ if (process.env.NETLIFY_OTLP_TRACE_EXPORTER_URL || process.env.NETLIFY_NEXT_PERF_DEBUG) {
14
+ tracing.start()
15
+ }
16
+
17
+ if (process.env.NETLIFY_NEXT_PERF_DEBUG) {
18
+ enableModuleImportTracing()
19
+ }
20
+
12
21
  export default async function handler(req, context) {
13
- if (process.env.NETLIFY_OTLP_TRACE_EXPORTER_URL) {
14
- tracing.start()
15
- }
16
22
  const requestContext = createRequestContext(req.headers.get('x-next-debug-logging'))
17
23
  const tracer = getTracer()
18
24
 
@@ -65,13 +65,6 @@ function verifyNextVersion(ctx, nextVersion) {
65
65
  );
66
66
  }
67
67
  }
68
- function verifyBuildConfig(ctx) {
69
- if (ctx.buildConfig.experimental.ppr) {
70
- console.log(
71
- `Partial prerendering is not yet fully supported on Netlify, see https://ntl.fyi/nextjs-ppr for details`
72
- );
73
- }
74
- }
75
68
  async function verifyNoAdvancedAPIRoutes(ctx) {
76
69
  const apiRoutesConfigs = await getAPIRoutesConfigs(ctx);
77
70
  const unsupportedAPIRoutes = apiRoutesConfigs.filter((apiRouteConfig) => {
@@ -87,7 +80,6 @@ Refer to https://ntl.fyi/next-scheduled-bg-function-migration as migration examp
87
80
  }
88
81
  }
89
82
  export {
90
- verifyBuildConfig,
91
83
  verifyNextVersion,
92
84
  verifyNoAdvancedAPIRoutes,
93
85
  verifyPublishDir
@@ -8,7 +8,7 @@ import "./chunk-OEQOKJGE.js";
8
8
 
9
9
  // package.json
10
10
  var name = "@netlify/plugin-nextjs";
11
- var version = "5.3.0";
11
+ var version = "5.4.0-canary-perf-debug.0";
12
12
  var description = "Run Next.js seamlessly on Netlify";
13
13
  var main = "./dist/index.js";
14
14
  var type = "module";
@@ -58,13 +58,13 @@ var homepage = "https://github.com/netlify/next-runtime-minimal#readme";
58
58
  var devDependencies = {
59
59
  "@fastly/http-compute-js": "1.1.4",
60
60
  "@netlify/blobs": "^7.3.0",
61
- "@netlify/build": "^29.41.5",
61
+ "@netlify/build": "^29.42.2",
62
62
  "@netlify/edge-bundler": "^12.0.1",
63
- "@netlify/edge-functions": "^2.8.0",
63
+ "@netlify/edge-functions": "^2.8.1",
64
64
  "@netlify/eslint-config-node": "^7.0.1",
65
65
  "@netlify/functions": "^2.7.0",
66
- "@netlify/serverless-functions-api": "^1.18.1",
67
- "@netlify/zip-it-and-ship-it": "^9.32.2",
66
+ "@netlify/serverless-functions-api": "^1.18.2",
67
+ "@netlify/zip-it-and-ship-it": "^9.33.0",
68
68
  "@opentelemetry/api": "^1.8.0",
69
69
  "@opentelemetry/exporter-trace-otlp-http": "^0.51.0",
70
70
  "@opentelemetry/resources": "^1.24.0",
package/dist/index.js CHANGED
@@ -29,11 +29,7 @@ import { createEdgeHandlers } from "./build/functions/edge.js";
29
29
  import { createServerHandler } from "./build/functions/server.js";
30
30
  import { setImageConfig } from "./build/image-cdn.js";
31
31
  import { PluginContext } from "./build/plugin-context.js";
32
- import {
33
- verifyBuildConfig,
34
- verifyNoAdvancedAPIRoutes,
35
- verifyPublishDir
36
- } from "./build/verification.js";
32
+ import { verifyNoAdvancedAPIRoutes, verifyPublishDir } from "./build/verification.js";
37
33
  var tracer = wrapTracer(trace.getTracer("Next.js runtime"));
38
34
  var onPreDev = async (options) => {
39
35
  await tracer.withActiveSpan("onPreDev", async () => {
@@ -53,7 +49,6 @@ var onBuild = async (options) => {
53
49
  await tracer.withActiveSpan("onBuild", async (span) => {
54
50
  const ctx = new PluginContext(options);
55
51
  verifyPublishDir(ctx);
56
- verifyBuildConfig(ctx);
57
52
  span.setAttribute("next.buildConfig", JSON.stringify(ctx.buildConfig));
58
53
  if (!options.constants.IS_LOCAL) {
59
54
  await saveBuildCache(ctx);
@@ -170,6 +170,10 @@ var NetlifyCacheHandler = class {
170
170
  span.addEvent("Cache miss", { key, blobKey });
171
171
  return null;
172
172
  }
173
+ if (process.env.NETLIFY_NEXT_PERF_DEBUG) {
174
+ const blobSize = JSON.stringify(blob).length;
175
+ span.addEvent(`Blob size ${blobSize}`);
176
+ }
173
177
  const staleByTags = await this.checkCacheEntryStaleByTags(blob, ctx.tags, ctx.softTags);
174
178
  if (staleByTags) {
175
179
  span.addEvent("Stale", { staleByTags });
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/run/handlers/import-time-debug.cts
21
+ var import_time_debug_exports = {};
22
+ __export(import_time_debug_exports, {
23
+ enableModuleImportTracing: () => enableModuleImportTracing
24
+ });
25
+ module.exports = __toCommonJS(import_time_debug_exports);
26
+ var import_path = require("path");
27
+ var import_tracer = require("./tracer.cjs");
28
+ function enableModuleImportTracing() {
29
+ const cwd = process.cwd();
30
+ const extension = ".js";
31
+ const original = require.extensions[extension];
32
+ if (!original) {
33
+ return;
34
+ }
35
+ require.extensions[extension] = function patchedExtensions(module2, filename) {
36
+ const startTime = Date.now();
37
+ const ret = original(module2, filename);
38
+ const durationMS = Date.now() - startTime;
39
+ if (durationMS > 50) {
40
+ (0, import_tracer.getTracer)().withActiveSpan(
41
+ `module import ${(0, import_path.relative)(cwd, module2.filename)}`,
42
+ { startTime },
43
+ () => {
44
+ }
45
+ );
46
+ }
47
+ return ret;
48
+ };
49
+ }
50
+ // Annotate the CommonJS export names for ESM import in node:
51
+ 0 && (module.exports = {
52
+ enableModuleImportTracing
53
+ });
@@ -3122,6 +3122,7 @@ var disableFaultyTransferEncodingHandling = (res) => {
3122
3122
  };
3123
3123
  var server_default = async (request, context) => {
3124
3124
  const tracer = getTracer();
3125
+ const withPerfDebugSpan = process.env.NETLIFY_NEXT_PERF_DEBUG ? tracer.withActiveSpan.bind(tracer) : (_name, fn) => fn();
3125
3126
  if (!nextHandler) {
3126
3127
  await tracer.withActiveSpan("initialize next server", async (span) => {
3127
3128
  const { getRunConfig, setRunConfig } = await import("../config.js");
@@ -3187,9 +3188,13 @@ var server_default = async (request, context) => {
3187
3188
  }
3188
3189
  const keepOpenUntilNextFullyRendered = new TransformStream({
3189
3190
  async flush() {
3190
- await nextHandlerPromise;
3191
+ await withPerfDebugSpan("awaiting next handler", async () => {
3192
+ await nextHandlerPromise;
3193
+ });
3191
3194
  if (!context.waitUntil) {
3192
- await requestContext.backgroundWorkPromise;
3195
+ await withPerfDebugSpan("awaiting background work", async () => {
3196
+ await requestContext.backgroundWorkPromise;
3197
+ });
3193
3198
  }
3194
3199
  }
3195
3200
  });
@@ -67215,10 +67215,10 @@ var require_sdk = __commonJS({
67215
67215
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
67216
67216
  new sdk_trace_base_1.BatchSpanProcessor(configuration.traceExporter)
67217
67217
  );
67218
- const spanProcessors = (_e = configuration.spanProcessors) !== null && _e !== void 0 ? _e : [spanProcessor];
67218
+ const spanProcessors2 = (_e = configuration.spanProcessors) !== null && _e !== void 0 ? _e : [spanProcessor];
67219
67219
  this._tracerProviderConfig = {
67220
67220
  tracerConfig: tracerProviderConfig,
67221
- spanProcessors,
67221
+ spanProcessors: spanProcessors2,
67222
67222
  contextManager: configuration.contextManager,
67223
67223
  textMapPropagator: configuration.textMapPropagator
67224
67224
  };
@@ -67368,17 +67368,57 @@ var import_semantic_conventions = __toESM(require_src(), 1);
67368
67368
  import { logger } from "../systemlog.cjs";
67369
67369
  var {
67370
67370
  default: { version, name }
67371
- } = await import("../../esm-chunks/package-HC2KHZCZ.js");
67371
+ } = await import("../../esm-chunks/package-NQYUR3EH.js");
67372
+ var spanProcessors = [];
67373
+ if (process.env.NETLIFY_OTLP_TRACE_EXPORTER_URL) {
67374
+ spanProcessors.push(
67375
+ new import_sdk_trace_node.SimpleSpanProcessor(
67376
+ new import_exporter_trace_otlp_http.OTLPTraceExporter({
67377
+ url: process.env.NETLIFY_OTLP_TRACE_EXPORTER_URL
67378
+ })
67379
+ )
67380
+ );
67381
+ }
67382
+ if (process.env.NETLIFY_NEXT_PERF_DEBUG) {
67383
+ class CompactConsoleExporter {
67384
+ export(spans, resultCallback) {
67385
+ return this._sendSpans(spans, resultCallback);
67386
+ }
67387
+ shutdown() {
67388
+ this._sendSpans([]);
67389
+ return this.forceFlush();
67390
+ }
67391
+ forceFlush() {
67392
+ return Promise.resolve();
67393
+ }
67394
+ _sendSpans(spans, done) {
67395
+ for (const span of spans) {
67396
+ const startDate = new Date(span.startTime[0] * 10 ** 3 + span.startTime[1] / 10 ** 6);
67397
+ const durationS = span.duration[0] + span.duration[1] / 10 ** 9;
67398
+ console.log(
67399
+ `[Trace ${span.spanContext().traceId}] ${`"${span.name}"`.padEnd(
67400
+ 60,
67401
+ " "
67402
+ )} start=${startDate.toISOString()} dur=${durationS.toFixed(3)}s${span.events.length === 0 ? "" : ` events=[${span.events.map(
67403
+ (event) => `{ name="${event.name}", time=${new Date(
67404
+ event.time[0] * 10 ** 3 + event.time[1] / 10 ** 6
67405
+ ).toISOString()}}`
67406
+ ).join(", ")}]`}`
67407
+ );
67408
+ }
67409
+ if (done) {
67410
+ return done({ code: 0 });
67411
+ }
67412
+ }
67413
+ }
67414
+ spanProcessors.push(new import_sdk_trace_node.SimpleSpanProcessor(new CompactConsoleExporter()));
67415
+ }
67372
67416
  var sdk = new import_sdk_node.NodeSDK({
67373
67417
  resource: new import_resources.Resource({
67374
67418
  [import_semantic_conventions.SEMRESATTRS_SERVICE_NAME]: name,
67375
67419
  [import_semantic_conventions.SEMRESATTRS_SERVICE_VERSION]: version
67376
67420
  }),
67377
- spanProcessor: new import_sdk_trace_node.SimpleSpanProcessor(
67378
- new import_exporter_trace_otlp_http.OTLPTraceExporter({
67379
- url: process.env.NETLIFY_OTLP_TRACE_EXPORTER_URL
67380
- })
67381
- )
67421
+ spanProcessors
67382
67422
  });
67383
67423
  var tracing_default = sdk;
67384
67424
  process.on("SIGTERM", () => {
package/dist/run/next.cjs CHANGED
@@ -553,7 +553,9 @@ async function getMockedRequestHandlers(...args) {
553
553
  if (typeof path === "string" && path.endsWith(".html")) {
554
554
  const store = (0, import_regional_blob_store.getRegionalBlobStore)();
555
555
  const relPath = (0, import_path.relative)((0, import_path.resolve)(".next/server/pages"), path);
556
- const file = await store.get(await encodeBlobKey(relPath));
556
+ const file = await (0, import_tracer.getTracer)().withActiveSpan(`blob readFile ${relPath}`, async () => {
557
+ return await store.get(await encodeBlobKey(relPath));
558
+ });
557
559
  if (file !== null) {
558
560
  const requestContext = (0, import_request_context.getRequestContext)();
559
561
  if (requestContext) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netlify/plugin-nextjs",
3
- "version": "5.3.0",
3
+ "version": "5.4.0-canary-perf-debug.0",
4
4
  "description": "Run Next.js seamlessly on Netlify",
5
5
  "main": "./dist/index.js",
6
6
  "type": "module",