vinext 0.1.2 → 0.1.4

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.
Files changed (243) hide show
  1. package/dist/build/client-build-config.d.ts +11 -2
  2. package/dist/build/client-build-config.js +17 -6
  3. package/dist/build/prerender.d.ts +9 -1
  4. package/dist/build/prerender.js +42 -12
  5. package/dist/build/run-prerender.d.ts +10 -2
  6. package/dist/build/run-prerender.js +15 -1
  7. package/dist/client/app-nav-failure-handler.d.ts +8 -0
  8. package/dist/client/app-nav-failure-handler.js +44 -0
  9. package/dist/client/pages-router-link-navigation.d.ts +33 -7
  10. package/dist/client/pages-router-link-navigation.js +32 -2
  11. package/dist/client/vinext-next-data.d.ts +18 -1
  12. package/dist/client/vinext-next-data.js +2 -0
  13. package/dist/client/window-next.d.ts +2 -1
  14. package/dist/client/window-next.js +12 -1
  15. package/dist/cloudflare/src/cache/cdn-adapter.runtime.js +6 -1
  16. package/dist/config/config-matchers.d.ts +11 -1
  17. package/dist/config/config-matchers.js +87 -16
  18. package/dist/config/next-config.d.ts +46 -4
  19. package/dist/config/next-config.js +147 -48
  20. package/dist/config/tsconfig-paths.js +14 -1
  21. package/dist/deploy.d.ts +30 -11
  22. package/dist/deploy.js +200 -112
  23. package/dist/entries/app-browser-entry.d.ts +9 -3
  24. package/dist/entries/app-browser-entry.js +21 -3
  25. package/dist/entries/app-rsc-entry.d.ts +2 -0
  26. package/dist/entries/app-rsc-entry.js +65 -5
  27. package/dist/entries/app-rsc-manifest.js +2 -0
  28. package/dist/entries/app-ssr-entry.js +1 -1
  29. package/dist/entries/pages-client-entry.js +66 -20
  30. package/dist/entries/pages-server-entry.js +47 -31
  31. package/dist/index.js +417 -102
  32. package/dist/plugins/dynamic-preload-metadata.js +2 -4
  33. package/dist/plugins/extensionless-dynamic-import.d.ts +6 -0
  34. package/dist/plugins/extensionless-dynamic-import.js +152 -0
  35. package/dist/plugins/fonts.js +5 -4
  36. package/dist/plugins/optimize-imports.d.ts +2 -1
  37. package/dist/plugins/optimize-imports.js +11 -9
  38. package/dist/plugins/postcss.js +7 -7
  39. package/dist/plugins/strip-server-exports.d.ts +9 -7
  40. package/dist/plugins/strip-server-exports.js +493 -46
  41. package/dist/plugins/typeof-window.d.ts +14 -0
  42. package/dist/plugins/typeof-window.js +150 -0
  43. package/dist/routing/app-route-graph.d.ts +2 -1
  44. package/dist/routing/app-route-graph.js +46 -16
  45. package/dist/routing/file-matcher.d.ts +10 -1
  46. package/dist/routing/file-matcher.js +22 -1
  47. package/dist/routing/pages-router.js +3 -3
  48. package/dist/routing/utils.d.ts +35 -6
  49. package/dist/routing/utils.js +59 -7
  50. package/dist/server/api-handler.d.ts +6 -1
  51. package/dist/server/api-handler.js +21 -15
  52. package/dist/server/app-browser-action-result.d.ts +19 -6
  53. package/dist/server/app-browser-action-result.js +20 -11
  54. package/dist/server/app-browser-entry.js +175 -91
  55. package/dist/server/app-browser-error.d.ts +10 -6
  56. package/dist/server/app-browser-error.js +43 -8
  57. package/dist/server/app-browser-hydration.d.ts +2 -0
  58. package/dist/server/app-browser-hydration.js +1 -0
  59. package/dist/server/app-browser-navigation-controller.d.ts +5 -3
  60. package/dist/server/app-browser-navigation-controller.js +23 -2
  61. package/dist/server/app-browser-server-action-navigation.d.ts +6 -0
  62. package/dist/server/app-browser-server-action-navigation.js +9 -0
  63. package/dist/server/app-browser-state.d.ts +1 -1
  64. package/dist/server/app-browser-state.js +19 -11
  65. package/dist/server/app-browser-stream.js +86 -43
  66. package/dist/server/app-browser-visible-commit.d.ts +1 -1
  67. package/dist/server/app-elements-wire.d.ts +6 -1
  68. package/dist/server/app-elements-wire.js +14 -4
  69. package/dist/server/app-elements.d.ts +2 -2
  70. package/dist/server/app-elements.js +2 -2
  71. package/dist/server/app-fallback-renderer.d.ts +1 -0
  72. package/dist/server/app-fallback-renderer.js +3 -1
  73. package/dist/server/app-optimistic-routing.js +2 -2
  74. package/dist/server/app-page-boundary-render.d.ts +1 -0
  75. package/dist/server/app-page-boundary-render.js +27 -14
  76. package/dist/server/app-page-cache-render.d.ts +53 -0
  77. package/dist/server/app-page-cache-render.js +91 -0
  78. package/dist/server/app-page-cache.d.ts +16 -2
  79. package/dist/server/app-page-cache.js +62 -1
  80. package/dist/server/app-page-dispatch.d.ts +26 -0
  81. package/dist/server/app-page-dispatch.js +149 -92
  82. package/dist/server/app-page-element-builder.d.ts +1 -0
  83. package/dist/server/app-page-element-builder.js +5 -2
  84. package/dist/server/app-page-execution.d.ts +6 -1
  85. package/dist/server/app-page-execution.js +21 -1
  86. package/dist/server/app-page-probe.d.ts +1 -0
  87. package/dist/server/app-page-probe.js +4 -0
  88. package/dist/server/app-page-render-observation.d.ts +3 -1
  89. package/dist/server/app-page-render-observation.js +17 -1
  90. package/dist/server/app-page-render.d.ts +12 -1
  91. package/dist/server/app-page-render.js +42 -4
  92. package/dist/server/app-page-request.d.ts +2 -0
  93. package/dist/server/app-page-request.js +2 -1
  94. package/dist/server/app-page-route-wiring.d.ts +3 -1
  95. package/dist/server/app-page-route-wiring.js +14 -5
  96. package/dist/server/app-page-stream.d.ts +15 -3
  97. package/dist/server/app-page-stream.js +11 -5
  98. package/dist/server/app-pages-bridge.d.ts +23 -1
  99. package/dist/server/app-pages-bridge.js +26 -17
  100. package/dist/server/app-ppr-fallback-shell-render.d.ts +17 -0
  101. package/dist/server/app-ppr-fallback-shell-render.js +26 -0
  102. package/dist/server/app-ppr-fallback-shell.d.ts +13 -1
  103. package/dist/server/app-ppr-fallback-shell.js +8 -1
  104. package/dist/server/app-route-handler-dispatch.js +9 -2
  105. package/dist/server/app-route-handler-policy.d.ts +1 -0
  106. package/dist/server/app-router-entry.js +5 -0
  107. package/dist/server/app-rsc-cache-busting.js +2 -0
  108. package/dist/server/app-rsc-handler.d.ts +28 -0
  109. package/dist/server/app-rsc-handler.js +195 -59
  110. package/dist/server/app-rsc-route-matching.d.ts +3 -0
  111. package/dist/server/app-rsc-route-matching.js +8 -2
  112. package/dist/server/app-segment-config.d.ts +9 -1
  113. package/dist/server/app-segment-config.js +12 -3
  114. package/dist/server/app-server-action-execution.d.ts +1 -0
  115. package/dist/server/app-server-action-execution.js +47 -15
  116. package/dist/server/app-ssr-entry.d.ts +2 -0
  117. package/dist/server/app-ssr-entry.js +84 -39
  118. package/dist/server/before-interactive-head.d.ts +17 -0
  119. package/dist/server/before-interactive-head.js +35 -0
  120. package/dist/server/cache-control.js +4 -0
  121. package/dist/server/csp.js +1 -4
  122. package/dist/server/dev-server.d.ts +2 -2
  123. package/dist/server/dev-server.js +321 -83
  124. package/dist/server/hybrid-route-priority.d.ts +22 -0
  125. package/dist/server/hybrid-route-priority.js +33 -0
  126. package/dist/server/image-optimization.d.ts +18 -9
  127. package/dist/server/image-optimization.js +37 -23
  128. package/dist/server/implicit-tags.d.ts +2 -1
  129. package/dist/server/implicit-tags.js +4 -1
  130. package/dist/server/middleware-matcher.js +12 -3
  131. package/dist/server/middleware-runtime.d.ts +3 -4
  132. package/dist/server/middleware-runtime.js +2 -0
  133. package/dist/server/navigation-planner.d.ts +135 -41
  134. package/dist/server/navigation-planner.js +138 -0
  135. package/dist/server/navigation-trace.d.ts +9 -1
  136. package/dist/server/navigation-trace.js +9 -1
  137. package/dist/server/operation-token.d.ts +40 -0
  138. package/dist/server/operation-token.js +85 -0
  139. package/dist/server/pages-api-route.d.ts +6 -0
  140. package/dist/server/pages-api-route.js +13 -2
  141. package/dist/server/pages-asset-tags.d.ts +2 -1
  142. package/dist/server/pages-asset-tags.js +6 -2
  143. package/dist/server/pages-data-route.d.ts +9 -2
  144. package/dist/server/pages-data-route.js +18 -6
  145. package/dist/server/pages-dev-module-url.d.ts +4 -0
  146. package/dist/server/pages-dev-module-url.js +15 -0
  147. package/dist/server/pages-document-initial-props.d.ts +4 -15
  148. package/dist/server/pages-document-initial-props.js +27 -56
  149. package/dist/server/pages-get-initial-props.d.ts +54 -4
  150. package/dist/server/pages-get-initial-props.js +43 -1
  151. package/dist/server/pages-i18n.js +2 -2
  152. package/dist/server/pages-node-compat.js +2 -2
  153. package/dist/server/pages-page-data.d.ts +11 -2
  154. package/dist/server/pages-page-data.js +207 -34
  155. package/dist/server/pages-page-handler.d.ts +4 -2
  156. package/dist/server/pages-page-handler.js +62 -23
  157. package/dist/server/pages-page-response.d.ts +4 -1
  158. package/dist/server/pages-page-response.js +11 -8
  159. package/dist/server/pages-readiness.js +1 -1
  160. package/dist/server/pages-request-pipeline.d.ts +8 -7
  161. package/dist/server/pages-request-pipeline.js +126 -47
  162. package/dist/server/pregenerated-concrete-paths.d.ts +1 -17
  163. package/dist/server/pregenerated-concrete-paths.js +2 -19
  164. package/dist/server/prerender-manifest.d.ts +33 -0
  165. package/dist/server/prerender-manifest.js +54 -0
  166. package/dist/server/prerender-route-params.d.ts +1 -2
  167. package/dist/server/prod-server.d.ts +3 -1
  168. package/dist/server/prod-server.js +50 -13
  169. package/dist/server/request-pipeline.d.ts +3 -15
  170. package/dist/server/request-pipeline.js +58 -47
  171. package/dist/server/rsc-stream-hints.d.ts +5 -1
  172. package/dist/server/rsc-stream-hints.js +6 -1
  173. package/dist/server/seed-cache.js +10 -18
  174. package/dist/server/static-file-cache.js +16 -4
  175. package/dist/shims/app-router-scroll-state.d.ts +3 -1
  176. package/dist/shims/app-router-scroll-state.js +14 -2
  177. package/dist/shims/app-router-scroll.d.ts +3 -0
  178. package/dist/shims/app-router-scroll.js +28 -18
  179. package/dist/shims/before-interactive-context.d.ts +14 -3
  180. package/dist/shims/cache-runtime.js +3 -2
  181. package/dist/shims/cache.d.ts +1 -0
  182. package/dist/shims/cache.js +1 -1
  183. package/dist/shims/cdn-cache.d.ts +5 -5
  184. package/dist/shims/document.d.ts +15 -20
  185. package/dist/shims/document.js +5 -8
  186. package/dist/shims/dynamic-preload-chunks.js +6 -4
  187. package/dist/shims/error-boundary.d.ts +2 -0
  188. package/dist/shims/error-boundary.js +7 -0
  189. package/dist/shims/error.js +3 -2
  190. package/dist/shims/error.react-server.d.ts +9 -0
  191. package/dist/shims/error.react-server.js +6 -0
  192. package/dist/shims/fetch-cache.d.ts +3 -1
  193. package/dist/shims/fetch-cache.js +45 -20
  194. package/dist/shims/hash-scroll.js +6 -1
  195. package/dist/shims/headers.js +29 -4
  196. package/dist/shims/image.js +9 -2
  197. package/dist/shims/internal/als-registry.js +28 -1
  198. package/dist/shims/internal/app-route-detection.js +8 -17
  199. package/dist/shims/internal/hybrid-client-route-owner.d.ts +31 -0
  200. package/dist/shims/internal/hybrid-client-route-owner.js +143 -0
  201. package/dist/shims/internal/navigation-untracked.d.ts +35 -0
  202. package/dist/shims/internal/navigation-untracked.js +55 -0
  203. package/dist/shims/internal/pages-data-fetch-dedup.d.ts +6 -7
  204. package/dist/shims/internal/pages-data-fetch-dedup.js +67 -14
  205. package/dist/shims/internal/pages-data-target.d.ts +7 -2
  206. package/dist/shims/internal/pages-data-target.js +17 -8
  207. package/dist/shims/internal/pages-router-accessor.d.ts +19 -0
  208. package/dist/shims/internal/pages-router-accessor.js +13 -0
  209. package/dist/shims/internal/router-context.d.ts +2 -1
  210. package/dist/shims/internal/router-context.js +3 -1
  211. package/dist/shims/link.js +47 -19
  212. package/dist/shims/metadata.js +4 -4
  213. package/dist/shims/navigation.d.ts +8 -2
  214. package/dist/shims/navigation.js +63 -31
  215. package/dist/shims/ppr-fallback-shell.d.ts +5 -1
  216. package/dist/shims/ppr-fallback-shell.js +28 -7
  217. package/dist/shims/router.d.ts +18 -3
  218. package/dist/shims/router.js +512 -142
  219. package/dist/shims/script.js +8 -4
  220. package/dist/shims/server.d.ts +16 -1
  221. package/dist/shims/server.js +44 -12
  222. package/dist/shims/unified-request-context.js +1 -0
  223. package/dist/utils/built-asset-url.d.ts +4 -0
  224. package/dist/utils/built-asset-url.js +11 -0
  225. package/dist/utils/commonjs-loader.d.ts +16 -0
  226. package/dist/utils/commonjs-loader.js +100 -0
  227. package/dist/utils/deployment-id.d.ts +8 -0
  228. package/dist/utils/deployment-id.js +22 -0
  229. package/dist/utils/has-trailing-comma.d.ts +24 -0
  230. package/dist/utils/has-trailing-comma.js +62 -0
  231. package/dist/utils/html-limited-bots.d.ts +18 -1
  232. package/dist/utils/html-limited-bots.js +23 -1
  233. package/dist/utils/parse-cookie.d.ts +13 -0
  234. package/dist/utils/parse-cookie.js +52 -0
  235. package/dist/utils/path.d.ts +7 -1
  236. package/dist/utils/path.js +9 -1
  237. package/dist/utils/text-stream.d.ts +1 -1
  238. package/dist/utils/text-stream.js +2 -2
  239. package/dist/utils/vite-version.d.ts +12 -1
  240. package/dist/utils/vite-version.js +9 -1
  241. package/package.json +2 -2
  242. package/dist/shims/internal/parse-cookie-header.d.ts +0 -14
  243. package/dist/shims/internal/parse-cookie-header.js +0 -30
