vinext 0.1.1 → 0.1.3
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.
- package/README.md +2 -5
- package/dist/build/client-build-config.d.ts +7 -1
- package/dist/build/client-build-config.js +9 -1
- package/dist/build/prerender.d.ts +9 -1
- package/dist/build/prerender.js +41 -12
- package/dist/build/run-prerender.d.ts +10 -2
- package/dist/build/run-prerender.js +15 -1
- package/dist/check.js +4 -3
- package/dist/client/app-nav-failure-handler.d.ts +8 -0
- package/dist/client/app-nav-failure-handler.js +44 -0
- package/dist/client/navigation-runtime.d.ts +3 -2
- package/dist/client/vinext-next-data.d.ts +18 -1
- package/dist/client/window-next.d.ts +8 -5
- package/dist/client/window-next.js +12 -1
- package/dist/cloudflare/src/cache/cdn-adapter.runtime.js +6 -1
- package/dist/config/config-matchers.d.ts +11 -4
- package/dist/config/config-matchers.js +88 -16
- package/dist/config/next-config.d.ts +59 -4
- package/dist/config/next-config.js +149 -48
- package/dist/deploy.d.ts +30 -11
- package/dist/deploy.js +189 -101
- package/dist/entries/app-browser-entry.d.ts +9 -3
- package/dist/entries/app-browser-entry.js +21 -3
- package/dist/entries/app-rsc-entry.d.ts +2 -0
- package/dist/entries/app-rsc-entry.js +71 -6
- package/dist/entries/app-rsc-manifest.js +2 -0
- package/dist/entries/app-ssr-entry.js +1 -1
- package/dist/entries/pages-client-entry.js +54 -9
- package/dist/entries/pages-server-entry.js +48 -11
- package/dist/index.d.ts +0 -2
- package/dist/index.js +285 -139
- package/dist/plugins/dynamic-preload-metadata.d.ts +13 -0
- package/dist/plugins/dynamic-preload-metadata.js +415 -0
- package/dist/plugins/extensionless-dynamic-import.d.ts +6 -0
- package/dist/plugins/extensionless-dynamic-import.js +152 -0
- package/dist/plugins/og-assets.js +2 -2
- package/dist/plugins/optimize-imports.d.ts +10 -5
- package/dist/plugins/optimize-imports.js +27 -21
- package/dist/plugins/postcss.js +7 -7
- package/dist/plugins/sass.d.ts +53 -24
- package/dist/plugins/sass.js +249 -1
- package/dist/plugins/typeof-window.d.ts +14 -0
- package/dist/plugins/typeof-window.js +150 -0
- package/dist/plugins/wasm-module-import.d.ts +15 -0
- package/dist/plugins/wasm-module-import.js +50 -0
- package/dist/routing/app-route-graph.d.ts +25 -2
- package/dist/routing/app-route-graph.js +91 -22
- package/dist/routing/file-matcher.d.ts +10 -1
- package/dist/routing/file-matcher.js +23 -2
- package/dist/routing/pages-router.js +3 -3
- package/dist/routing/utils.d.ts +35 -6
- package/dist/routing/utils.js +59 -7
- package/dist/server/api-handler.d.ts +6 -1
- package/dist/server/api-handler.js +21 -15
- package/dist/server/app-browser-action-result.d.ts +19 -6
- package/dist/server/app-browser-action-result.js +19 -10
- package/dist/server/app-browser-entry.js +269 -297
- package/dist/server/app-browser-error.d.ts +10 -3
- package/dist/server/app-browser-error.js +47 -6
- package/dist/server/app-browser-history-controller.d.ts +104 -0
- package/dist/server/app-browser-history-controller.js +210 -0
- package/dist/server/app-browser-hydration.d.ts +2 -0
- package/dist/server/app-browser-hydration.js +1 -0
- package/dist/server/app-browser-navigation-controller.d.ts +7 -4
- package/dist/server/app-browser-navigation-controller.js +33 -9
- package/dist/server/app-browser-rsc-redirect.d.ts +11 -2
- package/dist/server/app-browser-rsc-redirect.js +30 -8
- package/dist/server/app-browser-server-action-navigation.d.ts +6 -0
- package/dist/server/app-browser-server-action-navigation.js +9 -0
- package/dist/server/app-browser-state.js +4 -7
- package/dist/server/app-browser-stream.js +86 -43
- package/dist/server/app-browser-visible-commit.js +1 -1
- package/dist/server/app-elements-wire.d.ts +6 -1
- package/dist/server/app-elements-wire.js +14 -4
- package/dist/server/app-elements.d.ts +2 -2
- package/dist/server/app-elements.js +2 -2
- package/dist/server/app-fallback-renderer.d.ts +3 -1
- package/dist/server/app-fallback-renderer.js +6 -2
- package/dist/server/app-middleware.js +1 -0
- package/dist/server/app-optimistic-routing.js +24 -3
- package/dist/server/app-page-boundary-render.d.ts +3 -1
- package/dist/server/app-page-boundary-render.js +31 -16
- package/dist/server/app-page-cache-render.d.ts +53 -0
- package/dist/server/app-page-cache-render.js +91 -0
- package/dist/server/app-page-cache.d.ts +16 -2
- package/dist/server/app-page-cache.js +71 -8
- package/dist/server/app-page-dispatch.d.ts +34 -0
- package/dist/server/app-page-dispatch.js +167 -97
- package/dist/server/app-page-element-builder.d.ts +23 -2
- package/dist/server/app-page-element-builder.js +42 -10
- package/dist/server/app-page-execution.d.ts +7 -2
- package/dist/server/app-page-execution.js +53 -18
- package/dist/server/app-page-probe.d.ts +1 -0
- package/dist/server/app-page-probe.js +4 -0
- package/dist/server/app-page-render-observation.d.ts +3 -1
- package/dist/server/app-page-render-observation.js +17 -1
- package/dist/server/app-page-render.d.ts +13 -2
- package/dist/server/app-page-render.js +48 -17
- package/dist/server/app-page-request.d.ts +3 -0
- package/dist/server/app-page-request.js +5 -3
- package/dist/server/app-page-response.js +1 -1
- package/dist/server/app-page-route-wiring.d.ts +5 -1
- package/dist/server/app-page-route-wiring.js +21 -11
- package/dist/server/app-page-stream.d.ts +16 -9
- package/dist/server/app-page-stream.js +12 -9
- package/dist/server/app-pages-bridge.d.ts +18 -0
- package/dist/server/app-pages-bridge.js +22 -5
- package/dist/server/app-ppr-fallback-shell-render.d.ts +17 -0
- package/dist/server/app-ppr-fallback-shell-render.js +26 -0
- package/dist/server/app-ppr-fallback-shell.d.ts +13 -1
- package/dist/server/app-ppr-fallback-shell.js +8 -1
- package/dist/server/app-route-handler-dispatch.js +9 -2
- package/dist/server/app-route-handler-policy.d.ts +1 -0
- package/dist/server/app-route-handler-response.js +11 -10
- package/dist/server/app-route-handler-runtime.js +12 -1
- package/dist/server/app-router-entry.js +5 -0
- package/dist/server/app-rsc-cache-busting.js +2 -0
- package/dist/server/app-rsc-handler.d.ts +25 -0
- package/dist/server/app-rsc-handler.js +153 -53
- package/dist/server/app-rsc-response-finalizer.js +1 -1
- package/dist/server/app-rsc-route-matching.d.ts +3 -0
- package/dist/server/app-rsc-route-matching.js +2 -0
- package/dist/server/app-segment-config.d.ts +9 -1
- package/dist/server/app-segment-config.js +12 -3
- package/dist/server/app-server-action-execution.d.ts +12 -0
- package/dist/server/app-server-action-execution.js +47 -15
- package/dist/server/app-ssr-entry.d.ts +2 -0
- package/dist/server/app-ssr-entry.js +81 -8
- package/dist/server/app-ssr-stream.js +9 -1
- package/dist/server/cache-control.js +4 -0
- package/dist/server/dev-lockfile.js +2 -1
- package/dist/server/dev-server.d.ts +2 -2
- package/dist/server/dev-server.js +287 -63
- package/dist/server/headers.d.ts +8 -1
- package/dist/server/headers.js +8 -1
- package/dist/server/hybrid-route-priority.d.ts +22 -0
- package/dist/server/hybrid-route-priority.js +33 -0
- package/dist/server/image-optimization.d.ts +18 -9
- package/dist/server/image-optimization.js +37 -23
- package/dist/server/implicit-tags.d.ts +2 -1
- package/dist/server/implicit-tags.js +4 -1
- package/dist/server/instrumentation-runtime.d.ts +6 -0
- package/dist/server/instrumentation-runtime.js +8 -0
- package/dist/server/isr-decision.d.ts +79 -0
- package/dist/server/isr-decision.js +70 -0
- package/dist/server/metadata-route-response.js +5 -3
- package/dist/server/middleware-runtime.d.ts +13 -0
- package/dist/server/middleware-runtime.js +11 -7
- package/dist/server/middleware.js +1 -0
- package/dist/server/navigation-planner.d.ts +186 -22
- package/dist/server/navigation-planner.js +302 -0
- package/dist/server/navigation-trace.d.ts +18 -1
- package/dist/server/navigation-trace.js +18 -1
- package/dist/server/normalize-path.d.ts +0 -8
- package/dist/server/normalize-path.js +3 -1
- package/dist/server/otel-tracer-extension.d.ts +45 -0
- package/dist/server/otel-tracer-extension.js +89 -0
- package/dist/server/pages-api-route.d.ts +20 -3
- package/dist/server/pages-api-route.js +19 -3
- package/dist/server/pages-asset-tags.d.ts +16 -4
- package/dist/server/pages-asset-tags.js +22 -12
- package/dist/server/pages-data-route.d.ts +8 -1
- package/dist/server/pages-data-route.js +16 -3
- package/dist/server/pages-get-initial-props.d.ts +54 -4
- package/dist/server/pages-get-initial-props.js +43 -1
- package/dist/server/pages-node-compat.d.ts +3 -11
- package/dist/server/pages-node-compat.js +175 -122
- package/dist/server/pages-page-data.d.ts +39 -2
- package/dist/server/pages-page-data.js +261 -46
- package/dist/server/pages-page-handler.d.ts +5 -2
- package/dist/server/pages-page-handler.js +78 -25
- package/dist/server/pages-page-response.d.ts +47 -2
- package/dist/server/pages-page-response.js +73 -9
- package/dist/server/pages-readiness.d.ts +1 -1
- package/dist/server/pages-request-pipeline.d.ts +16 -1
- package/dist/server/pages-request-pipeline.js +96 -38
- package/dist/server/pregenerated-concrete-paths.d.ts +1 -17
- package/dist/server/pregenerated-concrete-paths.js +2 -19
- package/dist/server/prerender-manifest.d.ts +33 -0
- package/dist/server/prerender-manifest.js +54 -0
- package/dist/server/prerender-route-params.d.ts +1 -2
- package/dist/server/prod-server.d.ts +39 -1
- package/dist/server/prod-server.js +107 -37
- package/dist/server/request-pipeline.d.ts +3 -15
- package/dist/server/request-pipeline.js +58 -47
- package/dist/server/rsc-stream-hints.d.ts +5 -1
- package/dist/server/rsc-stream-hints.js +6 -1
- package/dist/server/seed-cache.js +10 -18
- package/dist/shims/app-router-scroll-state.d.ts +3 -1
- package/dist/shims/app-router-scroll-state.js +14 -2
- package/dist/shims/app-router-scroll.d.ts +3 -0
- package/dist/shims/app-router-scroll.js +28 -18
- package/dist/shims/cache-runtime.js +12 -4
- package/dist/shims/cache.d.ts +1 -0
- package/dist/shims/cache.js +1 -1
- package/dist/shims/cdn-cache.d.ts +5 -5
- package/dist/shims/dynamic-preload-chunks.d.ts +8 -0
- package/dist/shims/dynamic-preload-chunks.js +79 -0
- package/dist/shims/dynamic.d.ts +4 -0
- package/dist/shims/dynamic.js +4 -2
- package/dist/shims/error-boundary.d.ts +6 -4
- package/dist/shims/error-boundary.js +7 -0
- package/dist/shims/error.js +38 -11
- package/dist/shims/error.react-server.d.ts +9 -0
- package/dist/shims/error.react-server.js +6 -0
- package/dist/shims/fetch-cache.d.ts +11 -1
- package/dist/shims/fetch-cache.js +55 -20
- package/dist/shims/hash-scroll.js +6 -1
- package/dist/shims/head.js +6 -1
- package/dist/shims/headers.d.ts +16 -2
- package/dist/shims/headers.js +66 -5
- package/dist/shims/image-config.js +7 -1
- package/dist/shims/internal/als-registry.js +28 -1
- package/dist/shims/internal/app-route-detection.d.ts +6 -3
- package/dist/shims/internal/app-route-detection.js +18 -23
- package/dist/shims/internal/app-router-context.d.ts +5 -0
- package/dist/shims/internal/hybrid-client-route-owner.d.ts +31 -0
- package/dist/shims/internal/hybrid-client-route-owner.js +143 -0
- package/dist/shims/internal/navigation-untracked.d.ts +35 -0
- package/dist/shims/internal/navigation-untracked.js +55 -0
- package/dist/shims/internal/pages-data-target.d.ts +7 -2
- package/dist/shims/internal/pages-data-target.js +17 -8
- package/dist/shims/internal/pages-router-accessor.d.ts +19 -0
- package/dist/shims/internal/pages-router-accessor.js +13 -0
- package/dist/shims/internal/router-context.d.ts +2 -1
- package/dist/shims/internal/router-context.js +3 -1
- package/dist/shims/link.js +12 -5
- package/dist/shims/metadata.d.ts +6 -2
- package/dist/shims/metadata.js +32 -14
- package/dist/shims/navigation.d.ts +14 -17
- package/dist/shims/navigation.js +93 -46
- package/dist/shims/ppr-fallback-shell.d.ts +5 -1
- package/dist/shims/ppr-fallback-shell.js +28 -7
- package/dist/shims/router.d.ts +13 -2
- package/dist/shims/router.js +434 -116
- package/dist/shims/script-nonce-context.d.ts +1 -1
- package/dist/shims/script-nonce-context.js +11 -3
- package/dist/shims/server.d.ts +33 -2
- package/dist/shims/server.js +75 -18
- package/dist/shims/slot.js +1 -1
- package/dist/shims/unified-request-context.js +2 -0
- package/dist/typegen.js +1 -0
- package/dist/utils/built-asset-url.d.ts +4 -0
- package/dist/utils/built-asset-url.js +11 -0
- package/dist/utils/client-build-manifest.js +15 -5
- package/dist/utils/client-runtime-metadata.d.ts +45 -0
- package/dist/utils/client-runtime-metadata.js +63 -0
- package/dist/utils/commonjs-loader.d.ts +16 -0
- package/dist/utils/commonjs-loader.js +100 -0
- package/dist/utils/deployment-id.d.ts +8 -0
- package/dist/utils/deployment-id.js +22 -0
- package/dist/utils/hash.d.ts +17 -1
- package/dist/utils/hash.js +36 -1
- package/dist/utils/html-limited-bots.d.ts +18 -1
- package/dist/utils/html-limited-bots.js +23 -1
- package/dist/utils/lazy-chunks.d.ts +27 -1
- package/dist/utils/lazy-chunks.js +65 -1
- package/dist/utils/manifest-paths.d.ts +20 -2
- package/dist/utils/manifest-paths.js +38 -3
- package/dist/utils/parse-cookie.d.ts +13 -0
- package/dist/utils/parse-cookie.js +52 -0
- package/dist/utils/path.d.ts +8 -1
- package/dist/utils/path.js +13 -1
- package/package.json +2 -2
- package/dist/shims/internal/parse-cookie-header.d.ts +0 -14
- package/dist/shims/internal/parse-cookie-header.js +0 -30
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { normalizePathSeparators } from "../utils/path.js";
|
|
2
|
+
import { escapeRegExp } from "../utils/regex.js";
|
|
1
3
|
import { getAstName } from "./ast-utils.js";
|
|
2
4
|
import { createRequire } from "node:module";
|
|
3
5
|
import path from "node:path";
|
|
@@ -99,6 +101,12 @@ const DEFAULT_OPTIMIZE_PACKAGES = [
|
|
|
99
101
|
"react-icons/wi",
|
|
100
102
|
"radix-ui"
|
|
101
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
|
+
}
|
|
102
110
|
/**
|
|
103
111
|
* Resolve a package.json exports value to a string entry path.
|
|
104
112
|
* Prefers node → import → module → default conditions, recursing into nested objects.
|
|
@@ -185,12 +193,12 @@ async function resolvePackageEntry(packageName, projectRoot, preferReactServer)
|
|
|
185
193
|
const dotExport = pkgJson.exports["."];
|
|
186
194
|
if (dotExport) {
|
|
187
195
|
const entryPath = resolveExportsValue(dotExport, preferReactServer);
|
|
188
|
-
if (entryPath) return path.resolve(pkgDir, entryPath)
|
|
196
|
+
if (entryPath) return normalizePathSeparators(path.resolve(pkgDir, entryPath));
|
|
189
197
|
}
|
|
190
198
|
}
|
|
191
199
|
const entryField = pkgJson.module ?? pkgJson.main;
|
|
192
|
-
if (typeof entryField === "string") return path.resolve(pkgDir, entryField)
|
|
193
|
-
return createRequire(path.join(projectRoot, "package.json")).resolve(packageName)
|
|
200
|
+
if (typeof entryField === "string") return normalizePathSeparators(path.resolve(pkgDir, entryField));
|
|
201
|
+
return normalizePathSeparators(createRequire(path.join(projectRoot, "package.json")).resolve(packageName));
|
|
194
202
|
} catch {
|
|
195
203
|
return null;
|
|
196
204
|
}
|
|
@@ -228,14 +236,14 @@ async function buildExportMapFromFile(filePath, readFile, cache, visited, initia
|
|
|
228
236
|
const exportMap = /* @__PURE__ */ new Map();
|
|
229
237
|
const importBindings = /* @__PURE__ */ new Map();
|
|
230
238
|
const localDeclarations = /* @__PURE__ */ new Set();
|
|
231
|
-
const fileDir = path.dirname(filePath);
|
|
239
|
+
const fileDir = path.posix.dirname(filePath);
|
|
232
240
|
/**
|
|
233
241
|
* Normalize a source specifier: resolve relative paths to absolute so that
|
|
234
242
|
* entries in the export map always store absolute paths for file references.
|
|
235
243
|
* Bare package specifiers (e.g. "@radix-ui/react-slot") are returned unchanged.
|
|
236
244
|
*/
|
|
237
245
|
function normalizeSource(source) {
|
|
238
|
-
return source.startsWith(".") ? path.
|
|
246
|
+
return source.startsWith(".") ? path.posix.join(fileDir, source) : source;
|
|
239
247
|
}
|
|
240
248
|
function recordLocalDeclaration(node) {
|
|
241
249
|
if (!node) return;
|
|
@@ -297,7 +305,7 @@ async function buildExportMapFromFile(filePath, readFile, cache, visited, initia
|
|
|
297
305
|
isNamespace: true
|
|
298
306
|
});
|
|
299
307
|
} else if (rawSource.startsWith(".")) {
|
|
300
|
-
const subPath = path.
|
|
308
|
+
const subPath = path.posix.join(fileDir, rawSource);
|
|
301
309
|
const candidates = [
|
|
302
310
|
subPath,
|
|
303
311
|
`${subPath}.js`,
|
|
@@ -386,12 +394,15 @@ async function buildExportMapFromFile(filePath, readFile, cache, visited, initia
|
|
|
386
394
|
* Handles: `export * as X from`, `export { A } from`, `import * as X; export { X }`,
|
|
387
395
|
* and `export * from "./sub"` (recursively resolves wildcard re-exports).
|
|
388
396
|
*
|
|
389
|
-
* Returns null if
|
|
390
|
-
*
|
|
391
|
-
*
|
|
397
|
+
* Returns null if `entryPath` is empty, the file cannot be read, or the file
|
|
398
|
+
* has a parse error. Returns an empty map if the file is valid but exports
|
|
399
|
+
* nothing.
|
|
400
|
+
*
|
|
401
|
+
* @param entryPath - Pre-resolved absolute path to the barrel entry file (the
|
|
402
|
+
* caller owns entry resolution + its caching), or null when it could not be
|
|
403
|
+
* resolved.
|
|
392
404
|
*/
|
|
393
|
-
async function buildBarrelExportMap(
|
|
394
|
-
const entryPath = resolveEntry(packageName);
|
|
405
|
+
async function buildBarrelExportMap(entryPath, readFile, cache) {
|
|
395
406
|
if (!entryPath) return null;
|
|
396
407
|
const exportMapCache = cache ?? /* @__PURE__ */ new Map();
|
|
397
408
|
const cached = exportMapCache.get(entryPath);
|
|
@@ -413,14 +424,14 @@ function createOptimizeImportsPlugin(getNextConfig, getRoot) {
|
|
|
413
424
|
};
|
|
414
425
|
const entryPathCache = /* @__PURE__ */ new Map();
|
|
415
426
|
let optimizedPackages = /* @__PURE__ */ new Set();
|
|
416
|
-
let
|
|
427
|
+
let hasOptimizedImportSource = () => false;
|
|
417
428
|
const registeredBarrels = /* @__PURE__ */ new Set();
|
|
418
429
|
return {
|
|
419
430
|
name: "vinext:optimize-imports",
|
|
420
431
|
buildStart() {
|
|
421
432
|
const nextConfig = getNextConfig();
|
|
422
433
|
optimizedPackages = new Set([...DEFAULT_OPTIMIZE_PACKAGES, ...nextConfig?.optimizePackageImports ?? []]);
|
|
423
|
-
|
|
434
|
+
hasOptimizedImportSource = createOptimizedImportSourceMatcher(optimizedPackages);
|
|
424
435
|
entryPathCache.clear();
|
|
425
436
|
barrelCaches.exportMapCache.clear();
|
|
426
437
|
barrelCaches.subpkgOrigin.clear();
|
|
@@ -441,12 +452,7 @@ function createOptimizeImportsPlugin(getNextConfig, getRoot) {
|
|
|
441
452
|
const preferReactServer = env?.name === "rsc";
|
|
442
453
|
if (id.startsWith("\0")) return null;
|
|
443
454
|
const packages = optimizedPackages;
|
|
444
|
-
|
|
445
|
-
for (const quoted of quotedPackages) if (code.includes(quoted)) {
|
|
446
|
-
hasBarrelImport = true;
|
|
447
|
-
break;
|
|
448
|
-
}
|
|
449
|
-
if (!hasBarrelImport) return null;
|
|
455
|
+
if (!hasOptimizedImportSource(code)) return null;
|
|
450
456
|
let ast;
|
|
451
457
|
try {
|
|
452
458
|
ast = parseAst(code);
|
|
@@ -466,7 +472,7 @@ function createOptimizeImportsPlugin(getNextConfig, getRoot) {
|
|
|
466
472
|
barrelEntry = await resolvePackageEntry(importSource, root, preferReactServer);
|
|
467
473
|
entryPathCache.set(cacheKey, barrelEntry ?? null);
|
|
468
474
|
}
|
|
469
|
-
const exportMap = await buildBarrelExportMap(
|
|
475
|
+
const exportMap = await buildBarrelExportMap(barrelEntry, readFileSafe, barrelCaches.exportMapCache);
|
|
470
476
|
if (!exportMap || !barrelEntry) continue;
|
|
471
477
|
const envKey = preferReactServer ? "rsc" : "ssr";
|
|
472
478
|
const registeredKey = `${envKey}:${barrelEntry}`;
|
|
@@ -572,4 +578,4 @@ function createOptimizeImportsPlugin(getNextConfig, getRoot) {
|
|
|
572
578
|
};
|
|
573
579
|
}
|
|
574
580
|
//#endregion
|
|
575
|
-
export { DEFAULT_OPTIMIZE_PACKAGES, buildBarrelExportMap, createOptimizeImportsPlugin };
|
|
581
|
+
export { DEFAULT_OPTIMIZE_PACKAGES, buildBarrelExportMap, createOptimizeImportsPlugin, createOptimizedImportSourceMatcher };
|
package/dist/plugins/postcss.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
|
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;
|
package/dist/plugins/sass.d.ts
CHANGED
|
@@ -1,33 +1,62 @@
|
|
|
1
|
+
import { ResolvedConfig } from "vite";
|
|
2
|
+
|
|
1
3
|
//#region src/plugins/sass.d.ts
|
|
2
|
-
/**
|
|
3
|
-
* Map a Next.js `sassOptions` object onto Vite's
|
|
4
|
-
* `css.preprocessorOptions.scss` / `.sass` shape.
|
|
5
|
-
*
|
|
6
|
-
* Next.js (webpack + sass-loader) accepts:
|
|
7
|
-
* - `additionalData` (or legacy `prependData`) — prepended to every source
|
|
8
|
-
* - `includePaths` — directories searched by `@import`
|
|
9
|
-
* - `loadPaths` — modern Sass equivalent of `includePaths`
|
|
10
|
-
* - `implementation` — Sass implementation package name (e.g. `sass-embedded`)
|
|
11
|
-
* - other Sass options that get forwarded as-is
|
|
12
|
-
*
|
|
13
|
-
* Reference (Next.js source — destructures the same keys before forwarding
|
|
14
|
-
* the rest to sass-loader):
|
|
15
|
-
* .nextjs-ref/packages/next/src/build/webpack/config/blocks/css/index.ts#L150-L180
|
|
16
|
-
* https://github.com/vercel/next.js/blob/canary/packages/next/src/build/webpack/config/blocks/css/index.ts
|
|
17
|
-
*
|
|
18
|
-
* Vite expects:
|
|
19
|
-
* - `additionalData` (string or function) on the preprocessor options
|
|
20
|
-
* - modern Sass options (`loadPaths`, `importers`, `implementation`, …)
|
|
21
|
-
* flattened next to `additionalData`
|
|
22
|
-
*
|
|
23
|
-
* @see https://vite.dev/config/shared-options.html#css-preprocessoroptions
|
|
24
|
-
*/
|
|
25
4
|
type AdditionalData = string | ((source: string, filename: string) => string | Promise<string>);
|
|
26
5
|
type VitePreprocessorOptions = {
|
|
27
6
|
additionalData?: AdditionalData;
|
|
28
7
|
loadPaths?: string[];
|
|
29
8
|
[key: string]: any;
|
|
30
9
|
};
|
|
10
|
+
/**
|
|
11
|
+
* Create a Sass `FileImporter` that resolves webpack-style tilde (`~`) imports.
|
|
12
|
+
*
|
|
13
|
+
* Next.js (via sass-loader's `webpackImporter`) supports two tilde forms:
|
|
14
|
+
*
|
|
15
|
+
* 1. `~pkg/path` — resolves `pkg/path` from `node_modules`. Used for
|
|
16
|
+
* third-party SCSS/CSS, e.g. `@import '~nprogress/nprogress.css'`.
|
|
17
|
+
*
|
|
18
|
+
* 2. `~/path` — resolves relative to the **project root** (the `~` acts as
|
|
19
|
+
* an alias for the root). Used with Turbopack's `resolveAlias: { '~*': '*' }`
|
|
20
|
+
* convention, e.g. `@use '~/styles/variables' as *`.
|
|
21
|
+
*
|
|
22
|
+
* Vite's built-in Sass resolver does not strip the `~` prefix, so any SCSS
|
|
23
|
+
* that uses tilde imports fails with "Can't find stylesheet to import" errors.
|
|
24
|
+
* This `FileImporter` runs before Vite's internal importer (added at the end
|
|
25
|
+
* of `importers[]` in the vite:css plugin) and canonicalises tilde URLs so
|
|
26
|
+
* Sass can load them from the filesystem.
|
|
27
|
+
*
|
|
28
|
+
* The returned object implements the modern Sass `FileImporter` interface:
|
|
29
|
+
* `findFileUrl` returns a `file://` URL and Sass automatically handles partial
|
|
30
|
+
* resolution (`_variables.scss` for `variables`), index files, and extensions.
|
|
31
|
+
*
|
|
32
|
+
* @param root - Absolute path to the Vite project root (used as the base for
|
|
33
|
+
* `~/path` resolution and for locating `node_modules`).
|
|
34
|
+
*/
|
|
35
|
+
declare function createSassTildeImporter(root: string): {
|
|
36
|
+
findFileUrl(url: string): URL | null;
|
|
37
|
+
};
|
|
31
38
|
declare function buildSassPreprocessorOptions(sassOptions: Record<string, unknown> | null | undefined): VitePreprocessorOptions | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* Create a per-build binding of {@link SassAwareFileSystemLoader}.
|
|
41
|
+
*
|
|
42
|
+
* Returns:
|
|
43
|
+
* - `Loader` — a class to inject as postcss-modules' `css.modules.Loader`
|
|
44
|
+
* option. postcss-modules instantiates it with the fixed
|
|
45
|
+
* `(root, plugins, fileResolve)` signature, so the resolved Vite config is
|
|
46
|
+
* captured in this factory's closure rather than passed to the constructor.
|
|
47
|
+
* - `setResolvedConfig` — called from vinext's `configResolved` hook to bind
|
|
48
|
+
* that build's resolved config.
|
|
49
|
+
*
|
|
50
|
+
* One binding is created per vinext plugin instance, so concurrent or
|
|
51
|
+
* back-to-back builds in a single process never observe another build's
|
|
52
|
+
* config (root, sass options, `generateScopedName`, logger, …).
|
|
53
|
+
*/
|
|
54
|
+
declare function createSassAwareFileSystemLoader(): {
|
|
55
|
+
Loader: new (root: string, plugins: unknown[], fileResolve?: (newPath: string, relativeTo: string) => Promise<string>) => {
|
|
56
|
+
fetch(newPath: string, relativeTo: string, trace?: string): Promise<Record<string, string>>;
|
|
57
|
+
readonly finalSource: string;
|
|
58
|
+
};
|
|
59
|
+
setResolvedConfig: (config: ResolvedConfig) => void;
|
|
60
|
+
};
|
|
32
61
|
//#endregion
|
|
33
|
-
export { buildSassPreprocessorOptions };
|
|
62
|
+
export { buildSassPreprocessorOptions, createSassAwareFileSystemLoader, createSassTildeImporter };
|
package/dist/plugins/sass.js
CHANGED
|
@@ -1,4 +1,80 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { preprocessCSS } from "vite";
|
|
5
|
+
import { pathToFileURL } from "node:url";
|
|
1
6
|
//#region src/plugins/sass.ts
|
|
7
|
+
/**
|
|
8
|
+
* Map a Next.js `sassOptions` object onto Vite's
|
|
9
|
+
* `css.preprocessorOptions.scss` / `.sass` shape.
|
|
10
|
+
*
|
|
11
|
+
* Next.js (webpack + sass-loader) accepts:
|
|
12
|
+
* - `additionalData` (or legacy `prependData`) — prepended to every source
|
|
13
|
+
* - `includePaths` — directories searched by `@import`
|
|
14
|
+
* - `loadPaths` — modern Sass equivalent of `includePaths`
|
|
15
|
+
* - `implementation` — Sass implementation package name (e.g. `sass-embedded`)
|
|
16
|
+
* - other Sass options that get forwarded as-is
|
|
17
|
+
*
|
|
18
|
+
* Reference (Next.js source — destructures the same keys before forwarding
|
|
19
|
+
* the rest to sass-loader):
|
|
20
|
+
* .nextjs-ref/packages/next/src/build/webpack/config/blocks/css/index.ts#L150-L180
|
|
21
|
+
* https://github.com/vercel/next.js/blob/canary/packages/next/src/build/webpack/config/blocks/css/index.ts
|
|
22
|
+
*
|
|
23
|
+
* Vite expects:
|
|
24
|
+
* - `additionalData` (string or function) on the preprocessor options
|
|
25
|
+
* - modern Sass options (`loadPaths`, `importers`, `implementation`, …)
|
|
26
|
+
* flattened next to `additionalData`
|
|
27
|
+
*
|
|
28
|
+
* @see https://vite.dev/config/shared-options.html#css-preprocessoroptions
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* Create a Sass `FileImporter` that resolves webpack-style tilde (`~`) imports.
|
|
32
|
+
*
|
|
33
|
+
* Next.js (via sass-loader's `webpackImporter`) supports two tilde forms:
|
|
34
|
+
*
|
|
35
|
+
* 1. `~pkg/path` — resolves `pkg/path` from `node_modules`. Used for
|
|
36
|
+
* third-party SCSS/CSS, e.g. `@import '~nprogress/nprogress.css'`.
|
|
37
|
+
*
|
|
38
|
+
* 2. `~/path` — resolves relative to the **project root** (the `~` acts as
|
|
39
|
+
* an alias for the root). Used with Turbopack's `resolveAlias: { '~*': '*' }`
|
|
40
|
+
* convention, e.g. `@use '~/styles/variables' as *`.
|
|
41
|
+
*
|
|
42
|
+
* Vite's built-in Sass resolver does not strip the `~` prefix, so any SCSS
|
|
43
|
+
* that uses tilde imports fails with "Can't find stylesheet to import" errors.
|
|
44
|
+
* This `FileImporter` runs before Vite's internal importer (added at the end
|
|
45
|
+
* of `importers[]` in the vite:css plugin) and canonicalises tilde URLs so
|
|
46
|
+
* Sass can load them from the filesystem.
|
|
47
|
+
*
|
|
48
|
+
* The returned object implements the modern Sass `FileImporter` interface:
|
|
49
|
+
* `findFileUrl` returns a `file://` URL and Sass automatically handles partial
|
|
50
|
+
* resolution (`_variables.scss` for `variables`), index files, and extensions.
|
|
51
|
+
*
|
|
52
|
+
* @param root - Absolute path to the Vite project root (used as the base for
|
|
53
|
+
* `~/path` resolution and for locating `node_modules`).
|
|
54
|
+
*/
|
|
55
|
+
function createSassTildeImporter(root) {
|
|
56
|
+
const rootBaseUrl = pathToFileURL(root.endsWith("/") ? root : root + "/");
|
|
57
|
+
const nodeModulesBaseUrl = pathToFileURL(path.join(root, "node_modules") + "/");
|
|
58
|
+
return { findFileUrl(url) {
|
|
59
|
+
if (!url.startsWith("~")) return null;
|
|
60
|
+
const stripped = url.slice(1);
|
|
61
|
+
if (stripped.startsWith("/")) return new URL(stripped.slice(1), rootBaseUrl);
|
|
62
|
+
if (!stripped) return null;
|
|
63
|
+
const simpleResolved = new URL(stripped, nodeModulesBaseUrl);
|
|
64
|
+
const pkgName = stripped.startsWith("@") ? stripped.split("/").slice(0, 2).join("/") : stripped.split("/")[0] ?? "";
|
|
65
|
+
const directPkgDir = path.join(root, "node_modules", pkgName);
|
|
66
|
+
if (pkgName && fs.existsSync(directPkgDir)) return simpleResolved;
|
|
67
|
+
const req = createRequire(path.join(root, "package.json"));
|
|
68
|
+
try {
|
|
69
|
+
const pkgJsonPath = req.resolve(`${pkgName}/package.json`);
|
|
70
|
+
const pkgDir = path.dirname(pkgJsonPath);
|
|
71
|
+
const afterPkg = stripped.startsWith("@") ? stripped.split("/").slice(2).join("/") : stripped.split("/").slice(1).join("/");
|
|
72
|
+
return pathToFileURL(afterPkg ? path.join(pkgDir, afterPkg) : pkgDir);
|
|
73
|
+
} catch {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
} };
|
|
77
|
+
}
|
|
2
78
|
function buildSassPreprocessorOptions(sassOptions) {
|
|
3
79
|
if (!sassOptions || typeof sassOptions !== "object") return void 0;
|
|
4
80
|
const { prependData, additionalData, includePaths, loadPaths, ...rest } = sassOptions;
|
|
@@ -16,5 +92,177 @@ function buildSassPreprocessorOptions(sassOptions) {
|
|
|
16
92
|
if (Object.keys(out).length === 0) return void 0;
|
|
17
93
|
return out;
|
|
18
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* Sort key comparator used by postcss-modules' FileSystemLoader to determine
|
|
97
|
+
* the order in which dependency CSS is prepended to the output.
|
|
98
|
+
* Mirrors the original `traceKeySorter` from postcss-modules source.
|
|
99
|
+
*/
|
|
100
|
+
function traceKeySorter(a, b) {
|
|
101
|
+
if (a.length < b.length) return a < b.substring(0, a.length) ? -1 : 1;
|
|
102
|
+
if (a.length > b.length) return a.substring(0, b.length) <= b ? -1 : 1;
|
|
103
|
+
return a < b ? -1 : 1;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Mirrors Vite's internal `cssModuleRE` (`/\.module\.(css|less|sass|scss|…)/`).
|
|
107
|
+
*
|
|
108
|
+
* postcss-modules treats *every* `composes: x from './file'` dependency as a
|
|
109
|
+
* CSS module regardless of its filename, but Vite's pipeline only applies
|
|
110
|
+
* CSS-module scoping to `*.module.*` files. When a dependency is not named
|
|
111
|
+
* `*.module.*` (e.g. `composes: x from './plain.css'`), we hand
|
|
112
|
+
* `preprocessCSS` a virtual `*.module.*` filename (same directory, so Sass
|
|
113
|
+
* imports and relative resolution are unaffected) so the dependency's classes
|
|
114
|
+
* are scoped and its export tokens extracted — matching what postcss-modules'
|
|
115
|
+
* built-in `FileSystemLoader` did.
|
|
116
|
+
*/
|
|
117
|
+
const CSS_MODULE_RE = /\.module\.\w+$/;
|
|
118
|
+
/**
|
|
119
|
+
* Sass-aware replacement for postcss-modules' `FileSystemLoader`.
|
|
120
|
+
*
|
|
121
|
+
* Implements the same constructor + `fetch` + `finalSource` interface that
|
|
122
|
+
* postcss-modules calls when resolving `composes: className from 'file'`
|
|
123
|
+
* dependencies.
|
|
124
|
+
*
|
|
125
|
+
* For every dependency file, Vite's `preprocessCSS` is used so that:
|
|
126
|
+
* - `.scss`/`.sass` files are compiled through Sass *before* CSS-module
|
|
127
|
+
* scoping runs (fixing the "Invalid empty selector" LightningCSS crash).
|
|
128
|
+
* - `.module.css` and `.module.scss` files have their class names scoped and
|
|
129
|
+
* export tokens extracted in exactly the same way as the top-level file.
|
|
130
|
+
*
|
|
131
|
+
* Failure handling: a missing Sass implementation is downgraded to a logged
|
|
132
|
+
* warning and an empty token map so the build continues (class composition
|
|
133
|
+
* will be incomplete); any other preprocessing error (e.g. a syntax error in
|
|
134
|
+
* the composed dependency) propagates and fails the build, matching the
|
|
135
|
+
* built-in `FileSystemLoader`. When no resolved config has been bound —
|
|
136
|
+
* only reachable if the Loader is used outside vinext's `configResolved`
|
|
137
|
+
* wiring — the Loader silently returns an empty token map.
|
|
138
|
+
*
|
|
139
|
+
* Recursion boundary: nested `composes` chains are handled by delegating to
|
|
140
|
+
* `preprocessCSS`, which re-applies postcss-modules (and therefore this
|
|
141
|
+
* Loader) for each dependency — every composed subtree gets its own inner
|
|
142
|
+
* Loader instance rather than sharing this instance's `tokensByFile`/
|
|
143
|
+
* `sources` state. Two intentional consequences, versus the built-in
|
|
144
|
+
* single-loader recursion:
|
|
145
|
+
* - A dependency reached from two sibling `composes` branches is inlined
|
|
146
|
+
* once per subtree; the duplicate identical rules are collapsed by
|
|
147
|
+
* LightningCSS during minification (bloat-free in practice, but the
|
|
148
|
+
* pre-minification CSS differs from the built-in loader's single pass).
|
|
149
|
+
* - Circular `composes` chains are not short-circuited across the
|
|
150
|
+
* `preprocessCSS` boundary (the built-in loader's shared cache caught
|
|
151
|
+
* them). Cycles are invalid CSS-module inputs — webpack/Next.js errors on
|
|
152
|
+
* them too — so no cycle bookkeeping is layered on here.
|
|
153
|
+
*
|
|
154
|
+
* Not exported directly: postcss-modules constructs the Loader itself with a
|
|
155
|
+
* fixed `(root, plugins, fileResolve)` signature, so the resolved Vite config
|
|
156
|
+
* cannot be a constructor argument. `createSassAwareFileSystemLoader` returns
|
|
157
|
+
* a subclass with the config bound per factory call (i.e. per vinext plugin
|
|
158
|
+
* instance) instead of a module-level singleton, so multiple builds in one
|
|
159
|
+
* process (monorepos, programmatic multi-build runners) each preprocess
|
|
160
|
+
* `composes` dependencies with their own root/sass options/scoped-name
|
|
161
|
+
* generator.
|
|
162
|
+
*/
|
|
163
|
+
var SassAwareFileSystemLoader = class {
|
|
164
|
+
root;
|
|
165
|
+
fileResolve;
|
|
166
|
+
sources;
|
|
167
|
+
traces;
|
|
168
|
+
importNr;
|
|
169
|
+
tokensByFile;
|
|
170
|
+
constructor(root, _plugins, fileResolve) {
|
|
171
|
+
if (root === "/" && process.platform === "win32") {
|
|
172
|
+
const cwdDrive = process.cwd().slice(0, 3);
|
|
173
|
+
if (!/^[A-Za-z]:\\$/.test(cwdDrive)) throw new Error(`Failed to obtain root from "${process.cwd()}".`);
|
|
174
|
+
root = cwdDrive;
|
|
175
|
+
}
|
|
176
|
+
this.root = root;
|
|
177
|
+
this.fileResolve = fileResolve;
|
|
178
|
+
this.sources = {};
|
|
179
|
+
this.traces = {};
|
|
180
|
+
this.importNr = 0;
|
|
181
|
+
this.tokensByFile = {};
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* The resolved Vite config used to preprocess `composes` dependencies.
|
|
185
|
+
* The base implementation has no config (`fetch` silently returns empty
|
|
186
|
+
* tokens); `createSassAwareFileSystemLoader` overrides this with the
|
|
187
|
+
* config bound to that factory call.
|
|
188
|
+
*/
|
|
189
|
+
getResolvedConfig() {
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
async fetch(_newPath, relativeTo, _trace) {
|
|
193
|
+
const newPath = _newPath.replace(/^["']|["']$/g, "");
|
|
194
|
+
const trace = _trace ?? String.fromCharCode(this.importNr++);
|
|
195
|
+
const useFileResolve = typeof this.fileResolve === "function";
|
|
196
|
+
const fileResolvedPath = useFileResolve ? await this.fileResolve(newPath, relativeTo) : void 0;
|
|
197
|
+
if (fileResolvedPath !== void 0 && !path.isAbsolute(fileResolvedPath)) throw new Error("The returned path from the \"fileResolve\" option must be absolute.");
|
|
198
|
+
const relativeDir = path.dirname(relativeTo);
|
|
199
|
+
const fileRelativePath = fileResolvedPath ?? (() => {
|
|
200
|
+
let resolved = path.resolve(path.resolve(this.root, relativeDir), newPath);
|
|
201
|
+
if (!useFileResolve && newPath[0] !== "." && !path.isAbsolute(newPath)) try {
|
|
202
|
+
resolved = createRequire(import.meta.url).resolve(newPath);
|
|
203
|
+
} catch {}
|
|
204
|
+
return resolved;
|
|
205
|
+
})();
|
|
206
|
+
const cached = this.tokensByFile[fileRelativePath];
|
|
207
|
+
if (cached) return cached;
|
|
208
|
+
const config = this.getResolvedConfig();
|
|
209
|
+
const rawSource = await fs.promises.readFile(fileRelativePath, "utf-8");
|
|
210
|
+
if (config) try {
|
|
211
|
+
const ext = path.extname(fileRelativePath);
|
|
212
|
+
const result = await preprocessCSS(rawSource, CSS_MODULE_RE.test(fileRelativePath) ? fileRelativePath : ext === "" ? `${fileRelativePath}.module.css` : `${fileRelativePath.slice(0, -ext.length)}.module${ext}`, config);
|
|
213
|
+
const exportTokens = result.modules ?? {};
|
|
214
|
+
this.sources[fileRelativePath] = result.code;
|
|
215
|
+
this.traces[trace] = fileRelativePath;
|
|
216
|
+
this.tokensByFile[fileRelativePath] = exportTokens;
|
|
217
|
+
return exportTokens;
|
|
218
|
+
} catch (error) {
|
|
219
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
220
|
+
if (!message.includes("Preprocessor dependency")) throw error;
|
|
221
|
+
config.logger.warn(`[vinext] Failed to preprocess \`composes\` dependency ${fileRelativePath}: ${message}. Classes composed from this file will be missing from the build output.`);
|
|
222
|
+
}
|
|
223
|
+
this.sources[fileRelativePath] = "";
|
|
224
|
+
this.traces[trace] = fileRelativePath;
|
|
225
|
+
this.tokensByFile[fileRelativePath] = {};
|
|
226
|
+
return {};
|
|
227
|
+
}
|
|
228
|
+
get finalSource() {
|
|
229
|
+
const { traces, sources } = this;
|
|
230
|
+
const written = /* @__PURE__ */ new Set();
|
|
231
|
+
return Object.keys(traces).sort(traceKeySorter).map((key) => {
|
|
232
|
+
const filename = traces[key];
|
|
233
|
+
if (!filename || written.has(filename)) return null;
|
|
234
|
+
written.add(filename);
|
|
235
|
+
return sources[filename];
|
|
236
|
+
}).join("");
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
/**
|
|
240
|
+
* Create a per-build binding of {@link SassAwareFileSystemLoader}.
|
|
241
|
+
*
|
|
242
|
+
* Returns:
|
|
243
|
+
* - `Loader` — a class to inject as postcss-modules' `css.modules.Loader`
|
|
244
|
+
* option. postcss-modules instantiates it with the fixed
|
|
245
|
+
* `(root, plugins, fileResolve)` signature, so the resolved Vite config is
|
|
246
|
+
* captured in this factory's closure rather than passed to the constructor.
|
|
247
|
+
* - `setResolvedConfig` — called from vinext's `configResolved` hook to bind
|
|
248
|
+
* that build's resolved config.
|
|
249
|
+
*
|
|
250
|
+
* One binding is created per vinext plugin instance, so concurrent or
|
|
251
|
+
* back-to-back builds in a single process never observe another build's
|
|
252
|
+
* config (root, sass options, `generateScopedName`, logger, …).
|
|
253
|
+
*/
|
|
254
|
+
function createSassAwareFileSystemLoader() {
|
|
255
|
+
let resolvedConfig = null;
|
|
256
|
+
return {
|
|
257
|
+
Loader: class extends SassAwareFileSystemLoader {
|
|
258
|
+
getResolvedConfig() {
|
|
259
|
+
return resolvedConfig;
|
|
260
|
+
}
|
|
261
|
+
},
|
|
262
|
+
setResolvedConfig(config) {
|
|
263
|
+
resolvedConfig = config;
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
}
|
|
19
267
|
//#endregion
|
|
20
|
-
export { buildSassPreprocessorOptions };
|
|
268
|
+
export { buildSassPreprocessorOptions, createSassAwareFileSystemLoader, createSassTildeImporter };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/plugins/typeof-window.d.ts
|
|
2
|
+
type WindowType = "object" | "undefined";
|
|
3
|
+
type EnvironmentLike = {
|
|
4
|
+
config: {
|
|
5
|
+
consumer: "client" | "server";
|
|
6
|
+
};
|
|
7
|
+
};
|
|
8
|
+
declare function getTypeofWindowReplacement(environment: EnvironmentLike): WindowType;
|
|
9
|
+
declare function replaceTypeofWindow(code: string, replacement: WindowType): {
|
|
10
|
+
code: string;
|
|
11
|
+
map: import("magic-string").SourceMap;
|
|
12
|
+
} | null;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { getTypeofWindowReplacement, replaceTypeofWindow };
|