@edgeone/opennextjs-pages 0.1.4 → 0.1.5-beta.1

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.
@@ -2455,11 +2455,14 @@ async function compileTurbopack(inputPath, middlewareCode, options = {}) {
2455
2455
  }
2456
2456
  const externalChunks = [];
2457
2457
  const middlewareChunks = [];
2458
+ const libraryChunks = [];
2458
2459
  for (const chunkPath of chunkPaths) {
2459
2460
  if (chunkPath.includes("[externals]")) {
2460
2461
  externalChunks.push(chunkPath);
2461
2462
  } else if (chunkPath.includes("[root-of-the-server]")) {
2462
2463
  middlewareChunks.push(chunkPath);
2464
+ } else {
2465
+ libraryChunks.push(chunkPath);
2463
2466
  }
2464
2467
  }
2465
2468
  const chunksCode = [];
@@ -2474,6 +2477,17 @@ async function compileTurbopack(inputPath, middlewareCode, options = {}) {
2474
2477
  warnings.push(`External chunk not found: ${fullPath}`);
2475
2478
  }
2476
2479
  }
2480
+ for (const chunkPath of libraryChunks) {
2481
+ const relativePath = chunkPath.replace(/^server\//, "");
2482
+ const fullPath = join(middlewareDir, relativePath);
2483
+ if (existsSync(fullPath)) {
2484
+ let code = readFileSync(fullPath, "utf-8");
2485
+ code = transformForEdgeOneRuntime(code);
2486
+ chunksCode.push(code);
2487
+ } else {
2488
+ warnings.push(`Library chunk not found: ${fullPath}`);
2489
+ }
2490
+ }
2477
2491
  for (const chunkPath of middlewareChunks) {
2478
2492
  const relativePath = chunkPath.replace(/^server\//, "");
2479
2493
  const fullPath = join(middlewareDir, relativePath);
@@ -3650,6 +3664,22 @@ async function executeMiddleware({request}) {
3650
3664
  }
3651
3665
  } catch (e) {}
3652
3666
  }
3667
+
3668
+ // \u4ECE EdgeOne request.eo \u83B7\u53D6 geo \u548C ip \u4FE1\u606F
3669
+ const eoData = request.eo || {};
3670
+ const eoGeo = eoData.geo || {};
3671
+
3672
+ // \u5C06 EdgeOne geo \u683C\u5F0F\u8F6C\u6362\u4E3A Next.js geo \u683C\u5F0F
3673
+ // EdgeOne: { countryCodeAlpha2, regionCode, cityName, latitude, longitude, ... }
3674
+ // Next.js: { country, region, city, latitude, longitude }
3675
+ const nextGeo = {
3676
+ country: eoGeo.countryCodeAlpha2 || undefined,
3677
+ region: eoGeo.regionCode || undefined,
3678
+ city: eoGeo.cityName || undefined,
3679
+ latitude: eoGeo.latitude !== undefined ? String(eoGeo.latitude) : undefined,
3680
+ longitude: eoGeo.longitude !== undefined ? String(eoGeo.longitude) : undefined,
3681
+ };
3682
+ const clientIp = eoData.clientIp || request.headers.get('x-forwarded-for') || '';
3653
3683
 
3654
3684
  // \u6784\u9020\u8BF7\u6C42\u5BF9\u8C61
3655
3685
  let nextRequest;
@@ -3659,7 +3689,9 @@ async function executeMiddleware({request}) {
3659
3689
  // NextRequest \u6784\u9020\u51FD\u6570\u7B7E\u540D: new NextRequest(input, init?)
3660
3690
  // input \u53EF\u4EE5\u662F URL \u5B57\u7B26\u4E32\u6216 Request \u5BF9\u8C61
3661
3691
  nextRequest = new NextRequestClass(request, {
3662
- nextConfig: {}
3692
+ nextConfig: {},
3693
+ geo: nextGeo,
3694
+ ip: clientIp
3663
3695
  });
3664
3696
  } catch (e) {
3665
3697
  nextRequest = null;
@@ -3713,9 +3745,9 @@ async function executeMiddleware({request}) {
3713
3745
  delete: () => {}
3714
3746
  };
3715
3747
 
3716
- // \u6DFB\u52A0 geo \u548C ip
3717
- nextRequest.geo = {};
3718
- nextRequest.ip = request.headers.get('x-forwarded-for') || '';
3748
+ // \u6DFB\u52A0 geo \u548C ip\uFF08\u4F7F\u7528\u4ECE EdgeOne \u8F6C\u6362\u540E\u7684\u6570\u636E\uFF09
3749
+ nextRequest.geo = nextGeo;
3750
+ nextRequest.ip = clientIp;
3719
3751
  }
3720
3752
 
3721
3753
  // \u8BBE\u7F6E\u5168\u5C40 NextResponse\uFF08\u5982\u679C\u53EF\u7528\uFF09
@@ -3738,6 +3770,11 @@ async function executeMiddleware({request}) {
3738
3770
  headersObj[key] = value;
3739
3771
  });