@@ -1,4 +1,5 @@
1
1
  import { isUnknownRecord } from "../utils/record.js";
2
+ import { hasTrailingComma } from "../utils/has-trailing-comma.js";
2
3
  import { relativeWithinRoot, tryRealpathSync } from "../build/ssr-manifest.js";
3
4
  import path from "node:path";
4
5
  import { parseAst } from "vite";
@@ -281,15 +282,12 @@ function appendObjectProperty(output, objectNode, property) {
281
282
  output.appendLeft(propertyEnd, `, ${property}`);
282
283
  return true;
283
284
  }
284
- function stripComments(source) {
285
- return source.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/[^\n]*/g, "");
286
- }
287
285
  function insertSecondOptionsArgument(output, code, callNode, firstArg, optionsLiteral) {
288
286
  const callEnd = getNumber(callNode, "end");
289
287
  const firstArgEnd = getNumber(firstArg, "end");
290
288
  if (callEnd === null || firstArgEnd === null) return false;
291
289
  const closeParen = callEnd - 1;
292
- const separator = stripComments(code.slice(firstArgEnd, closeParen)).trimEnd().endsWith(",") ? " " : ", ";
290
+ const separator = hasTrailingComma(code.slice(firstArgEnd, closeParen)) ? " " : ", ";
293
291
  output.appendLeft(closeParen, `${separator}${optionsLiteral}`);
294
292
  return true;
295
293
  }
