vinext 1.0.0 → 1.0.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.
- package/THIRD_PARTY_LICENSES.md +26 -0
- package/dist/build/lifecycle.js +10 -10
- package/dist/build/pages-client-assets-module.js +6 -1
- package/dist/build/precompress.js +1 -1
- package/dist/build/prerender-paths.js +3 -7
- package/dist/build/prerender.d.ts +8 -1
- package/dist/build/prerender.js +134 -38
- package/dist/build/run-prerender.js +4 -3
- package/dist/build/server-entry.d.ts +2 -0
- package/dist/build/server-entry.js +7 -1
- package/dist/client/browser-globals.d.ts +4 -0
- package/dist/client/browser-globals.js +5 -0
- package/dist/client/navigation-runtime.d.ts +0 -1
- package/dist/client/navigation-runtime.js +2 -2
- package/dist/config/dotenv.js +14 -3
- package/dist/entries/app-rsc-entry.js +3 -2
- package/dist/index.js +142 -71
- package/dist/init-cloudflare.d.ts +1 -1
- package/dist/init-cloudflare.js +6 -6
- package/dist/init-platform.js +1 -1
- package/dist/init.js +4 -2
- package/dist/plugins/commonjs-syntax.d.ts +16 -0
- package/dist/plugins/commonjs-syntax.js +22 -0
- package/dist/plugins/ignore-dynamic-requests.d.ts +11 -0
- package/dist/plugins/ignore-dynamic-requests.js +54 -3
- package/dist/plugins/import-meta-url.js +6 -6
- package/dist/plugins/og-asset-ownership.d.ts +2 -0
- package/dist/plugins/og-asset-ownership.js +24 -13
- package/dist/plugins/og-assets.d.ts +18 -0
- package/dist/plugins/og-assets.js +50 -8
- package/dist/plugins/og-harfbuzz.js +38 -27
- package/dist/plugins/optimize-imports.js +2 -1
- package/dist/plugins/require-context.d.ts +1 -0
- package/dist/plugins/require-context.js +28 -1
- package/dist/plugins/scan-build-css.d.ts +12 -0
- package/dist/plugins/scan-build-css.js +39 -0
- package/dist/plugins/strip-server-exports.d.ts +2 -0
- package/dist/plugins/strip-server-exports.js +3 -1
- package/dist/plugins/transform-result.d.ts +18 -0
- package/dist/plugins/transform-result.js +23 -2
- package/dist/plugins/typeof-window.d.ts +10 -0
- package/dist/plugins/typeof-window.js +33 -9
- package/dist/routing/app-route-graph.d.ts +0 -1
- package/dist/routing/app-route-graph.js +2 -4
- package/dist/routing/app-route-ids.d.ts +3 -0
- package/dist/routing/app-route-ids.js +6 -0
- package/dist/server/app-bfcache-id.d.ts +1 -0
- package/dist/server/app-bfcache-id.js +7 -1
- package/dist/server/app-bfcache-identity.js +1 -2
- package/dist/server/app-browser-entry.js +4 -2
- package/dist/server/app-browser-hydration.d.ts +1 -1
- package/dist/server/app-browser-hydration.js +2 -2
- package/dist/server/app-browser-navigation-controller.js +1 -1
- package/dist/server/app-browser-state.js +1 -1
- package/dist/server/app-browser-stream.d.ts +1 -1
- package/dist/server/app-history-state.d.ts +0 -1
- package/dist/server/app-history-state.js +2 -5
- package/dist/server/app-page-cache-render.js +2 -1
- package/dist/server/app-page-render.js +2 -1
- package/dist/server/app-page-search-params-observation.js +1 -1
- package/dist/server/app-page-stream.js +1 -1
- package/dist/server/app-page-tracing.js +2 -1
- package/dist/server/app-pages-bridge.js +3 -2
- package/dist/server/app-render-abort-error.d.ts +3 -0
- package/dist/server/app-render-abort-error.js +8 -0
- package/dist/server/app-request-stage-independent-entry.js +4 -7
- package/dist/server/app-route-handler-cache.d.ts +2 -1
- package/dist/server/app-route-handler-cache.js +11 -7
- package/dist/server/app-route-handler-dispatch.js +10 -3
- package/dist/server/app-route-handler-execution.d.ts +9 -1
- package/dist/server/app-route-handler-execution.js +28 -13
- package/dist/server/app-route-handler-policy.js +2 -2
- package/dist/server/app-route-handler-response.d.ts +1 -1
- package/dist/server/app-route-handler-response.js +14 -5
- package/dist/server/app-router-entry.d.ts +2 -1
- package/dist/server/app-router-entry.js +5 -9
- package/dist/server/app-rsc-errors.d.ts +0 -1
- package/dist/server/app-rsc-errors.js +2 -6
- package/dist/server/app-rsc-handler.d.ts +1 -0
- package/dist/server/app-rsc-handler.js +18 -7
- package/dist/server/app-rsc-request-normalization.d.ts +1 -1
- package/dist/server/app-rsc-request-normalization.js +3 -2
- package/dist/server/app-rsc-response-finalizer.js +4 -1
- package/dist/server/app-rsc-route-matching.js +1 -1
- package/dist/server/app-server-action-execution.d.ts +2 -1
- package/dist/server/app-ssr-entry.js +3 -3
- package/dist/server/app-ssr-search-params-gate.js +1 -1
- package/dist/server/app-ssr-stream.js +1 -1
- package/dist/server/cache-control.js +3 -11
- package/dist/server/cacheability-request.js +49 -49
- package/dist/server/config-headers.js +1 -1
- package/dist/server/dev-server.js +11 -3
- package/dist/server/headers.d.ts +2 -0
- package/dist/server/headers.js +5 -1
- package/dist/server/http-error-responses.js +1 -0
- package/dist/server/isr-cache.d.ts +2 -0
- package/dist/server/isr-cache.js +6 -1
- package/dist/server/metadata-route-response.js +94 -37
- package/dist/server/pages-api-route.js +8 -2
- package/dist/server/pages-asset-tags.d.ts +1 -0
- package/dist/server/pages-asset-tags.js +73 -22
- package/dist/server/pages-client-assets.d.ts +2 -0
- package/dist/server/pages-page-data.d.ts +6 -1
- package/dist/server/pages-page-data.js +71 -65
- package/dist/server/pages-page-handler.js +29 -11
- package/dist/server/pages-page-response.js +3 -1
- package/dist/server/pages-request-pipeline.d.ts +2 -1
- package/dist/server/pages-request-pipeline.js +20 -5
- package/dist/server/pages-request-stage-entry.js +6 -4
- package/dist/server/prerender-manifest.d.ts +6 -0
- package/dist/server/prerender-manifest.js +1 -1
- package/dist/server/prod-server.js +3 -13
- package/dist/server/response-stage-cacheability.js +1 -1
- package/dist/server/worker-revalidation-context.d.ts +2 -1
- package/dist/server/worker-revalidation-context.js +1 -0
- package/dist/server/workers-tracing.d.ts +17 -0
- package/dist/server/workers-tracing.js +48 -8
- package/dist/shims/cache-request-state.d.ts +3 -14
- package/dist/shims/cache-request-state.js +2 -13
- package/dist/shims/cache-runtime.js +4 -2
- package/dist/shims/cache.d.ts +2 -1
- package/dist/shims/cache.js +4 -2
- package/dist/shims/cacheability-classification.d.ts +1 -1
- package/dist/shims/cacheability-classification.js +2 -2
- package/dist/shims/cdn-cache.d.ts +10 -1
- package/dist/shims/cdn-cache.js +16 -9
- package/dist/shims/error.d.ts +4 -18
- package/dist/shims/error.js +17 -10
- package/dist/shims/error.react-server.d.ts +4 -6
- package/dist/shims/error.react-server.js +4 -1
- package/dist/shims/fetch-cache.js +4 -3
- package/dist/shims/headers.d.ts +6 -69
- package/dist/shims/headers.js +37 -181
- package/dist/shims/internal/cache-context-accessor.d.ts +16 -0
- package/dist/shims/internal/cache-context-accessor.js +15 -0
- package/dist/shims/internal/headers-state.d.ts +74 -0
- package/dist/shims/internal/headers-state.js +157 -0
- package/dist/shims/navigation.js +2 -2
- package/dist/shims/request-state-types.d.ts +2 -1
- package/dist/shims/root-params.js +1 -1
- package/dist/shims/server.js +52 -2
- package/dist/shims/unified-request-context.d.ts +1 -1
- package/dist/utils/encode-cache-tag.d.ts +1 -0
- package/dist/utils/encode-cache-tag.js +11 -1
- package/dist/utils/vite-cli-invocation.js +8 -1
- package/package.json +6 -2
- package/dist/server/metadata-route-cache-policy.d.ts +0 -5
- package/dist/server/metadata-route-cache-policy.js +0 -6
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path, { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
2
|
import { DYNAMIC_IMPORT_PRESCAN, SCRIPT_MODULE_ID_RE, collectBindingNames, forEachAstChild, isIdentifierNamed, mayContainDynamicImport, scriptParserLanguage, stringLiteralValue, unwrapExpression } from "./ast-utils.js";
|
|
3
|
-
import { magicStringTransformResult } from "./transform-result.js";
|
|
3
|
+
import { magicStringTransformResult, omitUnusedBuildSourcemap } from "./transform-result.js";
|
|
4
4
|
import { stripViteModuleQuery } from "../utils/path.js";
|
|
5
5
|
import { collectDirectScopeBindings, collectLoopScopeBindings, collectSwitchScopeBindings, collectVarScopeBindings, hasAstBinding, isFunctionNode } from "./ast-scope.js";
|
|
6
6
|
import { createTransformCache } from "./transform-cache.js";
|
|
@@ -12,6 +12,16 @@ const DYNAMIC_REQUEST_ERROR = "Cannot find module as expression is too dynamic";
|
|
|
12
12
|
const REQUIRE_PRESCAN = /(?:\brequire\b|(?:r|\\u(?:0072|\{0*72\}))(?:e|\\u(?:0065|\{0*65\}))(?:q|\\u(?:0071|\{0*71\}))(?:u|\\u(?:0075|\{0*75\}))(?:i|\\u(?:0069|\{0*69\}))(?:r|\\u(?:0072|\{0*72\}))(?:e|\\u(?:0065|\{0*65\})))/i;
|
|
13
13
|
const DYNAMIC_REQUEST_PRESCAN = new RegExp(String.raw`(?:${REQUIRE_PRESCAN.source}|${DYNAMIC_IMPORT_PRESCAN.source})`, "i");
|
|
14
14
|
const MAX_CONSTANT_BINDING_DEPTH = 1500;
|
|
15
|
+
const REQUIRE_OR_IMPORT_OCCURRENCE = new RegExp(String.raw`${REQUIRE_PRESCAN.source}|\bimport\b`, "gi");
|
|
16
|
+
const IDENTIFIER_CHAR = /[\w$]/;
|
|
17
|
+
const LINE_TERMINATOR = /[\n\r\u2028\u2029]/;
|
|
18
|
+
const WHITESPACE_CHAR = /\s/;
|
|
19
|
+
const UNCHANGED_STRING_ARGUMENT = String.raw`\s*\(\s*(?:"(?!\/")[^"\\\r\n]*"|'(?!\/')[^'\\\r\n]*')\s*`;
|
|
20
|
+
const UNCHANGED_REQUIRE_CALL = new RegExp(String.raw`${UNCHANGED_STRING_ARGUMENT}\)`, "y");
|
|
21
|
+
const UNCHANGED_IMPORT_CALL = new RegExp(String.raw`${UNCHANGED_STRING_ARGUMENT}[,)]`, "y");
|
|
22
|
+
const POSSIBLE_REQUIRE_CALLEE_FOLLOWER = /\s*(?:[(/<]|--!?>|\?\.|!(?!=)|as\b|satisfies\b)/y;
|
|
23
|
+
const CLOSING_PAREN_FOLLOWER = /\s*\)/y;
|
|
24
|
+
const POSSIBLE_IMPORT_EXPRESSION_FOLLOWER = /\s*(?:[(/<]|--!?>|\.(?!\s*meta\b))/y;
|
|
15
25
|
const VINEXT_SOURCE_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
16
26
|
const PLUGIN_RSC_PATH = /[\\/]node_modules[\\/](?:\.pnpm[\\/][^/\\]+[\\/]node_modules[\\/])?@vitejs[\\/]plugin-rsc[\\/]/;
|
|
17
27
|
function stringFromCharCodeValue(value, scope) {
|
|
@@ -355,8 +365,48 @@ function dynamicRequireReplacement() {
|
|
|
355
365
|
function dynamicImportReplacement() {
|
|
356
366
|
return `Promise.resolve().then(() => { const error = new Error(${JSON.stringify(DYNAMIC_REQUEST_ERROR)}); error.code = "MODULE_NOT_FOUND"; throw error; })`;
|
|
357
367
|
}
|
|
368
|
+
function matchesAt(pattern, code, index) {
|
|
369
|
+
pattern.lastIndex = index;
|
|
370
|
+
return pattern.test(code);
|
|
371
|
+
}
|
|
372
|
+
function mayBeWrappedCallee(code, start) {
|
|
373
|
+
let index = start - 1;
|
|
374
|
+
while (index >= 0 && WHITESPACE_CHAR.test(code[index])) {
|
|
375
|
+
if (LINE_TERMINATOR.test(code[index])) return true;
|
|
376
|
+
index--;
|
|
377
|
+
}
|
|
378
|
+
return index < 0 || code[index] === "(" || code[index] === ">" || code[index] === "/";
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Cheap, conservative check run before parsing: whether any `require` or
|
|
382
|
+
* `import` occurrence could be a request this transform rewrites. Occurrences
|
|
383
|
+
* that are part of a longer identifier, member properties, static imports,
|
|
384
|
+
* non-callee positions (`typeof require`, `require,`), and calls with a
|
|
385
|
+
* single-line string literal argument other than "/" are left unchanged, so a
|
|
386
|
+
* module containing only those is skipped. Anything else, including escaped
|
|
387
|
+
* identifiers, falls through to the AST pass.
|
|
388
|
+
*/
|
|
389
|
+
function mayContainVeryDynamicRequest(code) {
|
|
390
|
+
REQUIRE_OR_IMPORT_OCCURRENCE.lastIndex = 0;
|
|
391
|
+
for (let match; match = REQUIRE_OR_IMPORT_OCCURRENCE.exec(code);) {
|
|
392
|
+
const text = match[0];
|
|
393
|
+
const start = match.index;
|
|
394
|
+
const end = start + text.length;
|
|
395
|
+
if (text.includes("\\")) return true;
|
|
396
|
+
if (text !== "require" && text !== "import") continue;
|
|
397
|
+
if (IDENTIFIER_CHAR.test(code[start - 1] ?? "") || IDENTIFIER_CHAR.test(code[end] ?? "")) continue;
|
|
398
|
+
if (code[start - 1] === "." && code[start - 2] !== ".") continue;
|
|
399
|
+
if (text === "import") {
|
|
400
|
+
if (matchesAt(POSSIBLE_IMPORT_EXPRESSION_FOLLOWER, code, end) && !matchesAt(UNCHANGED_IMPORT_CALL, code, end)) return true;
|
|
401
|
+
} else if (matchesAt(POSSIBLE_REQUIRE_CALLEE_FOLLOWER, code, end)) {
|
|
402
|
+
if (!matchesAt(UNCHANGED_REQUIRE_CALL, code, end)) return true;
|
|
403
|
+
} else if (matchesAt(CLOSING_PAREN_FOLLOWER, code, end) && mayBeWrappedCallee(code, start)) return true;
|
|
404
|
+
}
|
|
405
|
+
return false;
|
|
406
|
+
}
|
|
358
407
|
function transformVeryDynamicRequests(code, id) {
|
|
359
408
|
if (!REQUIRE_PRESCAN.test(code) && !mayContainDynamicImport(code)) return null;
|
|
409
|
+
if (!mayContainVeryDynamicRequest(code)) return null;
|
|
360
410
|
const lang = scriptParserLanguage(id) ?? "js";
|
|
361
411
|
let ast;
|
|
362
412
|
try {
|
|
@@ -486,7 +536,7 @@ function createIgnoreDynamicRequestsPlugin(getTranspiledPackages = () => []) {
|
|
|
486
536
|
if (!shouldTransformVeryDynamicRequests(this.environment, cleanId, getTranspiledPackages())) return null;
|
|
487
537
|
const absoluteId = path.resolve(cleanId);
|
|
488
538
|
if (absoluteId === VINEXT_SOURCE_ROOT || absoluteId.startsWith(`${VINEXT_SOURCE_ROOT}/`) || PLUGIN_RSC_PATH.test(absoluteId)) return null;
|
|
489
|
-
return cached(id, code, void 0, () => transformVeryDynamicRequests(code, id));
|
|
539
|
+
return omitUnusedBuildSourcemap(this.environment, cached(id, code, void 0, () => transformVeryDynamicRequests(code, id)));
|
|
490
540
|
}
|
|
491
541
|
}
|
|
492
542
|
};
|
|
@@ -498,5 +548,6 @@ function shouldTransformVeryDynamicRequests(environment, id, transpiledPackages)
|
|
|
498
548
|
return !transpiledPackages.some((packageName) => normalizedId.includes(`/node_modules/${packageName}/`));
|
|
499
549
|
}
|
|
500
550
|
const _transformVeryDynamicRequests = transformVeryDynamicRequests;
|
|
551
|
+
const _mayContainVeryDynamicRequest = mayContainVeryDynamicRequest;
|
|
501
552
|
//#endregion
|
|
502
|
-
export { _transformVeryDynamicRequests, createIgnoreDynamicRequestsPlugin };
|
|
553
|
+
export { _mayContainVeryDynamicRequest, _transformVeryDynamicRequests, createIgnoreDynamicRequestsPlugin };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path, { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
2
|
import { SCRIPT_MODULE_ID_RE, collectBindingNames, forEachAstChild, isIdentifierNamed, scriptParserLanguage } from "./ast-utils.js";
|
|
3
|
-
import { magicStringTransformResult } from "./transform-result.js";
|
|
3
|
+
import { magicStringTransformResult, omitUnusedBuildSourcemap } from "./transform-result.js";
|
|
4
4
|
import { canonicalizeFilePath, isPathInsideOrEqual, stripViteModuleQuery } from "../utils/path.js";
|
|
5
5
|
import { VIRTUAL_MODULE_ID_RE } from "../utils/virtual-module.js";
|
|
6
6
|
import fs from "node:fs";
|
|
@@ -80,11 +80,11 @@ function createImportMetaUrlPlugin(options) {
|
|
|
80
80
|
if (dependency) {
|
|
81
81
|
const importMetaUrlReplacement = mayContainImportMetaUrl(code) ? this.environment.mode === "dev" ? JSON.stringify(pathToFileURL(dependency.canonicalId).href) : emittedModuleIdentity.importMetaUrlInitializer : void 0;
|
|
82
82
|
const cjsGlobalInitializers = dependency.isCommonJs && mayContainServerCjsGlobal(code) ? this.environment.mode === "dev" ? sourcePathCjsGlobalInitializers(dependency.canonicalId) : emittedModuleIdentity.cjsGlobalInitializers : void 0;
|
|
83
|
-
if (importMetaUrlReplacement !== void 0 || cjsGlobalInitializers) return rewriteModuleIdentity(code, {
|
|
83
|
+
if (importMetaUrlReplacement !== void 0 || cjsGlobalInitializers) return omitUnusedBuildSourcemap(this.environment, rewriteModuleIdentity(code, {
|
|
84
84
|
id: dependency.canonicalId,
|
|
85
85
|
importMetaUrlReplacement,
|
|
86
86
|
cjsGlobalInitializers
|
|
87
|
-
});
|
|
87
|
+
}));
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
if (isNodeModulesId(cleanId)) return null;
|
|
@@ -106,10 +106,10 @@ function createImportMetaUrlPlugin(options) {
|
|
|
106
106
|
setBoundedCacheEntry(transformCache, id, entry, MAX_TRANSFORM_CACHE_ENTRIES);
|
|
107
107
|
}
|
|
108
108
|
const cached = entry.results.get(transformKind);
|
|
109
|
-
if (cached) return cached.value;
|
|
109
|
+
if (cached) return omitUnusedBuildSourcemap(this.environment, cached.value);
|
|
110
110
|
const value = rewriteCanonicalSourceIdentity(code, canonicalId, paths, environment, this.environment.mode === "build" && mayContainServerCjsGlobal(code) ? emittedModuleIdentity.cjsGlobalInitializers : sourcePathCjsGlobalInitializers(canonicalId));
|
|
111
111
|
entry.results.set(transformKind, { value });
|
|
112
|
-
return value;
|
|
112
|
+
return omitUnusedBuildSourcemap(this.environment, value);
|
|
113
113
|
}
|
|
114
114
|
},
|
|
115
115
|
renderChunk: {
|
|
@@ -117,7 +117,7 @@ function createImportMetaUrlPlugin(options) {
|
|
|
117
117
|
handler(code, chunk, outputOptions) {
|
|
118
118
|
if (this.environment?.config.consumer !== "server" || outputOptions.format !== "es") return null;
|
|
119
119
|
const emittedFileName = resolveEmittedModuleFileName(this.environment?.name, chunk.fileName);
|
|
120
|
-
return finalizeEmittedModuleIdentity(code, emittedModuleIdentity.replacements, emittedFileName);
|
|
120
|
+
return omitUnusedBuildSourcemap(this.environment, finalizeEmittedModuleIdentity(code, emittedModuleIdentity.replacements, emittedFileName));
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
},
|
|
@@ -11,6 +11,7 @@ export declare class OgAssetOwnership {
|
|
|
11
11
|
private readonly stringAliasesByFirstCharacter;
|
|
12
12
|
private regularExpressionAliases;
|
|
13
13
|
private configuredAliases;
|
|
14
|
+
private readonly resolvedImportPackageRoots;
|
|
14
15
|
configure(projectRoot: string, aliases: readonly Alias[]): void;
|
|
15
16
|
reset(): void;
|
|
16
17
|
shouldTrackImport(source: string): boolean;
|
|
@@ -19,6 +20,7 @@ export declare class OgAssetOwnership {
|
|
|
19
20
|
resolveContainedAsset(assetRoot: string, assetPath: string): Promise<string | null>;
|
|
20
21
|
private findAlias;
|
|
21
22
|
private getExpectedPackageName;
|
|
23
|
+
private findResolvedImportPackageRoot;
|
|
22
24
|
private resolveAliasPackageRoot;
|
|
23
25
|
private resolveConfiguredAliasRoot;
|
|
24
26
|
}
|
|
@@ -93,8 +93,10 @@ var OgAssetOwnership = class {
|
|
|
93
93
|
stringAliasesByFirstCharacter = /* @__PURE__ */ new Map();
|
|
94
94
|
regularExpressionAliases = [];
|
|
95
95
|
configuredAliases = [];
|
|
96
|
+
resolvedImportPackageRoots = /* @__PURE__ */ new Map();
|
|
96
97
|
configure(projectRoot, aliases) {
|
|
97
98
|
this.projectRoot = path.resolve(projectRoot);
|
|
99
|
+
this.resolvedImportPackageRoots.clear();
|
|
98
100
|
this.dependencyPackageNames.clear();
|
|
99
101
|
try {
|
|
100
102
|
const manifest = JSON.parse(fs.readFileSync(path.join(this.projectRoot, "package.json"), "utf8"));
|
|
@@ -129,25 +131,20 @@ var OgAssetOwnership = class {
|
|
|
129
131
|
}
|
|
130
132
|
reset() {
|
|
131
133
|
this.linkedPackageRoots.clear();
|
|
134
|
+
this.resolvedImportPackageRoots.clear();
|
|
132
135
|
}
|
|
133
136
|
shouldTrackImport(source) {
|
|
134
137
|
return this.findAlias(source) !== void 0 || this.getExpectedPackageName(source) !== void 0;
|
|
135
138
|
}
|
|
136
139
|
async recordResolvedImport(source, resolvedId) {
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
try {
|
|
143
|
-
realResolvedPath = await realpathNative(path.resolve(stripViteModuleQuery(resolvedId)));
|
|
144
|
-
} catch {
|
|
145
|
-
return;
|
|
140
|
+
const key = `${source}\0${resolvedId}`;
|
|
141
|
+
let packageRoot = this.resolvedImportPackageRoots.get(key);
|
|
142
|
+
if (packageRoot === void 0) {
|
|
143
|
+
packageRoot = this.findResolvedImportPackageRoot(source, resolvedId);
|
|
144
|
+
this.resolvedImportPackageRoots.set(key, packageRoot);
|
|
146
145
|
}
|
|
147
|
-
|
|
148
|
-
if (
|
|
149
|
-
else packageRoot = await findPackageRoot(path.dirname(realResolvedPath), expectedPackageName);
|
|
150
|
-
if (packageRoot !== null) this.linkedPackageRoots.add(packageRoot);
|
|
146
|
+
const root = await packageRoot;
|
|
147
|
+
if (root !== null) this.linkedPackageRoots.add(root);
|
|
151
148
|
}
|
|
152
149
|
async resolveModuleBoundary(moduleId) {
|
|
153
150
|
const modulePath = path.resolve(stripViteModuleQuery(moduleId));
|
|
@@ -219,6 +216,20 @@ var OgAssetOwnership = class {
|
|
|
219
216
|
const packageName = packageNameFromSpecifier(source);
|
|
220
217
|
return packageName === null ? void 0 : this.dependencyPackageNames.get(packageName);
|
|
221
218
|
}
|
|
219
|
+
async findResolvedImportPackageRoot(source, resolvedId) {
|
|
220
|
+
const configuredAlias = this.findAlias(source);
|
|
221
|
+
const sourcePackageName = packageNameFromSpecifier(source);
|
|
222
|
+
const expectedPackageName = this.getExpectedPackageName(source);
|
|
223
|
+
if (configuredAlias === void 0 && expectedPackageName === void 0) return null;
|
|
224
|
+
let realResolvedPath;
|
|
225
|
+
try {
|
|
226
|
+
realResolvedPath = await realpathNative(path.resolve(stripViteModuleQuery(resolvedId)));
|
|
227
|
+
} catch {
|
|
228
|
+
return null;
|
|
229
|
+
}
|
|
230
|
+
if (configuredAlias !== void 0) return this.resolveAliasPackageRoot(configuredAlias, source, sourcePackageName, realResolvedPath);
|
|
231
|
+
return findPackageRoot(path.dirname(realResolvedPath), expectedPackageName);
|
|
232
|
+
}
|
|
222
233
|
async resolveAliasPackageRoot(alias, source, sourcePackageName, realResolvedPath) {
|
|
223
234
|
const aliasTarget = applyAlias(alias.find, alias.replacement, source);
|
|
224
235
|
if (!path.isAbsolute(aliasTarget)) return null;
|
|
@@ -11,6 +11,24 @@ import { Plugin } from "vite";
|
|
|
11
11
|
* valid file URL.
|
|
12
12
|
*/
|
|
13
13
|
export declare function createOgInlineFetchAssetsPlugin(): Plugin;
|
|
14
|
+
type ReadFileSyncAssetUrlMatch = {
|
|
15
|
+
start: number;
|
|
16
|
+
end: number;
|
|
17
|
+
relPath: string;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Find every `<identifier>.readFileSync(fileURLToPath(new URL("./file", import.meta.url)))`
|
|
21
|
+
* call in `code`.
|
|
22
|
+
*
|
|
23
|
+
* Returns the same matches, in the same order, as `code.matchAll()` with
|
|
24
|
+
* `/[a-zA-Z_$][a-zA-Z0-9_$]*` followed by `READ_FILE_SYNC_ASSET_URL_TAIL_RE` as a
|
|
25
|
+
* global regex. That regex retries the identifier prefix at every identifier
|
|
26
|
+
* character of the module, which is slow on large bundles such as typescript.js.
|
|
27
|
+
* A match's identifier always ends right at a `.readFileSync(` occurrence, so
|
|
28
|
+
* candidates are found with `indexOf` and the identifier is recovered by
|
|
29
|
+
* scanning backwards.
|
|
30
|
+
*/
|
|
31
|
+
export declare function matchReadFileSyncAssetUrls(code: string): ReadFileSyncAssetUrlMatch[];
|
|
14
32
|
/**
|
|
15
33
|
* Copy a single root copy of each requested WASM asset from `sourceDir` into
|
|
16
34
|
* `outDir`, skipping any asset whose source is missing or whose destination
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
|
-
import { magicStringTransformResult } from "./transform-result.js";
|
|
2
|
+
import { magicStringTransformResult, omitUnusedBuildSourcemap } from "./transform-result.js";
|
|
3
3
|
import { resolveHarfbuzzWasmPath } from "./og-harfbuzz.js";
|
|
4
4
|
import { OgAssetOwnership } from "./og-asset-ownership.js";
|
|
5
5
|
import { createRequire } from "node:module";
|
|
@@ -80,21 +80,63 @@ function createOgInlineFetchAssetsPlugin() {
|
|
|
80
80
|
s.overwrite(match.index, match.index + fullMatch.length, inlined);
|
|
81
81
|
didReplace = true;
|
|
82
82
|
}
|
|
83
|
-
if (code.includes("readFileSync(")) for (const match of code
|
|
84
|
-
const
|
|
85
|
-
const relPath = match[2];
|
|
86
|
-
const fileBase64 = await readAsBase64(path.resolve(moduleDir, relPath));
|
|
83
|
+
if (code.includes("readFileSync(")) for (const match of matchReadFileSyncAssetUrls(code)) {
|
|
84
|
+
const fileBase64 = await readAsBase64(path.resolve(moduleDir, match.relPath));
|
|
87
85
|
if (fileBase64 === null) continue;
|
|
88
86
|
const inlined = `Buffer.from(${JSON.stringify(fileBase64)},"base64")`;
|
|
89
|
-
s.overwrite(match.
|
|
87
|
+
s.overwrite(match.start, match.end, inlined);
|
|
90
88
|
didReplace = true;
|
|
91
89
|
}
|
|
92
90
|
if (!didReplace) return null;
|
|
93
|
-
return magicStringTransformResult(s);
|
|
91
|
+
return omitUnusedBuildSourcemap(this.environment, magicStringTransformResult(s));
|
|
94
92
|
}
|
|
95
93
|
}
|
|
96
94
|
};
|
|
97
95
|
}
|
|
96
|
+
const READ_FILE_SYNC_ASSET_URL_TAIL_RE = /\.readFileSync\(\s*(?:[a-zA-Z_$][a-zA-Z0-9_$]*\.)?fileURLToPath\(\s*new URL\(\s*(["'])(\.[^"']+)\1\s*,\s*import\.meta\.url\s*\)\s*\)\s*\)/y;
|
|
97
|
+
/**
|
|
98
|
+
* Find every `<identifier>.readFileSync(fileURLToPath(new URL("./file", import.meta.url)))`
|
|
99
|
+
* call in `code`.
|
|
100
|
+
*
|
|
101
|
+
* Returns the same matches, in the same order, as `code.matchAll()` with
|
|
102
|
+
* `/[a-zA-Z_$][a-zA-Z0-9_$]*` followed by `READ_FILE_SYNC_ASSET_URL_TAIL_RE` as a
|
|
103
|
+
* global regex. That regex retries the identifier prefix at every identifier
|
|
104
|
+
* character of the module, which is slow on large bundles such as typescript.js.
|
|
105
|
+
* A match's identifier always ends right at a `.readFileSync(` occurrence, so
|
|
106
|
+
* candidates are found with `indexOf` and the identifier is recovered by
|
|
107
|
+
* scanning backwards.
|
|
108
|
+
*/
|
|
109
|
+
function matchReadFileSyncAssetUrls(code) {
|
|
110
|
+
const matches = [];
|
|
111
|
+
let searchFrom = 0;
|
|
112
|
+
let dot = code.indexOf(".readFileSync(");
|
|
113
|
+
while (dot !== -1) {
|
|
114
|
+
let start = dot;
|
|
115
|
+
while (start > searchFrom && isAsciiIdentifierPart(code.charCodeAt(start - 1))) start--;
|
|
116
|
+
while (start < dot && !isAsciiIdentifierStart(code.charCodeAt(start))) start++;
|
|
117
|
+
if (start < dot) {
|
|
118
|
+
READ_FILE_SYNC_ASSET_URL_TAIL_RE.lastIndex = dot;
|
|
119
|
+
const tail = READ_FILE_SYNC_ASSET_URL_TAIL_RE.exec(code);
|
|
120
|
+
if (tail !== null) {
|
|
121
|
+
const end = dot + tail[0].length;
|
|
122
|
+
matches.push({
|
|
123
|
+
start,
|
|
124
|
+
end,
|
|
125
|
+
relPath: tail[2]
|
|
126
|
+
});
|
|
127
|
+
searchFrom = end;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
dot = code.indexOf(".readFileSync(", Math.max(dot + 1, searchFrom));
|
|
131
|
+
}
|
|
132
|
+
return matches;
|
|
133
|
+
}
|
|
134
|
+
function isAsciiIdentifierStart(charCode) {
|
|
135
|
+
return charCode >= 97 && charCode <= 122 || charCode >= 65 && charCode <= 90 || charCode === 95 || charCode === 36;
|
|
136
|
+
}
|
|
137
|
+
function isAsciiIdentifierPart(charCode) {
|
|
138
|
+
return isAsciiIdentifierStart(charCode) || charCode >= 48 && charCode <= 57;
|
|
139
|
+
}
|
|
98
140
|
const OG_WASM_ASSETS = [
|
|
99
141
|
"resvg.wasm",
|
|
100
142
|
"yoga.wasm",
|
|
@@ -243,4 +285,4 @@ function createOgAssetsPlugin() {
|
|
|
243
285
|
};
|
|
244
286
|
}
|
|
245
287
|
//#endregion
|
|
246
|
-
export { copyMissingOgWasm, createOgAssetsPlugin, createOgInlineFetchAssetsPlugin };
|
|
288
|
+
export { copyMissingOgWasm, createOgAssetsPlugin, createOgInlineFetchAssetsPlugin, matchReadFileSyncAssetUrls };
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import path, { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
2
|
import { forEachAstChild, getAstName, staticStringValue } from "./ast-utils.js";
|
|
3
|
-
import { magicStringTransformResult } from "./transform-result.js";
|
|
3
|
+
import { magicStringTransformResult, omitUnusedBuildSourcemap } from "./transform-result.js";
|
|
4
4
|
import { isFunctionNode } from "./ast-scope.js";
|
|
5
|
+
import { createTransformCache } from "./transform-cache.js";
|
|
5
6
|
import { createRequire } from "node:module";
|
|
6
7
|
import fs from "node:fs";
|
|
7
8
|
import { parseAst } from "vite";
|
|
@@ -210,9 +211,43 @@ const INSTANTIATE_WASM = `function __vi_hb_instantiateWasm(imports, receiveInsta
|
|
|
210
211
|
receiveInstance(instance);
|
|
211
212
|
return instance.exports;
|
|
212
213
|
}`;
|
|
214
|
+
/**
|
|
215
|
+
* Patch one @vercel/og entry bundle. The result depends only on the bundle
|
|
216
|
+
* source, its id, the command and the callback module directory; callback
|
|
217
|
+
* modules are written once and reused by later calls.
|
|
218
|
+
*/
|
|
219
|
+
function patchHarfbuzzBundle(code, id, isBuild, callbackModuleDir, error) {
|
|
220
|
+
const ogEntry = toSlash(id.split("?", 1)[0]);
|
|
221
|
+
const isWorkerd = ogEntry.endsWith("/index.edge.js");
|
|
222
|
+
const fail = (reason) => error(`[vinext] Unsupported @vercel/og HarfBuzz bundle in ${ogEntry}: ${reason}. vinext must be updated to support this @vercel/og version.`);
|
|
223
|
+
const sites = findHarfbuzzPatchSites(parseAst(code, { lang: "js" }));
|
|
224
|
+
if (typeof sites === "string") return fail(sites);
|
|
225
|
+
const output = new MagicString(code);
|
|
226
|
+
for (const flag of sites.environmentFlags) output.overwrite(flag.start, flag.end, "false");
|
|
227
|
+
for (const member of sites.instantiateWasmReads) output.overwrite(member.start, member.end, "__vi_hb_instantiateWasm");
|
|
228
|
+
const harfbuzzWasm = resolveHarfbuzzWasmPath(ogEntry);
|
|
229
|
+
const preamble = [];
|
|
230
|
+
if (isWorkerd) {
|
|
231
|
+
if (sites.moduleCompilations.length === 0) return fail("no callback module compilation (new WebAssembly.Module) was found");
|
|
232
|
+
for (const { node, enclosingFunction } of sites.moduleCompilations) {
|
|
233
|
+
const signature = isFunctionNode(enclosingFunction) ? enclosingFunction.params[1] : void 0;
|
|
234
|
+
if (signature?.type !== "Identifier") return fail("the callback compiler does not take a (func, sig) signature");
|
|
235
|
+
output.prependLeft(node.start, `(__vi_hb_callbacks[${signature.name}.replace(/p/g, "i")] || `);
|
|
236
|
+
output.appendRight(node.end, ")");
|
|
237
|
+
}
|
|
238
|
+
const callbacks = [...writeHarfbuzzCallbackModules(harfbuzzWasm, callbackModuleDir)];
|
|
239
|
+
preamble.push(`import __vi_hb_wasm from ${JSON.stringify(`${harfbuzzWasm}?module`)};`, ...callbacks.map(([, file], index) => `import __vi_hb_callback_${index} from ${JSON.stringify(`${file}?module`)};`), `var __vi_hb_callbacks = { ${callbacks.map(([signature], index) => `${signature}: __vi_hb_callback_${index}`).join(", ")} };`, "function __vi_hb_module() { return __vi_hb_wasm; }");
|
|
240
|
+
} else {
|
|
241
|
+
const location = isBuild ? `new URL("./${HARFBUZZ_WASM}", import.meta.url)` : JSON.stringify(harfbuzzWasm);
|
|
242
|
+
preamble.push(`import { readFileSync as __vi_hb_readFileSync } from "node:fs";`, `function __vi_hb_module() { return new WebAssembly.Module(__vi_hb_readFileSync(${location})); }`);
|
|
243
|
+
}
|
|
244
|
+
output.prepend(`${preamble.join("\n")}\n${INSTANTIATE_WASM}\n`);
|
|
245
|
+
return magicStringTransformResult(output);
|
|
246
|
+
}
|
|
213
247
|
function createOgHarfbuzzPlugin() {
|
|
214
248
|
let callbackModuleDir;
|
|
215
249
|
let isBuild = false;
|
|
250
|
+
const cached = createTransformCache();
|
|
216
251
|
return {
|
|
217
252
|
name: "vinext:og-harfbuzz",
|
|
218
253
|
enforce: "pre",
|
|
@@ -226,32 +261,8 @@ function createOgHarfbuzzPlugin() {
|
|
|
226
261
|
code: /["'`]hb\.wasm["'`]/
|
|
227
262
|
},
|
|
228
263
|
handler(code, id) {
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
-
const fail = (reason) => this.error(`[vinext] Unsupported @vercel/og HarfBuzz bundle in ${ogEntry}: ${reason}. vinext must be updated to support this @vercel/og version.`);
|
|
232
|
-
const sites = findHarfbuzzPatchSites(parseAst(code, { lang: "js" }));
|
|
233
|
-
if (typeof sites === "string") return fail(sites);
|
|
234
|
-
const output = new MagicString(code);
|
|
235
|
-
for (const flag of sites.environmentFlags) output.overwrite(flag.start, flag.end, "false");
|
|
236
|
-
for (const member of sites.instantiateWasmReads) output.overwrite(member.start, member.end, "__vi_hb_instantiateWasm");
|
|
237
|
-
const harfbuzzWasm = resolveHarfbuzzWasmPath(ogEntry);
|
|
238
|
-
const preamble = [];
|
|
239
|
-
if (isWorkerd) {
|
|
240
|
-
if (sites.moduleCompilations.length === 0) return fail("no callback module compilation (new WebAssembly.Module) was found");
|
|
241
|
-
for (const { node, enclosingFunction } of sites.moduleCompilations) {
|
|
242
|
-
const signature = isFunctionNode(enclosingFunction) ? enclosingFunction.params[1] : void 0;
|
|
243
|
-
if (signature?.type !== "Identifier") return fail("the callback compiler does not take a (func, sig) signature");
|
|
244
|
-
output.prependLeft(node.start, `(__vi_hb_callbacks[${signature.name}.replace(/p/g, "i")] || `);
|
|
245
|
-
output.appendRight(node.end, ")");
|
|
246
|
-
}
|
|
247
|
-
const callbacks = [...writeHarfbuzzCallbackModules(harfbuzzWasm, callbackModuleDir)];
|
|
248
|
-
preamble.push(`import __vi_hb_wasm from ${JSON.stringify(`${harfbuzzWasm}?module`)};`, ...callbacks.map(([, file], index) => `import __vi_hb_callback_${index} from ${JSON.stringify(`${file}?module`)};`), `var __vi_hb_callbacks = { ${callbacks.map(([signature], index) => `${signature}: __vi_hb_callback_${index}`).join(", ")} };`, "function __vi_hb_module() { return __vi_hb_wasm; }");
|
|
249
|
-
} else {
|
|
250
|
-
const location = isBuild ? `new URL("./${HARFBUZZ_WASM}", import.meta.url)` : JSON.stringify(harfbuzzWasm);
|
|
251
|
-
preamble.push(`import { readFileSync as __vi_hb_readFileSync } from "node:fs";`, `function __vi_hb_module() { return new WebAssembly.Module(__vi_hb_readFileSync(${location})); }`);
|
|
252
|
-
}
|
|
253
|
-
output.prepend(`${preamble.join("\n")}\n${INSTANTIATE_WASM}\n`);
|
|
254
|
-
return magicStringTransformResult(output);
|
|
264
|
+
const patch = () => patchHarfbuzzBundle(code, id, isBuild, callbackModuleDir, (message) => this.error(message));
|
|
265
|
+
return omitUnusedBuildSourcemap(this.environment, isBuild ? cached(id, code, callbackModuleDir, patch) : patch());
|
|
255
266
|
}
|
|
256
267
|
}
|
|
257
268
|
};
|
|
@@ -108,7 +108,8 @@ function createOptimizedImportSourceMatcher(packages) {
|
|
|
108
108
|
const pattern = [...packages].map(escapeRegExp).join("|");
|
|
109
109
|
if (!pattern) return () => false;
|
|
110
110
|
const importFromPattern = new RegExp(String.raw`(?:^|[;}\n\r])\s*import(?!\s*\()(?:(?!\bfrom\b)[\s\S])*?\bfrom\s*["'](?:${pattern})["']`, "m");
|
|
111
|
-
|
|
111
|
+
const quotedSourcePattern = new RegExp(String.raw`["'](?:${pattern})["']`);
|
|
112
|
+
return (code) => code.includes("import") && code.includes("from") && quotedSourcePattern.test(code) && importFromPattern.test(code);
|
|
112
113
|
}
|
|
113
114
|
/**
|
|
114
115
|
* Resolve a package.json exports value to a string entry path.
|
|
@@ -51,7 +51,34 @@ function createRequireContextPlugin() {
|
|
|
51
51
|
}
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
|
+
const CONTEXT_CALL_SPACE = String.raw`[\s\u0085\u200b]`;
|
|
55
|
+
const LINE_TERMINATOR = String.raw`[\n\r\u2028\u2029]`;
|
|
56
|
+
const CONTEXT_PROPERTY = String.raw`(?:c|\\u(?:0063|\{0*63\}))(?:o|\\u(?:006f|\{0*6f\}))(?:n|\\u(?:006e|\{0*6e\}))(?:t|\\u(?:0074|\{0*74\}))(?:e|\\u(?:0065|\{0*65\}))(?:x|\\u(?:0078|\{0*78\}))(?:t|\\u(?:0074|\{0*74\}))`;
|
|
57
|
+
const CONTEXT_MEMBER_PREFIX = String.raw`(?:\.|\*\/|(?:\/\/|<!--|-->)[^\n\r\u2028\u2029]*${LINE_TERMINATOR})${CONTEXT_CALL_SPACE}*`;
|
|
58
|
+
const COMMENT_OPENER = String.raw`\/[*/]|<!--|-->`;
|
|
59
|
+
/**
|
|
60
|
+
* Cheap pre-parse gate for {@link transformRequireContext}. The transform only
|
|
61
|
+
* rewrites a `.context` member call whose first argument is a string literal,
|
|
62
|
+
* so the source must contain `.`, `context`, then — after optional closing
|
|
63
|
+
* parens of a `(require.context)` callee and an optional `?.` — a `(` followed
|
|
64
|
+
* by optional opening parens and a quote. TypeScript type arguments
|
|
65
|
+
* (`context<T>(...)`) are not scanned: any `<` after `context` keeps the parse.
|
|
66
|
+
*
|
|
67
|
+
* The transform filter admits every module that mentions both `require` and
|
|
68
|
+
* `.context` (React, TypeScript, ...), and parsing multi-MB dependencies that
|
|
69
|
+
* can never contain a matching call dominated this plugin's cost. The gate
|
|
70
|
+
* errs toward over-matching: a false positive costs one redundant parse,
|
|
71
|
+
* whereas a false negative would silently skip a real `require.context` call.
|
|
72
|
+
* Comments therefore count as a match instead of being scanned, and the match
|
|
73
|
+
* starts at `context` and looks back for the `.`. Every repetition then covers
|
|
74
|
+
* only whitespace and parens next to one `context`, so the scan stays linear.
|
|
75
|
+
*/
|
|
76
|
+
const REQUIRE_CONTEXT_CALL_PRESCAN = new RegExp(String.raw`${CONTEXT_PROPERTY}(?<=${CONTEXT_MEMBER_PREFIX}${CONTEXT_PROPERTY})(?:${CONTEXT_CALL_SPACE}|\))*(?:\?\.${CONTEXT_CALL_SPACE}*)?(?:<|${COMMENT_OPENER}|\((?:${CONTEXT_CALL_SPACE}|\()*(?:["']|${COMMENT_OPENER}))`, "i");
|
|
77
|
+
function _mayContainRequireContextCall(code) {
|
|
78
|
+
return REQUIRE_CONTEXT_CALL_PRESCAN.test(code);
|
|
79
|
+
}
|
|
54
80
|
async function transformRequireContext(code, id) {
|
|
81
|
+
if (!REQUIRE_CONTEXT_CALL_PRESCAN.test(code)) return null;
|
|
55
82
|
const lang = scriptParserLanguage(id);
|
|
56
83
|
let ast;
|
|
57
84
|
try {
|
|
@@ -261,4 +288,4 @@ function stripTrailingSlash(value) {
|
|
|
261
288
|
return value.endsWith("/") ? value.slice(0, -1) : value;
|
|
262
289
|
}
|
|
263
290
|
//#endregion
|
|
264
|
-
export { createRequireContextPlugin };
|
|
291
|
+
export { _mayContainRequireContextCall, createRequireContextPlugin };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Plugin } from "vite";
|
|
2
|
+
//#region src/plugins/scan-build-css.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* @vitejs/plugin-rsc discovers client and server references with two
|
|
5
|
+
* write-less scan builds whose output is discarded, and its `rsc:scan-strip`
|
|
6
|
+
* plugin reduces every module to its import specifiers. A stylesheet cannot
|
|
7
|
+
* contribute a JavaScript import, yet without this plugin every stylesheet in
|
|
8
|
+
* the app still ran through PostCSS/Tailwind/Sass in both scans. Empty their
|
|
9
|
+
* source during those scans only; real builds and dev are unchanged.
|
|
10
|
+
*/
|
|
11
|
+
export declare function createScanBuildCssPlugin(): Plugin;
|
|
12
|
+
//#endregion
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
//#region src/plugins/scan-build-css.ts
|
|
2
|
+
const CSS_LANGS_RE = /\.(?:css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/;
|
|
3
|
+
const SPECIAL_QUERY_RE = /[?&](?:worker|sharedworker|raw|url)\b/;
|
|
4
|
+
const VIRTUAL_MODULE_RE = /^\0/;
|
|
5
|
+
/**
|
|
6
|
+
* @vitejs/plugin-rsc discovers client and server references with two
|
|
7
|
+
* write-less scan builds whose output is discarded, and its `rsc:scan-strip`
|
|
8
|
+
* plugin reduces every module to its import specifiers. A stylesheet cannot
|
|
9
|
+
* contribute a JavaScript import, yet without this plugin every stylesheet in
|
|
10
|
+
* the app still ran through PostCSS/Tailwind/Sass in both scans. Empty their
|
|
11
|
+
* source during those scans only; real builds and dev are unchanged.
|
|
12
|
+
*/
|
|
13
|
+
function createScanBuildCssPlugin() {
|
|
14
|
+
let rscApi;
|
|
15
|
+
return {
|
|
16
|
+
name: "vinext:scan-build-css",
|
|
17
|
+
enforce: "pre",
|
|
18
|
+
apply: "build",
|
|
19
|
+
configResolved(config) {
|
|
20
|
+
rscApi = config.plugins.find((plugin) => plugin.name === "rsc:minimal")?.api;
|
|
21
|
+
},
|
|
22
|
+
transform: {
|
|
23
|
+
order: "pre",
|
|
24
|
+
filter: { id: {
|
|
25
|
+
include: CSS_LANGS_RE,
|
|
26
|
+
exclude: [SPECIAL_QUERY_RE, VIRTUAL_MODULE_RE]
|
|
27
|
+
} },
|
|
28
|
+
handler() {
|
|
29
|
+
if (!rscApi?.manager.isScanBuild || this.environment.config.build.write !== false) return null;
|
|
30
|
+
return {
|
|
31
|
+
code: "",
|
|
32
|
+
map: null
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
//#endregion
|
|
39
|
+
export { createScanBuildCssPlugin };
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import MagicString from "magic-string";
|
|
2
2
|
//#region src/plugins/strip-server-exports.d.ts
|
|
3
3
|
export declare function hasServerExportCandidate(code: string): boolean;
|
|
4
|
+
/** Transform prefilter; must admit every module `hasExportAllCandidate` accepts */
|
|
5
|
+
export declare const EXPORT_ALL_CANDIDATE_FILTER: RegExp;
|
|
4
6
|
export declare function hasExportAllCandidate(code: string): boolean;
|
|
5
7
|
export declare function validatePageExports(code: string): void;
|
|
6
8
|
type StripServerExportsResult = {
|
|
@@ -18,6 +18,8 @@ function hasServerExportCandidate(code) {
|
|
|
18
18
|
for (const name of SERVER_EXPORTS) if (code.includes(name)) return true;
|
|
19
19
|
return false;
|
|
20
20
|
}
|
|
21
|
+
/** Transform prefilter; must admit every module `hasExportAllCandidate` accepts */
|
|
22
|
+
const EXPORT_ALL_CANDIDATE_FILTER = /\bexport\s*[*/]/;
|
|
21
23
|
function hasExportAllCandidate(code) {
|
|
22
24
|
let searchFrom = 0;
|
|
23
25
|
while (searchFrom < code.length) {
|
|
@@ -510,4 +512,4 @@ function stripServerExports(code) {
|
|
|
510
512
|
return magicStringTransformResult(string);
|
|
511
513
|
}
|
|
512
514
|
//#endregion
|
|
513
|
-
export { hasExportAllCandidate, hasServerExportCandidate, stripServerExports, validatePageExports };
|
|
515
|
+
export { EXPORT_ALL_CANDIDATE_FILTER, hasExportAllCandidate, hasServerExportCandidate, stripServerExports, validatePageExports };
|
|
@@ -4,6 +4,24 @@ export type MagicStringTransformResult = {
|
|
|
4
4
|
code: string;
|
|
5
5
|
map: ReturnType<MagicString["generateMap"]>;
|
|
6
6
|
};
|
|
7
|
+
type SourcemapEnvironment = {
|
|
8
|
+
mode?: string;
|
|
9
|
+
config?: {
|
|
10
|
+
build?: {
|
|
11
|
+
sourcemap?: boolean | "inline" | "hidden";
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
};
|
|
7
15
|
/** Build the standard code + sourcemap result returned by source transforms. */
|
|
8
16
|
export declare function magicStringTransformResult(output: MagicString, options?: Parameters<MagicString["generateMap"]>[0]): MagicStringTransformResult;
|
|
17
|
+
/**
|
|
18
|
+
* Drop the sourcemap from a transform result when the build environment
|
|
19
|
+
* discards it, mirroring Vite's own transforms
|
|
20
|
+
* (`config.build.sourcemap ? s.generateMap(...) : null`). Dev and builds with
|
|
21
|
+
* sourcemaps enabled keep the result unchanged.
|
|
22
|
+
*/
|
|
23
|
+
export declare function omitUnusedBuildSourcemap(environment: SourcemapEnvironment | undefined, result: MagicStringTransformResult | null): {
|
|
24
|
+
code: string;
|
|
25
|
+
map: MagicStringTransformResult["map"] | null;
|
|
26
|
+
} | null;
|
|
9
27
|
//#endregion
|
|
@@ -1,10 +1,31 @@
|
|
|
1
1
|
//#region src/plugins/transform-result.ts
|
|
2
2
|
/** Build the standard code + sourcemap result returned by source transforms. */
|
|
3
3
|
function magicStringTransformResult(output, options = { hires: "boundary" }) {
|
|
4
|
+
let source = output;
|
|
5
|
+
let map;
|
|
4
6
|
return {
|
|
5
7
|
code: output.toString(),
|
|
6
|
-
map
|
|
8
|
+
get map() {
|
|
9
|
+
if (source) {
|
|
10
|
+
map = source.generateMap(options);
|
|
11
|
+
source = void 0;
|
|
12
|
+
}
|
|
13
|
+
return map;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Drop the sourcemap from a transform result when the build environment
|
|
19
|
+
* discards it, mirroring Vite's own transforms
|
|
20
|
+
* (`config.build.sourcemap ? s.generateMap(...) : null`). Dev and builds with
|
|
21
|
+
* sourcemaps enabled keep the result unchanged.
|
|
22
|
+
*/
|
|
23
|
+
function omitUnusedBuildSourcemap(environment, result) {
|
|
24
|
+
if (!result || environment?.mode !== "build" || environment.config?.build?.sourcemap !== false) return result;
|
|
25
|
+
return {
|
|
26
|
+
code: result.code,
|
|
27
|
+
map: null
|
|
7
28
|
};
|
|
8
29
|
}
|
|
9
30
|
//#endregion
|
|
10
|
-
export { magicStringTransformResult };
|
|
31
|
+
export { magicStringTransformResult, omitUnusedBuildSourcemap };
|
|
@@ -6,6 +6,11 @@ export type ConsumerEnvironmentReplacements = {
|
|
|
6
6
|
typeofWindow?: WindowType;
|
|
7
7
|
processBrowser?: boolean;
|
|
8
8
|
pruneUnreachableImports?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Return null without walking the AST when folding cannot change the module's
|
|
11
|
+
* scanned imports. Only valid for import-scan builds.
|
|
12
|
+
*/
|
|
13
|
+
onlyIfScannedImportsChange?: boolean;
|
|
9
14
|
};
|
|
10
15
|
type EnvironmentLike = {
|
|
11
16
|
config: {
|
|
@@ -13,6 +18,11 @@ type EnvironmentLike = {
|
|
|
13
18
|
};
|
|
14
19
|
};
|
|
15
20
|
export declare function getTypeofWindowReplacement(environment: EnvironmentLike): WindowType;
|
|
21
|
+
/**
|
|
22
|
+
* Cheap pre-parse gate for import-scan builds. Over-inclusive by design; the
|
|
23
|
+
* parser's module record in {@link moduleRecordHasScannedFoldTargets} is exact.
|
|
24
|
+
*/
|
|
25
|
+
export declare function mayFoldChangeScannedImports(code: string): boolean;
|
|
16
26
|
export declare function replaceTypeofWindow(code: string, replacement: WindowType, id?: string): MagicStringTransformResult | null;
|
|
17
27
|
export declare function replaceConsumerEnvironmentConditions(code: string, replacements: ConsumerEnvironmentReplacements, id?: string): MagicStringTransformResult | null;
|
|
18
28
|
//#endregion
|