vinext 0.1.0 → 0.1.2
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/assets-ignore.d.ts +32 -0
- package/dist/build/assets-ignore.js +48 -0
- package/dist/build/client-build-config.d.ts +33 -1
- package/dist/build/client-build-config.js +66 -1
- package/dist/check.js +4 -3
- package/dist/cli.js +2 -0
- package/dist/client/navigation-runtime.d.ts +11 -2
- package/dist/client/navigation-runtime.js +1 -1
- package/dist/client/vinext-next-data.d.ts +2 -1
- package/dist/client/window-next.d.ts +6 -4
- package/dist/config/config-matchers.d.ts +31 -5
- package/dist/config/config-matchers.js +50 -3
- package/dist/config/next-config.d.ts +29 -3
- package/dist/config/next-config.js +32 -2
- package/dist/deploy.js +47 -304
- package/dist/entries/app-rsc-entry.d.ts +8 -2
- package/dist/entries/app-rsc-entry.js +61 -5
- package/dist/entries/app-rsc-manifest.js +20 -2
- package/dist/entries/pages-client-entry.js +1 -1
- package/dist/entries/pages-server-entry.js +16 -7
- package/dist/index.d.ts +0 -2
- package/dist/index.js +233 -280
- package/dist/plugins/dynamic-preload-metadata.d.ts +13 -0
- package/dist/plugins/dynamic-preload-metadata.js +415 -0
- package/dist/plugins/og-assets.js +2 -2
- package/dist/plugins/optimize-imports.d.ts +8 -4
- package/dist/plugins/optimize-imports.js +16 -12
- package/dist/plugins/postcss.js +18 -14
- package/dist/plugins/require-context.d.ts +6 -0
- package/dist/plugins/require-context.js +184 -0
- package/dist/plugins/sass.d.ts +53 -24
- package/dist/plugins/sass.js +249 -1
- 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 +35 -2
- package/dist/routing/app-route-graph.js +179 -8
- package/dist/routing/file-matcher.js +1 -1
- package/dist/routing/route-pattern.d.ts +2 -1
- package/dist/routing/route-pattern.js +16 -1
- package/dist/server/api-handler.js +4 -0
- package/dist/server/app-browser-entry.js +155 -215
- package/dist/server/app-browser-error.d.ts +4 -1
- package/dist/server/app-browser-error.js +7 -1
- 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-interception-context.d.ts +2 -1
- package/dist/server/app-browser-interception-context.js +15 -2
- package/dist/server/app-browser-navigation-controller.d.ts +13 -2
- package/dist/server/app-browser-navigation-controller.js +83 -4
- package/dist/server/app-browser-popstate.d.ts +12 -3
- package/dist/server/app-browser-popstate.js +19 -4
- 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-state.d.ts +3 -0
- package/dist/server/app-browser-state.js +10 -10
- package/dist/server/app-browser-visible-commit.js +10 -8
- package/dist/server/app-fallback-renderer.d.ts +2 -1
- package/dist/server/app-fallback-renderer.js +3 -1
- package/dist/server/app-history-state.d.ts +45 -1
- package/dist/server/app-history-state.js +109 -1
- package/dist/server/app-middleware.js +1 -0
- package/dist/server/app-optimistic-routing.js +22 -1
- package/dist/server/app-page-boundary-render.d.ts +2 -1
- package/dist/server/app-page-boundary-render.js +45 -21
- package/dist/server/app-page-cache.js +9 -7
- package/dist/server/app-page-dispatch.d.ts +14 -0
- package/dist/server/app-page-dispatch.js +21 -6
- package/dist/server/app-page-element-builder.d.ts +23 -2
- package/dist/server/app-page-element-builder.js +58 -17
- package/dist/server/app-page-execution.d.ts +1 -1
- package/dist/server/app-page-execution.js +32 -17
- package/dist/server/app-page-render.d.ts +7 -1
- package/dist/server/app-page-render.js +11 -16
- package/dist/server/app-page-request.d.ts +9 -6
- package/dist/server/app-page-request.js +14 -10
- package/dist/server/app-page-response.d.ts +2 -2
- package/dist/server/app-page-response.js +2 -2
- package/dist/server/app-page-route-wiring.d.ts +3 -1
- package/dist/server/app-page-route-wiring.js +10 -8
- package/dist/server/app-page-stream.d.ts +37 -7
- package/dist/server/app-page-stream.js +36 -6
- package/dist/server/app-pages-bridge.d.ts +16 -0
- package/dist/server/app-pages-bridge.js +23 -3
- package/dist/server/app-route-handler-cache.d.ts +1 -0
- package/dist/server/app-route-handler-cache.js +1 -0
- package/dist/server/app-route-handler-dispatch.d.ts +1 -0
- package/dist/server/app-route-handler-dispatch.js +2 -0
- package/dist/server/app-route-handler-execution.d.ts +1 -0
- package/dist/server/app-route-handler-execution.js +1 -0
- package/dist/server/app-route-handler-response.js +11 -10
- package/dist/server/app-route-handler-runtime.d.ts +1 -0
- package/dist/server/app-route-handler-runtime.js +15 -3
- package/dist/server/app-rsc-handler.d.ts +1 -0
- package/dist/server/app-rsc-handler.js +5 -4
- package/dist/server/app-rsc-response-finalizer.js +1 -1
- package/dist/server/app-rsc-route-matching.d.ts +20 -1
- package/dist/server/app-rsc-route-matching.js +29 -4
- package/dist/server/app-server-action-execution.d.ts +22 -1
- package/dist/server/app-server-action-execution.js +73 -12
- package/dist/server/app-ssr-entry.d.ts +6 -0
- package/dist/server/app-ssr-entry.js +19 -3
- package/dist/server/app-ssr-stream.js +9 -1
- package/dist/server/dev-lockfile.js +2 -1
- package/dist/server/dev-server.d.ts +1 -1
- package/dist/server/dev-server.js +97 -43
- package/dist/server/headers.d.ts +8 -1
- package/dist/server/headers.js +8 -1
- package/dist/server/instrumentation-runtime.d.ts +6 -0
- package/dist/server/instrumentation-runtime.js +8 -0
- package/dist/server/isr-cache.d.ts +37 -1
- package/dist/server/isr-cache.js +85 -1
- 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 +62 -1
- package/dist/server/navigation-planner.js +193 -3
- package/dist/server/navigation-trace.d.ts +12 -2
- package/dist/server/navigation-trace.js +11 -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 +14 -3
- package/dist/server/pages-api-route.js +6 -1
- package/dist/server/pages-asset-tags.d.ts +15 -4
- package/dist/server/pages-asset-tags.js +18 -12
- package/dist/server/pages-data-route.js +5 -1
- package/dist/server/pages-node-compat.d.ts +5 -11
- package/dist/server/pages-node-compat.js +175 -118
- package/dist/server/pages-page-data.d.ts +38 -7
- package/dist/server/pages-page-data.js +64 -18
- package/dist/server/pages-page-handler.d.ts +10 -2
- package/dist/server/pages-page-handler.js +49 -20
- package/dist/server/pages-page-response.d.ts +55 -2
- package/dist/server/pages-page-response.js +74 -6
- package/dist/server/pages-readiness.d.ts +36 -0
- package/dist/server/pages-readiness.js +21 -0
- package/dist/server/pages-request-pipeline.d.ts +113 -0
- package/dist/server/pages-request-pipeline.js +230 -0
- package/dist/server/pages-revalidate.d.ts +15 -0
- package/dist/server/pages-revalidate.js +19 -0
- package/dist/server/prod-server.d.ts +45 -3
- package/dist/server/prod-server.js +182 -234
- package/dist/server/socket-error-backstop.d.ts +19 -1
- package/dist/server/socket-error-backstop.js +77 -4
- package/dist/shims/app-router-scroll.js +22 -4
- package/dist/shims/cache-runtime.js +39 -2
- package/dist/shims/dynamic-preload-chunks.d.ts +8 -0
- package/dist/shims/dynamic-preload-chunks.js +77 -0
- package/dist/shims/dynamic.d.ts +4 -0
- package/dist/shims/dynamic.js +4 -2
- package/dist/shims/error-boundary.d.ts +17 -7
- package/dist/shims/error-boundary.js +8 -1
- package/dist/shims/error.js +37 -11
- package/dist/shims/fetch-cache.d.ts +22 -1
- package/dist/shims/fetch-cache.js +28 -1
- package/dist/shims/hash-scroll.d.ts +1 -0
- package/dist/shims/hash-scroll.js +3 -1
- package/dist/shims/head.js +6 -1
- package/dist/shims/headers.d.ts +16 -2
- package/dist/shims/headers.js +37 -1
- package/dist/shims/image-config.js +7 -1
- package/dist/shims/internal/app-route-detection.d.ts +6 -3
- package/dist/shims/internal/app-route-detection.js +10 -6
- package/dist/shims/internal/app-router-context.d.ts +5 -0
- package/dist/shims/internal/link-status-registry.d.ts +43 -0
- package/dist/shims/internal/link-status-registry.js +42 -0
- package/dist/shims/internal/route-pattern-for-warning.d.ts +27 -0
- package/dist/shims/internal/route-pattern-for-warning.js +40 -0
- package/dist/shims/internal/utils.d.ts +1 -0
- package/dist/shims/link.js +20 -6
- package/dist/shims/metadata.d.ts +6 -2
- package/dist/shims/metadata.js +32 -14
- package/dist/shims/navigation.d.ts +9 -18
- package/dist/shims/navigation.js +96 -23
- package/dist/shims/router-state.d.ts +1 -0
- package/dist/shims/router-state.js +2 -0
- package/dist/shims/router.d.ts +6 -3
- package/dist/shims/router.js +156 -22
- 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 +17 -1
- package/dist/shims/server.js +31 -6
- package/dist/shims/slot.js +1 -1
- package/dist/shims/unified-request-context.js +1 -0
- package/dist/typegen.js +1 -0
- package/dist/utils/client-build-manifest.d.ts +8 -1
- package/dist/utils/client-build-manifest.js +41 -6
- package/dist/utils/client-entry-manifest.d.ts +11 -0
- package/dist/utils/client-entry-manifest.js +29 -0
- package/dist/utils/client-runtime-metadata.d.ts +45 -0
- package/dist/utils/client-runtime-metadata.js +63 -0
- package/dist/utils/hash.d.ts +17 -1
- package/dist/utils/hash.js +36 -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/path.d.ts +2 -1
- package/dist/utils/path.js +5 -1
- package/package.json +6 -2
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Plugin } from "vite";
|
|
2
|
+
import MagicString from "magic-string";
|
|
3
|
+
|
|
4
|
+
//#region src/plugins/dynamic-preload-metadata.d.ts
|
|
5
|
+
type TransformResult = {
|
|
6
|
+
code: string;
|
|
7
|
+
map: ReturnType<MagicString["generateMap"]>;
|
|
8
|
+
};
|
|
9
|
+
type ResolveDynamicImport = (specifier: string, importer: string) => Promise<string | null>;
|
|
10
|
+
declare function transformNextDynamicPreloadMetadata(code: string, id: string, root: string, resolveDynamicImport: ResolveDynamicImport): Promise<TransformResult | null>;
|
|
11
|
+
declare function createDynamicPreloadMetadataPlugin(): Plugin;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { createDynamicPreloadMetadataPlugin, transformNextDynamicPreloadMetadata };
|
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
import { isUnknownRecord } from "../utils/record.js";
|
|
2
|
+
import { relativeWithinRoot, tryRealpathSync } from "../build/ssr-manifest.js";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { parseAst } from "vite";
|
|
5
|
+
import MagicString from "magic-string";
|
|
6
|
+
//#region src/plugins/dynamic-preload-metadata.ts
|
|
7
|
+
function getString(node, key) {
|
|
8
|
+
const value = node[key];
|
|
9
|
+
return typeof value === "string" ? value : null;
|
|
10
|
+
}
|
|
11
|
+
function getNumber(node, key) {
|
|
12
|
+
const value = node[key];
|
|
13
|
+
return typeof value === "number" ? value : null;
|
|
14
|
+
}
|
|
15
|
+
function getArray(node, key) {
|
|
16
|
+
const value = node[key];
|
|
17
|
+
return Array.isArray(value) ? value : [];
|
|
18
|
+
}
|
|
19
|
+
function getBoolean(node, key) {
|
|
20
|
+
return node[key] === true;
|
|
21
|
+
}
|
|
22
|
+
function nodeName(node) {
|
|
23
|
+
if (!isUnknownRecord(node)) return null;
|
|
24
|
+
const name = node.name;
|
|
25
|
+
if (typeof name === "string") return name;
|
|
26
|
+
const value = node.value;
|
|
27
|
+
return typeof value === "string" ? value : null;
|
|
28
|
+
}
|
|
29
|
+
function nodeStringValue(node) {
|
|
30
|
+
if (!isUnknownRecord(node)) return null;
|
|
31
|
+
const value = node.value;
|
|
32
|
+
return typeof value === "string" ? value : null;
|
|
33
|
+
}
|
|
34
|
+
function walkAst(value, visitor) {
|
|
35
|
+
if (!isUnknownRecord(value)) return;
|
|
36
|
+
visitor(value);
|
|
37
|
+
for (const [key, child] of Object.entries(value)) {
|
|
38
|
+
if (key === "parent") continue;
|
|
39
|
+
if (Array.isArray(child)) for (const item of child) walkAst(item, visitor);
|
|
40
|
+
else if (isUnknownRecord(child)) walkAst(child, visitor);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function importSource(node) {
|
|
44
|
+
const source = node.source;
|
|
45
|
+
if (!isUnknownRecord(source)) return null;
|
|
46
|
+
return nodeStringValue(source);
|
|
47
|
+
}
|
|
48
|
+
function isNextDynamicSource(source) {
|
|
49
|
+
return source === "next/dynamic" || source === "next/dynamic.js";
|
|
50
|
+
}
|
|
51
|
+
function collectDynamicImportLocals(ast) {
|
|
52
|
+
const locals = /* @__PURE__ */ new Set();
|
|
53
|
+
if (!isUnknownRecord(ast)) return locals;
|
|
54
|
+
for (const node of getArray(ast, "body")) {
|
|
55
|
+
if (!isUnknownRecord(node)) continue;
|
|
56
|
+
if (getString(node, "type") !== "ImportDeclaration") continue;
|
|
57
|
+
if (!isNextDynamicSource(importSource(node))) continue;
|
|
58
|
+
for (const specifier of getArray(node, "specifiers")) {
|
|
59
|
+
if (!isUnknownRecord(specifier)) continue;
|
|
60
|
+
if (getString(specifier, "type") !== "ImportDefaultSpecifier") continue;
|
|
61
|
+
const local = nodeName(specifier.local);
|
|
62
|
+
if (local) locals.add(local);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return locals;
|
|
66
|
+
}
|
|
67
|
+
function isIdentifierNameInSet(node, names) {
|
|
68
|
+
if (!isUnknownRecord(node)) return false;
|
|
69
|
+
return getString(node, "type") === "Identifier" && names.has(getString(node, "name") ?? "");
|
|
70
|
+
}
|
|
71
|
+
function isDynamicCall(node, dynamicLocals) {
|
|
72
|
+
if (getString(node, "type") !== "CallExpression") return false;
|
|
73
|
+
return isIdentifierNameInSet(node.callee, dynamicLocals);
|
|
74
|
+
}
|
|
75
|
+
function addBindingName(pattern, names) {
|
|
76
|
+
if (!isUnknownRecord(pattern)) return;
|
|
77
|
+
const type = getString(pattern, "type");
|
|
78
|
+
if (type === null) return;
|
|
79
|
+
switch (type) {
|
|
80
|
+
case "Identifier": {
|
|
81
|
+
const name = getString(pattern, "name");
|
|
82
|
+
if (name) names.add(name);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
case "AssignmentPattern":
|
|
86
|
+
addBindingName(pattern.left, names);
|
|
87
|
+
return;
|
|
88
|
+
case "RestElement":
|
|
89
|
+
addBindingName(pattern.argument, names);
|
|
90
|
+
return;
|
|
91
|
+
case "ArrayPattern":
|
|
92
|
+
for (const element of getArray(pattern, "elements")) addBindingName(element, names);
|
|
93
|
+
return;
|
|
94
|
+
case "ObjectPattern":
|
|
95
|
+
for (const property of getArray(pattern, "properties")) {
|
|
96
|
+
if (!isUnknownRecord(property)) continue;
|
|
97
|
+
if (getString(property, "type") === "RestElement") {
|
|
98
|
+
addBindingName(property.argument, names);
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
addBindingName(property.value, names);
|
|
102
|
+
}
|
|
103
|
+
return;
|
|
104
|
+
default: return;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function addVariableDeclarationBindingNames(node, names) {
|
|
108
|
+
if (!isUnknownRecord(node) || getString(node, "type") !== "VariableDeclaration") return;
|
|
109
|
+
for (const declaration of getArray(node, "declarations")) if (isUnknownRecord(declaration)) addBindingName(declaration.id, names);
|
|
110
|
+
}
|
|
111
|
+
function collectBlockScopedBindingNames(body) {
|
|
112
|
+
const names = /* @__PURE__ */ new Set();
|
|
113
|
+
for (const statement of body) {
|
|
114
|
+
if (!isUnknownRecord(statement)) continue;
|
|
115
|
+
const type = getString(statement, "type");
|
|
116
|
+
if (type === "VariableDeclaration") {
|
|
117
|
+
if (getString(statement, "kind") !== "var") addVariableDeclarationBindingNames(statement, names);
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (type === "FunctionDeclaration" || type === "ClassDeclaration") {
|
|
121
|
+
const name = nodeName(statement.id);
|
|
122
|
+
if (name) names.add(name);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return names;
|
|
126
|
+
}
|
|
127
|
+
function collectSwitchScopedBindingNames(node) {
|
|
128
|
+
const names = /* @__PURE__ */ new Set();
|
|
129
|
+
for (const switchCase of getArray(node, "cases")) {
|
|
130
|
+
if (!isUnknownRecord(switchCase)) continue;
|
|
131
|
+
for (const statement of getArray(switchCase, "consequent")) for (const name of collectBlockScopedBindingNames([statement])) names.add(name);
|
|
132
|
+
}
|
|
133
|
+
return names;
|
|
134
|
+
}
|
|
135
|
+
function collectVarBindingNames(value, names) {
|
|
136
|
+
if (!isUnknownRecord(value)) return;
|
|
137
|
+
const type = getString(value, "type");
|
|
138
|
+
if (type === "FunctionDeclaration" || type === "FunctionExpression" || type === "ArrowFunctionExpression") return;
|
|
139
|
+
if (type === "VariableDeclaration" && getString(value, "kind") === "var") addVariableDeclarationBindingNames(value, names);
|
|
140
|
+
for (const [key, child] of Object.entries(value)) {
|
|
141
|
+
if (key === "parent") continue;
|
|
142
|
+
if (Array.isArray(child)) for (const item of child) collectVarBindingNames(item, names);
|
|
143
|
+
else if (isUnknownRecord(child)) collectVarBindingNames(child, names);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function collectFunctionScopeBindingNames(node) {
|
|
147
|
+
const names = /* @__PURE__ */ new Set();
|
|
148
|
+
if (getString(node, "type") === "FunctionExpression") {
|
|
149
|
+
const name = nodeName(node.id);
|
|
150
|
+
if (name) names.add(name);
|
|
151
|
+
}
|
|
152
|
+
for (const param of getArray(node, "params")) addBindingName(param, names);
|
|
153
|
+
collectVarBindingNames(node.body, names);
|
|
154
|
+
return names;
|
|
155
|
+
}
|
|
156
|
+
function collectForBindingNames(node) {
|
|
157
|
+
const names = /* @__PURE__ */ new Set();
|
|
158
|
+
addVariableDeclarationBindingNames(node.init, names);
|
|
159
|
+
addVariableDeclarationBindingNames(node.left, names);
|
|
160
|
+
return names;
|
|
161
|
+
}
|
|
162
|
+
function withoutBindings(activeNames, localNames) {
|
|
163
|
+
if (activeNames.size === 0 || localNames.size === 0) return activeNames;
|
|
164
|
+
let scoped = null;
|
|
165
|
+
for (const name of localNames) {
|
|
166
|
+
if (!activeNames.has(name)) continue;
|
|
167
|
+
scoped ??= new Set(activeNames);
|
|
168
|
+
scoped.delete(name);
|
|
169
|
+
}
|
|
170
|
+
return scoped ?? activeNames;
|
|
171
|
+
}
|
|
172
|
+
function visitChildren(node, dynamicLocals, visitor) {
|
|
173
|
+
for (const [key, child] of Object.entries(node)) {
|
|
174
|
+
if (key === "parent") continue;
|
|
175
|
+
if (Array.isArray(child)) for (const item of child) visitDynamicCalls(item, dynamicLocals, visitor);
|
|
176
|
+
else if (isUnknownRecord(child)) visitDynamicCalls(child, dynamicLocals, visitor);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
function visitDynamicCalls(value, dynamicLocals, visitor) {
|
|
180
|
+
if (!isUnknownRecord(value) || dynamicLocals.size === 0) return;
|
|
181
|
+
const type = getString(value, "type");
|
|
182
|
+
if (type === "Program") {
|
|
183
|
+
const scoped = withoutBindings(dynamicLocals, collectBlockScopedBindingNames(getArray(value, "body")));
|
|
184
|
+
for (const statement of getArray(value, "body")) visitDynamicCalls(statement, scoped, visitor);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
if (type === "BlockStatement") {
|
|
188
|
+
const scoped = withoutBindings(dynamicLocals, collectBlockScopedBindingNames(getArray(value, "body")));
|
|
189
|
+
for (const statement of getArray(value, "body")) visitDynamicCalls(statement, scoped, visitor);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
if (type === "SwitchStatement") {
|
|
193
|
+
visitDynamicCalls(value.discriminant, dynamicLocals, visitor);
|
|
194
|
+
const scoped = withoutBindings(dynamicLocals, collectSwitchScopedBindingNames(value));
|
|
195
|
+
for (const switchCase of getArray(value, "cases")) visitDynamicCalls(switchCase, scoped, visitor);
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
if (type === "FunctionDeclaration" || type === "FunctionExpression" || type === "ArrowFunctionExpression") {
|
|
199
|
+
visitChildren(value, withoutBindings(dynamicLocals, collectFunctionScopeBindingNames(value)), visitor);
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
if (type === "ClassDeclaration" || type === "ClassExpression") {
|
|
203
|
+
const names = /* @__PURE__ */ new Set();
|
|
204
|
+
const name = nodeName(value.id);
|
|
205
|
+
if (name) names.add(name);
|
|
206
|
+
visitChildren(value, withoutBindings(dynamicLocals, names), visitor);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
if (type === "ForStatement" || type === "ForInStatement" || type === "ForOfStatement") {
|
|
210
|
+
visitChildren(value, withoutBindings(dynamicLocals, collectForBindingNames(value)), visitor);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
if (type === "CatchClause") {
|
|
214
|
+
const names = /* @__PURE__ */ new Set();
|
|
215
|
+
addBindingName(value.param, names);
|
|
216
|
+
visitChildren(value, withoutBindings(dynamicLocals, names), visitor);
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
if (isDynamicCall(value, dynamicLocals)) visitor(value);
|
|
220
|
+
visitChildren(value, dynamicLocals, visitor);
|
|
221
|
+
}
|
|
222
|
+
function collectImportSpecifiers(node) {
|
|
223
|
+
const specifiers = [];
|
|
224
|
+
const seen = /* @__PURE__ */ new Set();
|
|
225
|
+
walkAst(node, (item) => {
|
|
226
|
+
if (getString(item, "type") === "ImportExpression") {
|
|
227
|
+
const specifier = nodeStringValue(item.source);
|
|
228
|
+
if (specifier && !seen.has(specifier)) {
|
|
229
|
+
seen.add(specifier);
|
|
230
|
+
specifiers.push(specifier);
|
|
231
|
+
}
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
if (getString(item, "type") !== "CallExpression") return;
|
|
235
|
+
const callee = item.callee;
|
|
236
|
+
if (!isUnknownRecord(callee) || getString(callee, "type") !== "Import") return;
|
|
237
|
+
const firstArg = getArray(item, "arguments")[0];
|
|
238
|
+
const specifier = nodeStringValue(firstArg);
|
|
239
|
+
if (specifier && !seen.has(specifier)) {
|
|
240
|
+
seen.add(specifier);
|
|
241
|
+
specifiers.push(specifier);
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
return specifiers;
|
|
245
|
+
}
|
|
246
|
+
function propertyKeyName(property) {
|
|
247
|
+
if (!isUnknownRecord(property)) return null;
|
|
248
|
+
if (getBoolean(property, "computed")) return null;
|
|
249
|
+
return nodeName(property.key);
|
|
250
|
+
}
|
|
251
|
+
function objectProperties(node) {
|
|
252
|
+
if (!isUnknownRecord(node) || getString(node, "type") !== "ObjectExpression") return [];
|
|
253
|
+
return getArray(node, "properties").filter(isUnknownRecord);
|
|
254
|
+
}
|
|
255
|
+
function hasObjectProperty(node, name) {
|
|
256
|
+
return objectProperties(node).some((property) => propertyKeyName(property) === name);
|
|
257
|
+
}
|
|
258
|
+
function findObjectProperty(node, name) {
|
|
259
|
+
return objectProperties(node).find((property) => propertyKeyName(property) === name) ?? null;
|
|
260
|
+
}
|
|
261
|
+
function dynamicLoaderNode(firstArg) {
|
|
262
|
+
if (!isUnknownRecord(firstArg) || getString(firstArg, "type") !== "ObjectExpression") return firstArg;
|
|
263
|
+
return (findObjectProperty(firstArg, "loader") ?? findObjectProperty(firstArg, "modules"))?.value;
|
|
264
|
+
}
|
|
265
|
+
function findLastEndedProperty(node) {
|
|
266
|
+
const properties = objectProperties(node);
|
|
267
|
+
for (let index = properties.length - 1; index >= 0; index -= 1) if (getNumber(properties[index], "end") !== null) return properties[index];
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
270
|
+
function appendObjectProperty(output, objectNode, property) {
|
|
271
|
+
const start = getNumber(objectNode, "start");
|
|
272
|
+
const end = getNumber(objectNode, "end");
|
|
273
|
+
if (start === null || end === null) return false;
|
|
274
|
+
const lastProperty = findLastEndedProperty(objectNode);
|
|
275
|
+
if (!lastProperty) {
|
|
276
|
+
output.appendLeft(start + 1, property);
|
|
277
|
+
return true;
|
|
278
|
+
}
|
|
279
|
+
const propertyEnd = getNumber(lastProperty, "end");
|
|
280
|
+
if (propertyEnd === null) return false;
|
|
281
|
+
output.appendLeft(propertyEnd, `, ${property}`);
|
|
282
|
+
return true;
|
|
283
|
+
}
|
|
284
|
+
function stripComments(source) {
|
|
285
|
+
return source.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/[^\n]*/g, "");
|
|
286
|
+
}
|
|
287
|
+
function insertSecondOptionsArgument(output, code, callNode, firstArg, optionsLiteral) {
|
|
288
|
+
const callEnd = getNumber(callNode, "end");
|
|
289
|
+
const firstArgEnd = getNumber(firstArg, "end");
|
|
290
|
+
if (callEnd === null || firstArgEnd === null) return false;
|
|
291
|
+
const closeParen = callEnd - 1;
|
|
292
|
+
const separator = stripComments(code.slice(firstArgEnd, closeParen)).trimEnd().endsWith(",") ? " " : ", ";
|
|
293
|
+
output.appendLeft(closeParen, `${separator}${optionsLiteral}`);
|
|
294
|
+
return true;
|
|
295
|
+
}
|
|
296
|
+
function cleanResolvedId(id) {
|
|
297
|
+
let start = 0;
|
|
298
|
+
while (start < id.length && id.charCodeAt(start) === 0) start += 1;
|
|
299
|
+
return id.slice(start).replace(/^\/@fs\//, "/").split("?")[0].replace(/\\/g, "/");
|
|
300
|
+
}
|
|
301
|
+
const rootRealpathCache = /* @__PURE__ */ new Map();
|
|
302
|
+
function cachedRootRealpath(root) {
|
|
303
|
+
if (!rootRealpathCache.has(root)) rootRealpathCache.set(root, tryRealpathSync(root));
|
|
304
|
+
return rootRealpathCache.get(root) ?? null;
|
|
305
|
+
}
|
|
306
|
+
/** `code` offset -> human `:line:column` (1-based), for build error messages. */
|
|
307
|
+
function formatNodeLocation(code, node) {
|
|
308
|
+
const start = getNumber(node, "start");
|
|
309
|
+
if (start === null) return "";
|
|
310
|
+
const before = code.slice(0, start);
|
|
311
|
+
return `:${before.split("\n").length}:${start - before.lastIndexOf("\n")}`;
|
|
312
|
+
}
|
|
313
|
+
function toManifestModuleId(root, resolvedId) {
|
|
314
|
+
const cleaned = cleanResolvedId(resolvedId);
|
|
315
|
+
if (!path.isAbsolute(cleaned)) return cleaned.replace(/^\/+/, "");
|
|
316
|
+
const rootCandidates = new Set([root]);
|
|
317
|
+
const realRoot = cachedRootRealpath(root);
|
|
318
|
+
if (realRoot) rootCandidates.add(realRoot);
|
|
319
|
+
const moduleCandidates = new Set([cleaned]);
|
|
320
|
+
const realCleaned = tryRealpathSync(cleaned);
|
|
321
|
+
if (realCleaned) moduleCandidates.add(realCleaned.replace(/\\/g, "/"));
|
|
322
|
+
for (const rootCandidate of rootCandidates) for (const moduleCandidate of moduleCandidates) {
|
|
323
|
+
const relative = relativeWithinRoot(rootCandidate, moduleCandidate);
|
|
324
|
+
if (relative) return relative;
|
|
325
|
+
}
|
|
326
|
+
return null;
|
|
327
|
+
}
|
|
328
|
+
async function resolveManifestModuleIds(specifiers, importer, root, resolveDynamicImport) {
|
|
329
|
+
const resolvedIds = [];
|
|
330
|
+
const seen = /* @__PURE__ */ new Set();
|
|
331
|
+
for (const specifier of specifiers) {
|
|
332
|
+
const resolved = await resolveDynamicImport(specifier, importer);
|
|
333
|
+
const moduleId = resolved ? toManifestModuleId(root, resolved) : null;
|
|
334
|
+
if (!moduleId || seen.has(moduleId)) continue;
|
|
335
|
+
seen.add(moduleId);
|
|
336
|
+
resolvedIds.push(moduleId);
|
|
337
|
+
}
|
|
338
|
+
return resolvedIds;
|
|
339
|
+
}
|
|
340
|
+
function shouldSkipCall(firstArg, secondArg) {
|
|
341
|
+
if (hasObjectProperty(firstArg, "loadableGenerated")) return true;
|
|
342
|
+
return hasObjectProperty(secondArg, "loadableGenerated");
|
|
343
|
+
}
|
|
344
|
+
function applyLoadableGenerated(output, code, callNode, moduleIds) {
|
|
345
|
+
const args = getArray(callNode, "arguments");
|
|
346
|
+
const firstArg = args[0];
|
|
347
|
+
const secondArg = args[1];
|
|
348
|
+
if (!isUnknownRecord(firstArg)) return false;
|
|
349
|
+
if (shouldSkipCall(firstArg, secondArg)) return false;
|
|
350
|
+
const property = `loadableGenerated: { modules: ${JSON.stringify(moduleIds)} }`;
|
|
351
|
+
if (getString(firstArg, "type") === "ObjectExpression") return appendObjectProperty(output, firstArg, property);
|
|
352
|
+
if (secondArg === void 0) return insertSecondOptionsArgument(output, code, callNode, firstArg, `{ ${property} }`);
|
|
353
|
+
if (isUnknownRecord(secondArg) && getString(secondArg, "type") === "ObjectExpression") return appendObjectProperty(output, secondArg, property);
|
|
354
|
+
return false;
|
|
355
|
+
}
|
|
356
|
+
async function transformNextDynamicPreloadMetadata(code, id, root, resolveDynamicImport) {
|
|
357
|
+
if (!code.includes("next/dynamic")) return null;
|
|
358
|
+
let ast;
|
|
359
|
+
try {
|
|
360
|
+
ast = parseAst(code);
|
|
361
|
+
} catch (error) {
|
|
362
|
+
if (typeof process !== "undefined" && process.env?.DEBUG?.includes("vinext")) console.debug(`[vinext] dynamic-preload-metadata: failed to parse ${id}:`, error);
|
|
363
|
+
return null;
|
|
364
|
+
}
|
|
365
|
+
const dynamicLocals = collectDynamicImportLocals(ast);
|
|
366
|
+
if (dynamicLocals.size === 0) return null;
|
|
367
|
+
const output = new MagicString(code);
|
|
368
|
+
let changed = false;
|
|
369
|
+
const pending = [];
|
|
370
|
+
visitDynamicCalls(ast, dynamicLocals, (node) => {
|
|
371
|
+
const args = getArray(node, "arguments");
|
|
372
|
+
if (args.length > 2) throw new Error(`next/dynamic only accepts 2 arguments (${id}${formatNodeLocation(code, node)})`);
|
|
373
|
+
const specifiers = collectImportSpecifiers(dynamicLoaderNode(args[0]));
|
|
374
|
+
if (specifiers.length === 0) return;
|
|
375
|
+
pending.push(resolveManifestModuleIds(specifiers, id, root, resolveDynamicImport).then((moduleIds) => {
|
|
376
|
+
if (moduleIds.length === 0) return;
|
|
377
|
+
if (applyLoadableGenerated(output, code, node, moduleIds)) changed = true;
|
|
378
|
+
}));
|
|
379
|
+
});
|
|
380
|
+
await Promise.all(pending);
|
|
381
|
+
if (!changed) return null;
|
|
382
|
+
return {
|
|
383
|
+
code: output.toString(),
|
|
384
|
+
map: output.generateMap({ hires: "boundary" })
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
function createDynamicPreloadMetadataPlugin() {
|
|
388
|
+
let root = process.cwd();
|
|
389
|
+
return {
|
|
390
|
+
name: "vinext:dynamic-preload-metadata",
|
|
391
|
+
configResolved(config) {
|
|
392
|
+
root = config.root;
|
|
393
|
+
},
|
|
394
|
+
transform: {
|
|
395
|
+
filter: {
|
|
396
|
+
id: {
|
|
397
|
+
include: /\.(tsx?|jsx?|mjs)$/,
|
|
398
|
+
exclude: /node_modules/
|
|
399
|
+
},
|
|
400
|
+
code: "next/dynamic"
|
|
401
|
+
},
|
|
402
|
+
async handler(code, id) {
|
|
403
|
+
if (id.includes("node_modules") || id.startsWith("\0")) return null;
|
|
404
|
+
if (!/\.(tsx?|jsx?|mjs)$/.test(id)) return null;
|
|
405
|
+
const result = await transformNextDynamicPreloadMetadata(code, id, root, async (specifier, importer) => {
|
|
406
|
+
return (await this.resolve(specifier, importer, { skipSelf: true }))?.id ?? null;
|
|
407
|
+
});
|
|
408
|
+
if (!result) return null;
|
|
409
|
+
return result;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
//#endregion
|
|
415
|
+
export { createDynamicPreloadMetadataPlugin, transformNextDynamicPreloadMetadata };
|
|
@@ -42,7 +42,7 @@ function createOgInlineFetchAssetsPlugin() {
|
|
|
42
42
|
return null;
|
|
43
43
|
}
|
|
44
44
|
};
|
|
45
|
-
if (code.includes("fetch(")) for (const match of code.matchAll(/fetch\(\s*new URL\(\s*(["'])(
|
|
45
|
+
if (code.includes("fetch(")) for (const match of code.matchAll(/fetch\(\s*new URL\(\s*(["'])(\.[^"']+)\1\s*,\s*import\.meta\.url\s*\)\s*\)(?:\.then\(\s*(?:function\s*\([^)]*\)|\([^)]*\)\s*=>)\s*\{?\s*return\s+[^.]+\.arrayBuffer\(\)\s*;?\s*\}?\s*,?\s*\)|\.then\(\s*\([^)]*\)\s*=>\s*[^.]+\.arrayBuffer\(\)\s*,?\s*\))/g)) {
|
|
46
46
|
const fullMatch = match[0];
|
|
47
47
|
const relPath = match[2];
|
|
48
48
|
const fileBase64 = await readAsBase64(path.resolve(moduleDir, relPath));
|
|
@@ -59,7 +59,7 @@ function createOgInlineFetchAssetsPlugin() {
|
|
|
59
59
|
newCode = newCode.replaceAll(fullMatch, inlined);
|
|
60
60
|
didReplace = true;
|
|
61
61
|
}
|
|
62
|
-
if (code.includes("readFileSync(")) for (const match of newCode.matchAll(/[a-zA-Z_$][a-zA-Z0-9_$]*\.readFileSync\(\s*(?:[a-zA-Z_$][a-zA-Z0-9_$]*\.)?fileURLToPath\(\s*new URL\(\s*(["'])(
|
|
62
|
+
if (code.includes("readFileSync(")) for (const match of newCode.matchAll(/[a-zA-Z_$][a-zA-Z0-9_$]*\.readFileSync\(\s*(?:[a-zA-Z_$][a-zA-Z0-9_$]*\.)?fileURLToPath\(\s*new URL\(\s*(["'])(\.[^"']+)\1\s*,\s*import\.meta\.url\s*\)\s*\)\s*\)/g)) {
|
|
63
63
|
const fullMatch = match[0];
|
|
64
64
|
const relPath = match[2];
|
|
65
65
|
const fileBase64 = await readAsBase64(path.resolve(moduleDir, relPath));
|
|
@@ -21,11 +21,15 @@ declare const DEFAULT_OPTIMIZE_PACKAGES: string[];
|
|
|
21
21
|
* Handles: `export * as X from`, `export { A } from`, `import * as X; export { X }`,
|
|
22
22
|
* and `export * from "./sub"` (recursively resolves wildcard re-exports).
|
|
23
23
|
*
|
|
24
|
-
* Returns null if
|
|
25
|
-
*
|
|
26
|
-
*
|
|
24
|
+
* Returns null if `entryPath` is empty, the file cannot be read, or the file
|
|
25
|
+
* has a parse error. Returns an empty map if the file is valid but exports
|
|
26
|
+
* nothing.
|
|
27
|
+
*
|
|
28
|
+
* @param entryPath - Pre-resolved absolute path to the barrel entry file (the
|
|
29
|
+
* caller owns entry resolution + its caching), or null when it could not be
|
|
30
|
+
* resolved.
|
|
27
31
|
*/
|
|
28
|
-
declare function buildBarrelExportMap(
|
|
32
|
+
declare function buildBarrelExportMap(entryPath: string | null, readFile: (filepath: string) => Promise<string | null>, cache?: Map<string, BarrelExportMap>): Promise<BarrelExportMap | null>;
|
|
29
33
|
/**
|
|
30
34
|
* Creates the vinext:optimize-imports Vite plugin.
|
|
31
35
|
*
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { normalizePathSeparators } from "../utils/path.js";
|
|
1
2
|
import { getAstName } from "./ast-utils.js";
|
|
2
3
|
import { createRequire } from "node:module";
|
|
3
4
|
import path from "node:path";
|
|
@@ -185,12 +186,12 @@ async function resolvePackageEntry(packageName, projectRoot, preferReactServer)
|
|
|
185
186
|
const dotExport = pkgJson.exports["."];
|
|
186
187
|
if (dotExport) {
|
|
187
188
|
const entryPath = resolveExportsValue(dotExport, preferReactServer);
|
|
188
|
-
if (entryPath) return path.resolve(pkgDir, entryPath)
|
|
189
|
+
if (entryPath) return normalizePathSeparators(path.resolve(pkgDir, entryPath));
|
|
189
190
|
}
|
|
190
191
|
}
|
|
191
192
|
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)
|
|
193
|
+
if (typeof entryField === "string") return normalizePathSeparators(path.resolve(pkgDir, entryField));
|
|
194
|
+
return normalizePathSeparators(createRequire(path.join(projectRoot, "package.json")).resolve(packageName));
|
|
194
195
|
} catch {
|
|
195
196
|
return null;
|
|
196
197
|
}
|
|
@@ -228,14 +229,14 @@ async function buildExportMapFromFile(filePath, readFile, cache, visited, initia
|
|
|
228
229
|
const exportMap = /* @__PURE__ */ new Map();
|
|
229
230
|
const importBindings = /* @__PURE__ */ new Map();
|
|
230
231
|
const localDeclarations = /* @__PURE__ */ new Set();
|
|
231
|
-
const fileDir = path.dirname(filePath);
|
|
232
|
+
const fileDir = path.posix.dirname(filePath);
|
|
232
233
|
/**
|
|
233
234
|
* Normalize a source specifier: resolve relative paths to absolute so that
|
|
234
235
|
* entries in the export map always store absolute paths for file references.
|
|
235
236
|
* Bare package specifiers (e.g. "@radix-ui/react-slot") are returned unchanged.
|
|
236
237
|
*/
|
|
237
238
|
function normalizeSource(source) {
|
|
238
|
-
return source.startsWith(".") ? path.
|
|
239
|
+
return source.startsWith(".") ? path.posix.join(fileDir, source) : source;
|
|
239
240
|
}
|
|
240
241
|
function recordLocalDeclaration(node) {
|
|
241
242
|
if (!node) return;
|
|
@@ -297,7 +298,7 @@ async function buildExportMapFromFile(filePath, readFile, cache, visited, initia
|
|
|
297
298
|
isNamespace: true
|
|
298
299
|
});
|
|
299
300
|
} else if (rawSource.startsWith(".")) {
|
|
300
|
-
const subPath = path.
|
|
301
|
+
const subPath = path.posix.join(fileDir, rawSource);
|
|
301
302
|
const candidates = [
|
|
302
303
|
subPath,
|
|
303
304
|
`${subPath}.js`,
|
|
@@ -386,12 +387,15 @@ async function buildExportMapFromFile(filePath, readFile, cache, visited, initia
|
|
|
386
387
|
* Handles: `export * as X from`, `export { A } from`, `import * as X; export { X }`,
|
|
387
388
|
* and `export * from "./sub"` (recursively resolves wildcard re-exports).
|
|
388
389
|
*
|
|
389
|
-
* Returns null if
|
|
390
|
-
*
|
|
391
|
-
*
|
|
390
|
+
* Returns null if `entryPath` is empty, the file cannot be read, or the file
|
|
391
|
+
* has a parse error. Returns an empty map if the file is valid but exports
|
|
392
|
+
* nothing.
|
|
393
|
+
*
|
|
394
|
+
* @param entryPath - Pre-resolved absolute path to the barrel entry file (the
|
|
395
|
+
* caller owns entry resolution + its caching), or null when it could not be
|
|
396
|
+
* resolved.
|
|
392
397
|
*/
|
|
393
|
-
async function buildBarrelExportMap(
|
|
394
|
-
const entryPath = resolveEntry(packageName);
|
|
398
|
+
async function buildBarrelExportMap(entryPath, readFile, cache) {
|
|
395
399
|
if (!entryPath) return null;
|
|
396
400
|
const exportMapCache = cache ?? /* @__PURE__ */ new Map();
|
|
397
401
|
const cached = exportMapCache.get(entryPath);
|
|
@@ -466,7 +470,7 @@ function createOptimizeImportsPlugin(getNextConfig, getRoot) {
|
|
|
466
470
|
barrelEntry = await resolvePackageEntry(importSource, root, preferReactServer);
|
|
467
471
|
entryPathCache.set(cacheKey, barrelEntry ?? null);
|
|
468
472
|
}
|
|
469
|
-
const exportMap = await buildBarrelExportMap(
|
|
473
|
+
const exportMap = await buildBarrelExportMap(barrelEntry, readFileSafe, barrelCaches.exportMapCache);
|
|
470
474
|
if (!exportMap || !barrelEntry) continue;
|
|
471
475
|
const envKey = preferReactServer ? "rsc" : "ssr";
|
|
472
476
|
const registeredKey = `${envKey}:${barrelEntry}`;
|
package/dist/plugins/postcss.js
CHANGED
|
@@ -73,20 +73,24 @@ async function resolvePostcssStringPluginsUncached(projectRoot) {
|
|
|
73
73
|
if (!config || !Array.isArray(config.plugins)) return;
|
|
74
74
|
if (!config.plugins.some((p) => typeof p === "string" || Array.isArray(p) && typeof p[0] === "string")) return;
|
|
75
75
|
const req = createRequire(path.join(projectRoot, "package.json"));
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
76
|
+
try {
|
|
77
|
+
return { plugins: await Promise.all(config.plugins.filter(Boolean).map(async (plugin) => {
|
|
78
|
+
if (typeof plugin === "string") {
|
|
79
|
+
const mod = await import(pathToFileURL(req.resolve(plugin)).href);
|
|
80
|
+
const fn = mod.default ?? mod;
|
|
81
|
+
return typeof fn === "function" ? fn() : fn;
|
|
82
|
+
}
|
|
83
|
+
if (Array.isArray(plugin) && typeof plugin[0] === "string") {
|
|
84
|
+
const [name, options] = plugin;
|
|
85
|
+
const mod = await import(pathToFileURL(req.resolve(name)).href);
|
|
86
|
+
const fn = mod.default ?? mod;
|
|
87
|
+
return typeof fn === "function" ? fn(options) : fn;
|
|
88
|
+
}
|
|
89
|
+
return plugin;
|
|
90
|
+
})) };
|
|
91
|
+
} catch {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
90
94
|
}
|
|
91
95
|
//#endregion
|
|
92
96
|
export { postcssCache, resolvePostcssStringPlugins };
|