@@ -0,0 +1,6 @@
1
+ import { Plugin } from "vite";
2
+
3
+ //#region src/plugins/extensionless-dynamic-import.d.ts
4
+ declare function createExtensionlessDynamicImportPlugin(): Plugin;
5
+ //#endregion
6
+ export { createExtensionlessDynamicImportPlugin };
@@ -0,0 +1,152 @@
1
+ import { forEachAstChild, hasRange, isAstRecord, nodeArray } from "./ast-utils.js";
2
+ import { parseAst } from "vite";
3
+ import MagicString from "magic-string";
4
+ //#region src/plugins/extensionless-dynamic-import.ts
5
+ const MODULE_EXTENSIONS = [
6
+ ".mjs",
7
+ ".js",
8
+ ".mts",
9
+ ".ts",
10
+ ".jsx",
11
+ ".tsx",
12
+ ".json"
13
+ ];
14
+ const TRANSFORMABLE_EXTENSIONS = new Set([
15
+ ".mjs",
16
+ ".js",
17
+ ".mts",
18
+ ".ts",
19
+ ".jsx",
20
+ ".tsx",
21
+ ".cjs",
22
+ ".cts"
23
+ ]);
24
+ function createExtensionlessDynamicImportPlugin() {
25
+ let moduleExtensions = MODULE_EXTENSIONS;
26
+ return {
27
+ name: "vinext:extensionless-dynamic-import",
28
+ enforce: "pre",
29
+ configResolved(config) {
30
+ moduleExtensions = getModuleExtensions(config);
31
+ },
32
+ transform(code, id) {
33
+ if (!/\bimport\s*\(/.test(code)) return null;
34
+ if (isDependencyId(id)) return null;
35
+ const lang = langForId(id);
36
+ if (!lang) return null;
37
+ let ast;
38
+ try {
39
+ ast = parseAst(code, { lang });
40
+ } catch {
41
+ return null;
42
+ }
43
+ const imports = collectExtensionlessImports(ast, code, moduleExtensions);
44
+ if (imports.length === 0) return null;
45
+ const output = new MagicString(code);
46
+ for (const dynamicImport of imports) {
47
+ const source = code.slice(dynamicImport.sourceStart, dynamicImport.sourceEnd);
48
+ output.overwrite(dynamicImport.start, dynamicImport.end, buildReplacement(source, dynamicImport.globPattern, dynamicImport.moduleExtensions));
49
+ }
50
+ return {
51
+ code: output.toString(),
52
+ map: output.generateMap({ hires: "boundary" })
53
+ };
54
+ }
55
+ };
56
+ }
57
+ function langForId(id) {
58
+ const clean = id.split("?", 1)[0];
59
+ const dot = clean.lastIndexOf(".");
60
+ if (dot < 0) return null;
61
+ const ext = clean.slice(dot).toLowerCase();
62
+ if (!TRANSFORMABLE_EXTENSIONS.has(ext)) return null;
63
+ if (ext === ".ts" || ext === ".mts" || ext === ".cts") return "ts";
64
+ if (ext === ".tsx") return "tsx";
65
+ return "jsx";
66
+ }
67
+ function isDependencyId(id) {
68
+ return id.split("?", 1)[0].replaceAll("\\", "/").includes("/node_modules/");
69
+ }
70
+ function collectExtensionlessImports(ast, code, moduleExtensions) {
71
+ const imports = [];
72
+ function visit(value) {
73
+ if (!isAstRecord(value)) return;
74
+ const parsed = parseExtensionlessImport(value, code, moduleExtensions);
75
+ if (parsed) {
76
+ imports.push(parsed);
77
+ return;
78
+ }
79
+ forEachAstChild(value, visit);
80
+ }
81
+ visit(ast);
82
+ return imports;
83
+ }
84
+ function parseExtensionlessImport(node, code, moduleExtensions) {
85
+ if (node.type !== "ImportExpression" || !hasRange(node)) return null;
86
+ if (node.options != null) return null;
87
+ const source = node.source;
88
+ if (!isAstRecord(source) || source.type !== "TemplateLiteral" || !hasRange(source)) return null;
89
+ if (nodeArray(source.expressions).length === 0) return null;
90
+ const quasiTexts = nodeArray(source.quasis).map(templateElementText);
91
+ if (quasiTexts.some((text) => text == null)) return null;
92
+ const texts = quasiTexts;
93
+ const first = texts[0];
94
+ if (!isImportPrefix(code.slice(node.start, source.start))) return null;
95
+ if (!(first.startsWith("./") || first.startsWith("../"))) return null;
96
+ if (texts.some((text) => /[*?[\]{}()!?#]/.test(text))) return null;
97
+ if (texts.slice(1).some((text) => text.includes("."))) return null;
98
+ const directoryEnd = first.lastIndexOf("/") + 1;
99
+ const directory = first.slice(0, directoryEnd);
100
+ const filenamePrefix = first.slice(directoryEnd);
101
+ if (filenamePrefix.includes(".")) return null;
102
+ return {
103
+ start: node.start,
104
+ end: node.end,
105
+ sourceStart: source.start,
106
+ sourceEnd: source.end,
107
+ globPattern: filenamePrefix.length > 0 ? [`${first}*`, `${first}*/**/*`] : `${directory}**/*`,
108
+ moduleExtensions
109
+ };
110
+ }
111
+ function isImportPrefix(value) {
112
+ const prefix = value.match(/^import\s*\(/)?.[0];
113
+ if (!prefix) return false;
114
+ let index = prefix.length;
115
+ while (index < value.length) {
116
+ const char = value[index];
117
+ if (/\s/.test(char)) {
118
+ index += 1;
119
+ continue;
120
+ }
121
+ if (value.startsWith("/*", index)) {
122
+ const commentEnd = value.indexOf("*/", index + 2);
123
+ if (commentEnd < 0) return false;
124
+ index = commentEnd + 2;
125
+ continue;
126
+ }
127
+ if (value.startsWith("//", index)) {
128
+ const lineEnd = value.indexOf("\n", index + 2);
129
+ if (lineEnd < 0) return true;
130
+ index = lineEnd + 1;
131
+ continue;
132
+ }
133
+ return false;
134
+ }
135
+ return true;
136
+ }
137
+ function templateElementText(value) {
138
+ if (!isAstRecord(value) || value.type !== "TemplateElement") return null;
139
+ const templateValue = value.value;
140
+ if (typeof templateValue !== "object" || templateValue === null) return null;
141
+ const cooked = Reflect.get(templateValue, "cooked");
142
+ return typeof cooked === "string" ? cooked : null;
143
+ }
144
+ function getModuleExtensions(config) {
145
+ return config.resolve.extensions.filter((extension) => extension !== ".node");
146
+ }
147
+ function buildReplacement(source, globPattern, moduleExtensions) {
148
+ const extensions = JSON.stringify(moduleExtensions);
149
+ return `((__vinextPath, __vinextModules = import.meta.glob(${JSON.stringify(globPattern)}), __vinextExtensions = ${extensions}) => { const __vinextLoader = __vinextModules[__vinextPath] ?? __vinextExtensions.map((__vinextExtension) => __vinextModules[__vinextPath + __vinextExtension]).find(Boolean) ?? __vinextExtensions.map((__vinextExtension) => __vinextModules[__vinextPath + "/index" + __vinextExtension]).find(Boolean); return __vinextLoader ? __vinextLoader() : Promise.reject(new Error("Cannot find module '" + __vinextPath + "'")); })(${source})`;
150
+ }
151
+ //#endregion
152
+ export { createExtensionlessDynamicImportPlugin };
@@ -1,4 +1,5 @@
1
1
  import { escapeRegExp } from "../utils/regex.js";
2
+ import { lastSignificantChar } from "../utils/has-trailing-comma.js";
2
3
  import { buildFallbackFontFace, getFallbackFontOverrideMetrics } from "../build/google-fonts/fallback-metrics.js";
3
4
  import { validateGoogleFontOptions } from "../build/google-fonts/validate.js";
4
5
  import { getFontAxes } from "../build/google-fonts/get-axes.js";
@@ -552,8 +553,8 @@ function createGoogleFontsPlugin(fontGoogleShimPath, shimsDir) {
552
553
  if (validatedFontStyle) internalFontProperties.push(`fontStyle: ${JSON.stringify(validatedFontStyle)}`);
553
554
  const injectedProperties = [`_vinext: { font: { ${internalFontProperties.join(", ")} } }`];
554
555
  const closingBrace = optionsStr.lastIndexOf("}");
555
- const beforeBrace = optionsStr.slice(0, closingBrace).trim();
556
- const separator = beforeBrace.endsWith("{") || beforeBrace.endsWith(",") ? "" : ", ";
556
+ const lastChar = lastSignificantChar(optionsStr.slice(0, closingBrace));
557
+ const separator = lastChar === "{" || lastChar === "," ? "" : ", ";
557
558
  const replacement = `${calleeSource}(${optionsStr.slice(0, closingBrace) + separator + injectedProperties.join(", ") + optionsStr.slice(closingBrace)})`;
558
559
  s.overwrite(callStart, callEnd, replacement);
559
560
  overwrittenRanges.push([callStart, callEnd]);
@@ -688,8 +689,8 @@ function createLocalFontsPlugin(shimsDir) {
688
689
  if (familyPayloadInsertions.has(insertAt)) continue;
689
690
  const optionsStr = code.slice(objRange[0], objRange[1]);
690
691
  if (/(?:^|[,{])\s*_vinext\s*:/.test(optionsStr)) continue;
691
- const beforeClosingBrace = optionsStr.slice(0, -1).trim();
692
- const separator = beforeClosingBrace.endsWith("{") || beforeClosingBrace.endsWith(",") ? "" : ", ";
692
+ const lastChar = lastSignificantChar(optionsStr.slice(0, -1));
693
+ const separator = lastChar === "{" || lastChar === "," ? "" : ", ";
693
694
  s.appendLeft(insertAt, `${separator}_vinext: { font: { family: ${JSON.stringify(bindingName)} } }`);
694
695
  familyPayloadInsertions.add(insertAt);
695
696
  hasChanges = true;
@@ -14,6 +14,7 @@ type BarrelExportMap = Map<string, BarrelExportEntry>;
14
14
  * @see https://github.com/vercel/next.js/blob/9c31bbdaa/packages/next/src/server/config.ts#L1301
15
15
  */
16
16
  declare const DEFAULT_OPTIMIZE_PACKAGES: string[];
17
+ declare function createOptimizedImportSourceMatcher(packages: Iterable<string>): (code: string) => boolean;
17
18
  /**
18
19
  * Build a map of exported names → source sub-module for a barrel package.
19
20
  *
@@ -38,4 +39,4 @@ declare function buildBarrelExportMap(entryPath: string | null, readFile: (filep
38
39
  */
39
40
  declare function createOptimizeImportsPlugin(getNextConfig: () => ResolvedNextConfig | undefined, getRoot: () => string): Plugin;
40
41
  //#endregion
41
- export { DEFAULT_OPTIMIZE_PACKAGES, buildBarrelExportMap, createOptimizeImportsPlugin };
42
+ export { DEFAULT_OPTIMIZE_PACKAGES, buildBarrelExportMap, createOptimizeImportsPlugin, createOptimizedImportSourceMatcher };
@@ -1,4 +1,5 @@
1
1
  import { normalizePathSeparators } from "../utils/path.js";
2
+ import { escapeRegExp } from "../utils/regex.js";
2
3
  import { getAstName } from "./ast-utils.js";
3
4
  import { createRequire } from "node:module";
4
5
  import path from "node:path";
@@ -100,6 +101,12 @@ const DEFAULT_OPTIMIZE_PACKAGES = [
100
101
  "react-icons/wi",
101
102
  "radix-ui"
102
103
  ];
104
+ function createOptimizedImportSourceMatcher(packages) {
105
+ const pattern = [...packages].map(escapeRegExp).join("|");
106
+ if (!pattern) return () => false;
107
+ const importFromPattern = new RegExp(String.raw`(?:^|[;}\n\r])\s*import(?!\s*\()(?:(?!\bfrom\b)[\s\S])*?\bfrom\s*["'](?:${pattern})["']`, "m");
108
+ return (code) => code.includes("import") && code.includes("from") && importFromPattern.test(code);
109
+ }
103
110
  /**
104
111
  * Resolve a package.json exports value to a string entry path.
105
112
  * Prefers node → import → module → default conditions, recursing into nested objects.
@@ -417,14 +424,14 @@ function createOptimizeImportsPlugin(getNextConfig, getRoot) {
417
424
  };
418
425
  const entryPathCache = /* @__PURE__ */ new Map();
419
426
  let optimizedPackages = /* @__PURE__ */ new Set();
420
- let quotedPackages = [];
427
+ let hasOptimizedImportSource = () => false;
421
428
  const registeredBarrels = /* @__PURE__ */ new Set();
422
429
  return {
423
430
  name: "vinext:optimize-imports",
424
431
  buildStart() {
425
432
  const nextConfig = getNextConfig();
426
433
  optimizedPackages = new Set([...DEFAULT_OPTIMIZE_PACKAGES, ...nextConfig?.optimizePackageImports ?? []]);
427
- quotedPackages = [...optimizedPackages].flatMap((pkg) => [`"${pkg}"`, `'${pkg}'`]);
434
+ hasOptimizedImportSource = createOptimizedImportSourceMatcher(optimizedPackages);
428
435
  entryPathCache.clear();
429
436
  barrelCaches.exportMapCache.clear();
430
437
  barrelCaches.subpkgOrigin.clear();
@@ -445,12 +452,7 @@ function createOptimizeImportsPlugin(getNextConfig, getRoot) {
445
452
  const preferReactServer = env?.name === "rsc";
446
453
  if (id.startsWith("\0")) return null;
447
454
  const packages = optimizedPackages;
448
- let hasBarrelImport = false;
449
- for (const quoted of quotedPackages) if (code.includes(quoted)) {
450
- hasBarrelImport = true;
451
- break;
452
- }
453
- if (!hasBarrelImport) return null;
455
+ if (!hasOptimizedImportSource(code)) return null;
454
456
  let ast;
455
457
  try {
456
458
  ast = parseAst(code);
@@ -576,4 +578,4 @@ function createOptimizeImportsPlugin(getNextConfig, getRoot) {
576
578
  };
577
579
  }
578
580
  //#endregion
579
- export { DEFAULT_OPTIMIZE_PACKAGES, buildBarrelExportMap, createOptimizeImportsPlugin };
581
+ export { DEFAULT_OPTIMIZE_PACKAGES, buildBarrelExportMap, createOptimizeImportsPlugin, createOptimizedImportSourceMatcher };
@@ -1,8 +1,11 @@
1
+ import { importExportWithCommonJsFallback } from "../utils/commonjs-loader.js";
1
2
  import { createRequire } from "node:module";
2
3
  import fs from "node:fs";
3
4
  import path from "node:path";
4
- import { pathToFileURL } from "node:url";
5
5
  //#region src/plugins/postcss.ts
6
+ async function loadPluginExport(resolvedPath) {
7
+ return importExportWithCommonJsFallback(resolvedPath);
8
+ }
6
9
  /**
7
10
  * PostCSS config file names to search for, in priority order.
8
11
  * Matches the same search order as postcss-load-config / lilconfig.
@@ -65,8 +68,7 @@ async function resolvePostcssStringPluginsUncached(projectRoot) {
65
68
  if (configPath.endsWith(".postcssrc")) {
66
69
  if (fs.readFileSync(configPath, "utf-8").trim().startsWith("{")) return;
67
70
  }
68
- const mod = await import(pathToFileURL(configPath).href);
69
- config = mod.default ?? mod;
71
+ config = await importExportWithCommonJsFallback(configPath);
70
72
  } catch {
71
73
  return;
72
74
  }
@@ -76,14 +78,12 @@ async function resolvePostcssStringPluginsUncached(projectRoot) {
76
78
  try {
77
79
  return { plugins: await Promise.all(config.plugins.filter(Boolean).map(async (plugin) => {
78
80
  if (typeof plugin === "string") {
79
- const mod = await import(pathToFileURL(req.resolve(plugin)).href);
80
- const fn = mod.default ?? mod;
81
+ const fn = await loadPluginExport(req.resolve(plugin));
81
82
  return typeof fn === "function" ? fn() : fn;
82
83
  }
83
84
  if (Array.isArray(plugin) && typeof plugin[0] === "string") {
84
85
  const [name, options] = plugin;
85
- const mod = await import(pathToFileURL(req.resolve(name)).href);
86
- const fn = mod.default ?? mod;
86
+ const fn = await loadPluginExport(req.resolve(name));
87
87
  return typeof fn === "function" ? fn(options) : fn;
88
88
  }
89
89
  return plugin;
@@ -1,13 +1,15 @@
1
1
  //#region src/plugins/strip-server-exports.d.ts
2
+ declare function hasServerExportCandidate(code: string): boolean;
3
+ declare function hasExportAllCandidate(code: string): boolean;
4
+ declare function validatePageExports(code: string): void;
2
5
  /**
3
- * Strip server-only data-fetching exports (getServerSideProps,
4
- * getStaticProps, getStaticPaths) from page modules for the client
5
- * bundle. Uses Vite's parseAst (Rollup/acorn) for correct handling
6
- * of all export patterns including function expressions, arrow
7
- * functions with TS return types, and re-exports.
6
+ * Strip server-only Pages Router data-fetching exports and their unique
7
+ * dependency graph from browser bundles.
8
8
  *
9
- * Modeled after Next.js's SWC `next-ssg-transform`.
9
+ * Ported from Next.js:
10
+ * - test/unit/babel-plugin-next-ssg-transform.test.ts
11
+ * - crates/next-custom-transforms/src/transforms/strip_page_exports.rs
10
12
  */
11
13
  declare function stripServerExports(code: string): string | null;
12
14
  //#endregion
13
- export { stripServerExports };
15
+ export { hasExportAllCandidate, hasServerExportCandidate, stripServerExports, validatePageExports };