3740
3772
 
3773
+ // \u6CE8\u5165 geo \u548C clientIp \u5230 headers \u4E2D
3774
+ // Next.js 15+ \u79FB\u9664\u4E86 request.geo \u548C request.ip\uFF0C\u7528\u6237\u9700\u8981\u4ECE headers \u4E2D\u8BFB\u53D6
3775
+ headersObj['geo'] = JSON.stringify(nextGeo);
3776
+ headersObj['clientIp'] = clientIp;
3777
+
3741
3778
  // \u521B\u5EFA\u4E00\u4E2A\u53EF\u5199\u7684 request \u5305\u88C5\u5BF9\u8C61
3742
3779
  const requestWrapper = {
3743
3780
  url: request.url,
@@ -3747,6 +3784,8 @@ async function executeMiddleware({request}) {
3747
3784
  bodyUsed: request.bodyUsed,
3748
3785
  signal: request.signal,
3749
3786
  nextConfig: {}, // NextURL \u6784\u9020\u51FD\u6570\u9700\u8981\u8FD9\u4E2A
3787
+ geo: nextGeo, // EdgeOne geo \u8F6C\u6362\u4E3A Next.js \u683C\u5F0F\uFF08\u517C\u5BB9 Next.js 14 \u53CA\u4EE5\u4E0B\uFF09
3788
+ ip: clientIp, // \u5BA2\u6237\u7AEF IP\uFF08\u517C\u5BB9 Next.js 14 \u53CA\u4EE5\u4E0B\uFF09
3750
3789
  // \u4FDD\u6301\u539F\u59CB Request \u7684\u65B9\u6CD5\u53EF\u7528
3751
3790
  clone: () => request.clone(),
3752
3791
  arrayBuffer: () => request.arrayBuffer(),
@@ -11,16 +11,20 @@ import { compile } from "./compiler.js";
11
11
  import { join } from "node:path";
12
12
  import { existsSync, writeFileSync, mkdirSync, readFileSync } from "node:fs";
13
13
  var compileMiddleware = async (ctx) => {
14
+ const nextDistDir = ctx.nextDistDir || ".next";
14
15
  const possiblePaths = [
15
- // 1. Next.js 15+: distDir/server/middleware.js (直接在 .next 目录下)
16
+ // 1. Next.js 15+: distDir/server/middleware.js (直接在 distDir 目录下)
16
17
  join(ctx.distDir, "server/middleware.js"),
17
- // 2. Next.js 15+: standaloneDir/.next/server/middleware.js
18
- join(ctx.standaloneDir, ".next/server/middleware.js"),
19
- // 3. 旧版: standaloneDir/.next/server/src/middleware.js
20
- join(ctx.standaloneDir, ".next/server/src/middleware.js"),
18
+ // 2. Next.js 15+: standaloneDir/{nextDistDir}/server/middleware.js
19
+ join(ctx.standaloneDir, nextDistDir, "server/middleware.js"),
20
+ // 3. 旧版: standaloneDir/{nextDistDir}/server/src/middleware.js
21
+ join(ctx.standaloneDir, nextDistDir, "server/src/middleware.js"),
21
22
  // 4. 旧版: distDir/server/src/middleware.js
22
23
  join(ctx.distDir, "server/src/middleware.js"),
23
- // 5. 相对于当前工作目录
24
+ // 5. 相对于当前工作目录(使用配置的 distDir)
25
+ join(process.cwd(), nextDistDir, "server/middleware.js"),
26
+ join(process.cwd(), nextDistDir, "server/src/middleware.js"),
27
+ // 6. 兼容默认 .next 目录(以防 nextDistDir 获取失败)
24
28
  join(process.cwd(), ".next/server/middleware.js"),
25
29
  join(process.cwd(), ".next/server/src/middleware.js")
26
30
  ];
@@ -41,7 +45,8 @@ var compileMiddleware = async (ctx) => {
41
45
  mkdirSync(outputDir, { recursive: true });
42
46
  const outputPath = join(outputDir, "compiled-middleware.js");
43
47
  writeFileSync(outputPath, result.code || "", "utf-8");
44
- const edgeFunctionPath = join(process.cwd(), ".edgeone/edge-functions/index.js");
48
+ const edgeoneDir = join(process.cwd(), ".edgeone");
49
+ const edgeFunctionPath = join(edgeoneDir, "edge-functions/index.js");
45
50
  if (existsSync(edgeFunctionPath)) {
46
51
  let edgeFunctionCode = readFileSync(edgeFunctionPath, "utf-8");
47
52
  if (edgeFunctionCode.includes(`'__MIDDLEWARE_BUNDLE_CODE__'`)) {
@@ -73,6 +73,22 @@ var responsePolyfill = `
73
73
  return originalRedirect.call(OriginalResponse, urlString, status);
74
74
  };
75
75
 
76
+ // Response.json \u9759\u6001\u65B9\u6CD5 polyfill
77
+ // \u67D0\u4E9B Edge \u8FD0\u884C\u65F6\u4E0D\u652F\u6301\u8FD9\u4E2A\u8F83\u65B0\u7684 Web API
78
+ const patchedJson = function(data, init) {
79
+ const body = JSON.stringify(data);
80
+ const responseInit = cleanResponseInit(init) || {};
81
+
82
+ // \u8BBE\u7F6E Content-Type header
83
+ const headers = new Headers(responseInit.headers || {});
84
+ if (!headers.has('Content-Type')) {
85
+ headers.set('Content-Type', 'application/json');
86
+ }
87
+ responseInit.headers = headers;
88
+
89
+ return new OriginalResponse(body, responseInit);
90
+ };
91
+
76
92
  // \u521B\u5EFA cookies \u5BF9\u8C61\u7684\u5DE5\u5382\u51FD\u6570
77
93
  function createResponseCookies(response) {
78
94
  const cookieStore = new Map();
@@ -137,6 +153,14 @@ var responsePolyfill = `
137
153
  if (prop === 'redirect') {
138
154
  return patchedRedirect;
139
155
  }
156
+ // \u62E6\u622A json \u9759\u6001\u65B9\u6CD5\uFF08polyfill for Edge runtime\uFF09
157
+ if (prop === 'json') {
158
+ // \u5982\u679C\u539F\u751F\u652F\u6301\u5C31\u7528\u539F\u751F\u7684\uFF0C\u5426\u5219\u7528 polyfill
159
+ if (typeof OriginalResponse.json === 'function') {
160
+ return OriginalResponse.json.bind(OriginalResponse);
161
+ }
162
+ return patchedJson;
163
+ }
140
164
  // \u5176\u4ED6\u9759\u6001\u65B9\u6CD5\u76F4\u63A5\u4ECE\u539F\u59CB Response \u83B7\u53D6
141
165
  return Reflect.get(target, prop, receiver);
142
166
  }
@@ -21,6 +21,24 @@ function getEdgeOneWrapperCode(options = {}) {
21
21
  // Middleware Runner (Raw Source Mode)
22
22
  // ============================================================
23
23
 
24
+ /**
25
+ * \u5C06 EdgeOne geo \u683C\u5F0F\u8F6C\u6362\u4E3A Next.js geo \u683C\u5F0F
26
+ * EdgeOne: { countryCodeAlpha2, regionCode, cityName, latitude, longitude, ... }
27
+ * Next.js: { country, region, city, latitude, longitude }
28
+ */
29
+ function convertEoGeoToNextGeo(eoGeo) {
30
+ if (!eoGeo || typeof eoGeo !== 'object') {
31
+ return {};
32
+ }
33
+ return {
34
+ country: eoGeo.countryCodeAlpha2 || undefined,
35
+ region: eoGeo.regionCode || undefined,
36
+ city: eoGeo.cityName || undefined,
37
+ latitude: eoGeo.latitude !== undefined ? String(eoGeo.latitude) : undefined,
38
+ longitude: eoGeo.longitude !== undefined ? String(eoGeo.longitude) : undefined,
39
+ };
40
+ }
41
+
24
42
  /**
25
43
  * \u8FD0\u884C\u4E2D\u95F4\u4EF6\u7684\u4E3B\u51FD\u6570
26
44
  * @param {Request} request - \u539F\u59CB\u8BF7\u6C42\u5BF9\u8C61
@@ -77,66 +95,80 @@ async function executeMiddleware({request}) {
77
95
  }
78
96
  }
79
97
 
98
+ // \u4ECE EdgeOne request.eo \u83B7\u53D6 geo \u548C ip \u4FE1\u606F
99
+ const eoData = request.eo || {};
100
+ const nextGeo = convertEoGeoToNextGeo(eoData.geo);
101
+ const clientIp = eoData.clientIp || request.headers.get('x-forwarded-for') || request.headers.get('x-real-ip') || '';
102
+
103
+ // \u521B\u5EFA\u65B0\u7684 Headers\uFF0C\u6CE8\u5165 geo \u548C clientIp
104
+ // Next.js 15+ \u79FB\u9664\u4E86 request.geo \u548C request.ip\uFF0C\u7528\u6237\u9700\u8981\u4ECE headers \u4E2D\u8BFB\u53D6
105
+ const newHeaders = new Headers(request.headers);
106
+ newHeaders.set('geo', JSON.stringify(nextGeo));
107
+ newHeaders.set('clientIp', clientIp);
108
+
109
+ // \u521B\u5EFA\u5E26\u6709\u65B0 headers \u7684 request
110
+ const newRequest = new Request(request.url, {
111
+ method: request.method,
112
+ headers: newHeaders,
113
+ body: request.body,
114
+ });
115
+
80
116
  // \u4E3A request \u6DFB\u52A0 nextUrl \u5C5E\u6027
81
- if (!request.nextUrl) {
82
- Object.defineProperty(request, 'nextUrl', {
83
- value: {
84
- pathname: pathname,
85
- search: url.search,
86
- searchParams: url.searchParams,
87
- hash: url.hash,
88
- host: url.host,
89
- hostname: url.hostname,
90
- port: url.port,
91
- protocol: url.protocol,
92
- href: url.href,
93
- origin: url.origin,
94
- basePath: '',
95
- locale: '',
96
- defaultLocale: '',
97
- toString: () => url.href,
98
- clone: () => new URL(url.href)
99
- },
100
- writable: true,
101
- enumerable: true
102
- });
103
- }
117
+ Object.defineProperty(newRequest, 'nextUrl', {
118
+ value: {
119
+ pathname: pathname,
120
+ search: url.search,
121
+ searchParams: url.searchParams,
122
+ hash: url.hash,
123
+ host: url.host,
124
+ hostname: url.hostname,
125
+ port: url.port,
126
+ protocol: url.protocol,
127
+ href: url.href,
128
+ origin: url.origin,
129
+ basePath: '',
130
+ locale: '',
131
+ defaultLocale: '',
132
+ toString: () => url.href,
133
+ clone: () => new URL(url.href)
134
+ },
135
+ writable: true,
136
+ enumerable: true
137
+ });
104
138
 
105
139
  // \u4E3A request \u6DFB\u52A0 cookies \u5C5E\u6027
106
- if (!request.cookies) {
107
- const cookieHeader = request.headers.get('cookie') || '';
108
- const cookieMap = new Map();
109
-
110
- if (cookieHeader) {
111
- cookieHeader.split(';').forEach(cookie => {
112
- const [name, ...valueParts] = cookie.trim().split('=');
113
- if (name) {
114
- cookieMap.set(name.trim(), {
115
- name: name.trim(),
116
- value: valueParts.join('=') || ''
117
- });
118
- }
119
- });
120
- }
121
-
122
- Object.defineProperty(request, 'cookies', {
123
- value: {
124
- get: (name) => cookieMap.get(name),
125
- has: (name) => cookieMap.has(name),
126
- getAll: () => Array.from(cookieMap.values()),
127
- set: () => {},
128
- delete: () => {},
129
- clear: () => {},
130
- [Symbol.iterator]: () => cookieMap.values(),
131
- size: cookieMap.size
132
- },
133
- writable: true,
134
- enumerable: true
140
+ const cookieHeader = newRequest.headers.get('cookie') || '';
141
+ const cookieMap = new Map();
142
+
143
+ if (cookieHeader) {
144
+ cookieHeader.split(';').forEach(cookie => {
145
+ const [name, ...valueParts] = cookie.trim().split('=');
146
+ if (name) {
147
+ cookieMap.set(name.trim(), {
148
+ name: name.trim(),
149
+ value: valueParts.join('=') || ''
150
+ });
151
+ }
135
152
  });
136
153
  }
154
+
155
+ Object.defineProperty(newRequest, 'cookies', {
156
+ value: {
157
+ get: (name) => cookieMap.get(name),
158
+ has: (name) => cookieMap.has(name),
159
+ getAll: () => Array.from(cookieMap.values()),
160
+ set: () => {},
161
+ delete: () => {},
162
+ clear: () => {},
163
+ [Symbol.iterator]: () => cookieMap.values(),
164
+ size: cookieMap.size
165
+ },
166
+ writable: true,
167
+ enumerable: true
168
+ });
137
169
 
138
170
  // \u8C03\u7528 middleware \u51FD\u6570
139
- const result = await middleware(request);
171
+ const result = await middleware(newRequest);
140
172
 
141
173
  return result;
142
174
  }
@@ -274,6 +306,24 @@ function matchesPath(pathname, matcher) {
274
306
  return false;
275
307
  }
276
308
 
309
+ /**
310
+ * \u5C06 EdgeOne geo \u683C\u5F0F\u8F6C\u6362\u4E3A Next.js geo \u683C\u5F0F
311
+ * EdgeOne: { countryCodeAlpha2, regionCode, cityName, latitude, longitude, ... }
312
+ * Next.js: { country, region, city, latitude, longitude }
313
+ */
314
+ function convertEoGeoToNextGeo(eoGeo) {
315
+ if (!eoGeo || typeof eoGeo !== 'object') {
316
+ return {};
317
+ }
318
+ return {
319
+ country: eoGeo.countryCodeAlpha2 || undefined,
320
+ region: eoGeo.regionCode || undefined,
321
+ city: eoGeo.cityName || undefined,
322
+ latitude: eoGeo.latitude !== undefined ? String(eoGeo.latitude) : undefined,
323
+ longitude: eoGeo.longitude !== undefined ? String(eoGeo.longitude) : undefined,
324
+ };
325
+ }
326
+
277
327
  /**
278
328
  * \u8FD0\u884C\u4E2D\u95F4\u4EF6\u7684\u4E3B\u51FD\u6570
279
329
  * @param {Request} request - \u539F\u59CB\u8BF7\u6C42\u5BF9\u8C61
@@ -298,6 +348,17 @@ async function executeMiddleware({request}) {
298
348
  request.headers.forEach((value, key) => {
299
349
  headersObject[key] = value;
300
350
  });
351
+
352
+ // \u4ECE EdgeOne request.eo \u83B7\u53D6 geo \u548C ip \u4FE1\u606F
353
+ const eoData = request.eo || {};
354
+ const nextGeo = convertEoGeoToNextGeo(eoData.geo);
355
+ const clientIp = eoData.clientIp || request.headers.get('x-forwarded-for') || request.headers.get('x-real-ip') || '';
356
+
357
+ // \u6CE8\u5165 geo \u548C clientIp \u5230 headers \u4E2D
358
+ // Next.js 15+ \u79FB\u9664\u4E86 request.geo \u548C request.ip\uFF0C\u7528\u6237\u9700\u8981\u4ECE headers \u4E2D\u8BFB\u53D6
359
+ // \u4F7F\u7528 'geo' (JSON \u5B57\u7B26\u4E32) \u548C 'clientIp' \u4F5C\u4E3A header \u540D\u79F0
360
+ headersObject['geo'] = JSON.stringify(nextGeo);
361
+ headersObject['clientIp'] = clientIp;
301
362
 
302
363
  // \u6784\u9020 Next.js middleware adapter \u671F\u671B\u7684\u53C2\u6570\u683C\u5F0F
303
364
  // \u53C2\u8003 Next.js \u6E90\u7801\u4E2D\u7684 adapter \u51FD\u6570
@@ -312,8 +373,8 @@ async function executeMiddleware({request}) {
312
373
  i18n: null,
313
374
  trailingSlash: false
314
375
  },
315
- geo: {},
316
- ip: request.headers.get('x-forwarded-for') || request.headers.get('x-real-ip') || '',
376
+ geo: nextGeo,
377
+ ip: clientIp,
317
378
  signal: request.signal || null
318
379
  },
319
380
  page: '/',
@@ -22,7 +22,7 @@ import { fileURLToPath } from "node:url";
22
22
  var MODULE_DIR = fileURLToPath(new URL(".", import.meta.url));
23
23
  var PLUGIN_DIR = join(MODULE_DIR, "../..");
24
24
  var DEFAULT_PUBLISH_DIR = ".next";
25
- var SERVER_HANDLER_NAME = "server-handler";
25
+ var SERVER_HANDLER_NAME = "cloud-functions/ssr-node";
26
26
  var EDGE_HANDLER_NAME = "edgeone-edge-handler";
27
27
  var PluginContext = class {
28
28
  edgeoneConfig;
@@ -40,7 +40,7 @@ var PluginContext = class {
40
40
  }
41
41
  /** Temporary directory for stashing the build output */
42
42
  get tempPublishDir() {
43
- return this.resolveFromPackagePath(".edgeone/.next");
43
+ return this.resolveFromPackagePath(join(".edgeone", this.nextDistDir));
44
44
  }
45
45
  /** Absolute path of the publish directory */
46
46
  get publishDir() {
@@ -152,13 +152,15 @@ var PluginContext = class {
152
152
  return join(this.edgeFunctionsDir, EDGE_HANDLER_NAME);
153
153
  }
154
154
  constructor(options) {
155
+ const detectedPublishDir = this.detectPublishDir(options?.constants?.PACKAGE_PATH);
155
156
  options = {
156
157
  ...options,
157
158
  functions: {
158
159
  "*": {}
159
160
  },
160
161
  constants: {
161
- PUBLISH_DIR: ".next"
162
+ ...options?.constants,
163
+ PUBLISH_DIR: detectedPublishDir
162
164
  // BUILD_VERSION: '32.1.4',
163
165
  }
164
166
  };
@@ -171,6 +173,32 @@ var PluginContext = class {
171
173
  this.serverlessWrapHandler = options.serverlessWrapHandler;
172
174
  this.getRuntimeShim = options.getRuntimeShim;
173
175
  }
176
+ /**
177
+ * 自动检测 Next.js 构建输出目录
178
+ * 搜索包含 BUILD_ID 文件的目录,支持自定义 distDir 配置
179
+ */
180
+ detectPublishDir(packagePath) {
181
+ const basePath = packagePath || process.cwd();
182
+ const possibleDirs = [
183
+ ".next",
184
+ // 默认
185
+ "build",
186
+ // 常见自定义
187
+ "dist",
188
+ // 常见自定义
189
+ "out",
190
+ // 常见自定义
191
+ ".build"
192
+ // 其他可能
193
+ ];
194
+ for (const dir of possibleDirs) {
195
+ const fullPath = resolve(basePath, dir);
196
+ if (existsSync(join(fullPath, "BUILD_ID"))) {
197
+ return dir;
198
+ }
199
+ }
200
+ return DEFAULT_PUBLISH_DIR;
201
+ }
174
202
  /** Resolves a path correctly with mono repository awareness for .edgeone directories mainly */
175
203
  resolveFromPackagePath(...args) {
176
204
  return resolve(this.constants.PACKAGE_PATH || "", ...args);
@@ -201,18 +229,21 @@ var PluginContext = class {
201
229
  /**
202
230
  * Uses various heuristics to try to find the .next dir.
203
231
  * Works by looking for BUILD_ID, so requires the site to have been built
232
+ * 支持自定义 distDir 配置(如 distDir: 'build')
204
233
  */
205
234
  findDotNext() {
206
- for (const dir of [
207
- // The publish directory
208
- this.publishDir,
209
- // In the root
210
- resolve(DEFAULT_PUBLISH_DIR),
211
- // The sibling of the publish directory
212
- resolve(this.publishDir, "..", DEFAULT_PUBLISH_DIR),
213
- // In the package dir
214
- resolve(this.constants.PACKAGE_PATH || "", DEFAULT_PUBLISH_DIR)
215
- ]) {
235
+ const possibleDirNames = [".next", "build", "dist", "out", ".build"];
236
+ const searchDirs = [
237
+ // The publish directory (已检测的目录)
238
+ this.publishDir
239
+ ];
240
+ for (const dirName of possibleDirNames) {
241
+ searchDirs.push(resolve(dirName));
242
+ searchDirs.push(resolve(this.publishDir, "..", dirName));
243
+ searchDirs.push(resolve(this.constants.PACKAGE_PATH || "", dirName));
244
+ }
245
+ const uniqueDirs = [...new Set(searchDirs)];
246
+ for (const dir of uniqueDirs) {
216
247
  if (existsSync(join(dir, "BUILD_ID"))) {
217
248
  return dir;
218
249
  }