@finesoft/front 0.1.31 → 0.1.33
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/dist/app-OOLQDVXA.js +10 -0
- package/dist/browser.cjs +13 -9
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +2 -2
- package/dist/{chunk-ZMOE42LB.js → chunk-AYO3UUQC.js} +39 -37
- package/dist/chunk-AYO3UUQC.js.map +1 -0
- package/dist/{chunk-H3RNYNSD.js → chunk-OE5BU5MR.js} +2 -2
- package/dist/{chunk-BUYWNNNQ.js → chunk-OXKFPW4U.js} +14 -10
- package/dist/chunk-OXKFPW4U.js.map +1 -0
- package/dist/{chunk-FYP2ZYYV.js → chunk-PSPVIVC2.js} +2 -2
- package/dist/chunk-PSPVIVC2.js.map +1 -0
- package/dist/{chunk-M7VITIMR.js → chunk-UHQBKSHL.js} +3 -3
- package/dist/index.cjs +265 -49
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +75 -6
- package/dist/index.d.ts +75 -6
- package/dist/index.js +220 -12
- package/dist/index.js.map +1 -1
- package/dist/locale-CAZ4INCX.js +7 -0
- package/dist/{src-B5YAJXIM.js → src-MVACJWBF.js} +3 -3
- package/package.json +1 -1
- package/dist/app-IA6JQC7V.js +0 -10
- package/dist/chunk-BUYWNNNQ.js.map +0 -1
- package/dist/chunk-FYP2ZYYV.js.map +0 -1
- package/dist/chunk-ZMOE42LB.js.map +0 -1
- package/dist/locale-YK3THSI6.js +0 -7
- /package/dist/{app-IA6JQC7V.js.map → app-OOLQDVXA.js.map} +0 -0
- /package/dist/{chunk-H3RNYNSD.js.map → chunk-OE5BU5MR.js.map} +0 -0
- /package/dist/{chunk-M7VITIMR.js.map → chunk-UHQBKSHL.js.map} +0 -0
- /package/dist/{locale-YK3THSI6.js.map → locale-CAZ4INCX.js.map} +0 -0
- /package/dist/{src-B5YAJXIM.js.map → src-MVACJWBF.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -397,13 +397,14 @@ var init_router = __esm({
|
|
|
397
397
|
/** 添加路由规则 */
|
|
398
398
|
add(pattern, intentId, renderMode) {
|
|
399
399
|
const paramNames = [];
|
|
400
|
-
const regexStr = pattern.
|
|
401
|
-
|
|
402
|
-
(
|
|
403
|
-
paramNames.push(
|
|
404
|
-
return
|
|
400
|
+
const regexStr = pattern.split(/(\/:[\w]+\??)/).map((segment) => {
|
|
401
|
+
const paramMatch = segment.match(/^\/:(\w+)(\?)?$/);
|
|
402
|
+
if (paramMatch) {
|
|
403
|
+
paramNames.push(paramMatch[1]);
|
|
404
|
+
return paramMatch[2] ? "(?:/([^/]+))?" : "/([^/]+)";
|
|
405
405
|
}
|
|
406
|
-
|
|
406
|
+
return segment.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
|
|
407
|
+
}).join("");
|
|
407
408
|
this.routes.push({
|
|
408
409
|
pattern,
|
|
409
410
|
intentId,
|
|
@@ -507,15 +508,18 @@ var init_composite = __esm({
|
|
|
507
508
|
});
|
|
508
509
|
|
|
509
510
|
// ../core/src/prefetched-intents/stable-stringify.ts
|
|
510
|
-
function stableStringify(obj) {
|
|
511
|
+
function stableStringify(obj, _seen) {
|
|
511
512
|
if (obj === null || obj === void 0) return String(obj);
|
|
512
513
|
if (typeof obj !== "object") return JSON.stringify(obj);
|
|
514
|
+
const seen = _seen ?? /* @__PURE__ */ new Set();
|
|
515
|
+
if (seen.has(obj)) return '"[Circular]"';
|
|
516
|
+
seen.add(obj);
|
|
513
517
|
if (Array.isArray(obj)) {
|
|
514
|
-
return "[" + obj.map(stableStringify).join(",") + "]";
|
|
518
|
+
return "[" + obj.map((v) => stableStringify(v, seen)).join(",") + "]";
|
|
515
519
|
}
|
|
516
520
|
const keys = Object.keys(obj).sort();
|
|
517
521
|
const parts = keys.filter((k) => obj[k] !== void 0).map(
|
|
518
|
-
(k) => JSON.stringify(k) + ":" + stableStringify(obj[k])
|
|
522
|
+
(k) => JSON.stringify(k) + ":" + stableStringify(obj[k], seen)
|
|
519
523
|
);
|
|
520
524
|
return "{" + parts.join(",") + "}";
|
|
521
525
|
}
|
|
@@ -980,44 +984,46 @@ async function ssrRender(options) {
|
|
|
980
984
|
const mergedConfig = ssrContext?.fetch ? { ...frameworkConfig, fetch: ssrContext.fetch } : frameworkConfig;
|
|
981
985
|
const framework = Framework.create(mergedConfig);
|
|
982
986
|
bootstrap(framework);
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
987
|
+
try {
|
|
988
|
+
const parsed = new URL(url, "http://localhost");
|
|
989
|
+
const fullPath = parsed.pathname + parsed.search;
|
|
990
|
+
const match = framework.routeUrl(fullPath);
|
|
991
|
+
if (match?.renderMode === "csr") {
|
|
992
|
+
return {
|
|
993
|
+
html: "",
|
|
994
|
+
head: "",
|
|
995
|
+
css: "",
|
|
996
|
+
serverData: [],
|
|
997
|
+
renderMode: "csr"
|
|
998
|
+
};
|
|
999
|
+
}
|
|
1000
|
+
let page;
|
|
1001
|
+
let serverData = [];
|
|
1002
|
+
if (match) {
|
|
1003
|
+
try {
|
|
1004
|
+
page = await framework.dispatch(match.intent);
|
|
1005
|
+
serverData = [{ intent: match.intent, data: page }];
|
|
1006
|
+
} catch (e) {
|
|
1007
|
+
console.error(
|
|
1008
|
+
`[SSR] dispatch failed for intent "${match.intent.id}":`,
|
|
1009
|
+
e
|
|
1010
|
+
);
|
|
1011
|
+
page = getErrorPage(500, "Internal error");
|
|
1012
|
+
}
|
|
1013
|
+
} else {
|
|
1014
|
+
page = getErrorPage(404, "Page not found");
|
|
1015
|
+
}
|
|
1016
|
+
const result = renderApp(page, framework);
|
|
988
1017
|
return {
|
|
989
|
-
html:
|
|
990
|
-
head:
|
|
991
|
-
css:
|
|
992
|
-
serverData
|
|
993
|
-
renderMode:
|
|
1018
|
+
html: result.html,
|
|
1019
|
+
head: result.head,
|
|
1020
|
+
css: result.css,
|
|
1021
|
+
serverData,
|
|
1022
|
+
renderMode: match?.renderMode
|
|
994
1023
|
};
|
|
1024
|
+
} finally {
|
|
1025
|
+
framework.dispose();
|
|
995
1026
|
}
|
|
996
|
-
let page;
|
|
997
|
-
let serverData = [];
|
|
998
|
-
if (match) {
|
|
999
|
-
try {
|
|
1000
|
-
page = await framework.dispatch(match.intent);
|
|
1001
|
-
serverData = [{ intent: match.intent, data: page }];
|
|
1002
|
-
} catch (e) {
|
|
1003
|
-
console.error(
|
|
1004
|
-
`[SSR] dispatch failed for intent "${match.intent.id}":`,
|
|
1005
|
-
e
|
|
1006
|
-
);
|
|
1007
|
-
page = getErrorPage(500, "Internal error");
|
|
1008
|
-
}
|
|
1009
|
-
} else {
|
|
1010
|
-
page = getErrorPage(404, "Page not found");
|
|
1011
|
-
}
|
|
1012
|
-
const result = renderApp(page, framework);
|
|
1013
|
-
framework.dispose();
|
|
1014
|
-
return {
|
|
1015
|
-
html: result.html,
|
|
1016
|
-
head: result.head,
|
|
1017
|
-
css: result.css,
|
|
1018
|
-
serverData,
|
|
1019
|
-
renderMode: match?.renderMode
|
|
1020
|
-
};
|
|
1021
1027
|
}
|
|
1022
1028
|
var init_render = __esm({
|
|
1023
1029
|
"../ssr/src/render.ts"() {
|
|
@@ -1149,7 +1155,7 @@ function parseAcceptLanguage(header, supported, fallback) {
|
|
|
1149
1155
|
const [lang, q] = part.trim().split(";q=");
|
|
1150
1156
|
return {
|
|
1151
1157
|
lang: lang.trim().toLowerCase(),
|
|
1152
|
-
q: q ? parseFloat(q) : 1
|
|
1158
|
+
q: q ? parseFloat(q) || 0 : 1
|
|
1153
1159
|
};
|
|
1154
1160
|
}).sort((a, b) => b.q - a.q);
|
|
1155
1161
|
for (const { lang } of langs) {
|
|
@@ -1352,6 +1358,7 @@ __export(index_exports, {
|
|
|
1352
1358
|
deserializeServerData: () => deserializeServerData,
|
|
1353
1359
|
detectRuntime: () => detectRuntime,
|
|
1354
1360
|
finesoftFrontViteConfig: () => finesoftFrontViteConfig,
|
|
1361
|
+
generateProxyCode: () => generateProxyCode,
|
|
1355
1362
|
generateUuid: () => generateUuid,
|
|
1356
1363
|
getBaseUrl: () => getBaseUrl,
|
|
1357
1364
|
injectCSRShell: () => injectCSRShell,
|
|
@@ -1373,6 +1380,7 @@ __export(index_exports, {
|
|
|
1373
1380
|
registerActionHandlers: () => registerActionHandlers,
|
|
1374
1381
|
registerExternalUrlHandler: () => registerExternalUrlHandler,
|
|
1375
1382
|
registerFlowActionHandler: () => registerFlowActionHandler,
|
|
1383
|
+
registerProxyRoutes: () => registerProxyRoutes,
|
|
1376
1384
|
removeHost: () => removeHost,
|
|
1377
1385
|
removeQueryParams: () => removeQueryParams,
|
|
1378
1386
|
removeScheme: () => removeScheme,
|
|
@@ -1726,6 +1734,120 @@ init_src();
|
|
|
1726
1734
|
// src/index.ts
|
|
1727
1735
|
init_src2();
|
|
1728
1736
|
|
|
1737
|
+
// ../server/src/proxy.ts
|
|
1738
|
+
function sanitizeProxyPath(raw) {
|
|
1739
|
+
if (raw.startsWith("//")) return null;
|
|
1740
|
+
return raw.startsWith("/") ? raw : `/${raw}`;
|
|
1741
|
+
}
|
|
1742
|
+
function validateConfig(config) {
|
|
1743
|
+
if (!config.prefix.startsWith("/")) {
|
|
1744
|
+
throw new Error(
|
|
1745
|
+
`[proxy] prefix must start with "/": "${config.prefix}"`
|
|
1746
|
+
);
|
|
1747
|
+
}
|
|
1748
|
+
if (!config.target.startsWith("https://")) {
|
|
1749
|
+
throw new Error(`[proxy] target must use HTTPS: "${config.target}"`);
|
|
1750
|
+
}
|
|
1751
|
+
}
|
|
1752
|
+
function registerProxyRoutes(app, configs) {
|
|
1753
|
+
for (const config of configs) {
|
|
1754
|
+
validateConfig(config);
|
|
1755
|
+
const methods = config.methods ?? ["all"];
|
|
1756
|
+
const pattern = `${config.prefix}/*`;
|
|
1757
|
+
const handler = async (c) => {
|
|
1758
|
+
const subPath = sanitizeProxyPath(
|
|
1759
|
+
c.req.path.replace(config.prefix, "")
|
|
1760
|
+
);
|
|
1761
|
+
if (!subPath) return c.text("Invalid path", 400);
|
|
1762
|
+
const targetUrl = new URL(subPath, config.target);
|
|
1763
|
+
const reqUrl = new URL(c.req.url);
|
|
1764
|
+
reqUrl.searchParams.forEach(
|
|
1765
|
+
(v, k) => targetUrl.searchParams.set(k, v)
|
|
1766
|
+
);
|
|
1767
|
+
const headers = { ...config.headers };
|
|
1768
|
+
if (config.auth) {
|
|
1769
|
+
const token = process.env[config.auth.envKey] ?? "";
|
|
1770
|
+
if (token) {
|
|
1771
|
+
headers.Authorization = config.auth.type === "bearer" ? `Bearer ${token}` : `Basic ${token}`;
|
|
1772
|
+
}
|
|
1773
|
+
}
|
|
1774
|
+
try {
|
|
1775
|
+
const resp = await fetch(targetUrl.toString(), {
|
|
1776
|
+
headers,
|
|
1777
|
+
redirect: config.followRedirects ? "follow" : "manual"
|
|
1778
|
+
});
|
|
1779
|
+
const body = await resp.text();
|
|
1780
|
+
const respHeaders = {
|
|
1781
|
+
"Content-Type": resp.headers.get("Content-Type") ?? "application/json"
|
|
1782
|
+
};
|
|
1783
|
+
if (config.cache) {
|
|
1784
|
+
respHeaders["Cache-Control"] = config.cache;
|
|
1785
|
+
}
|
|
1786
|
+
return c.newResponse(body, resp.status, respHeaders);
|
|
1787
|
+
} catch (e) {
|
|
1788
|
+
console.error(`[Proxy ${config.prefix}]`, e);
|
|
1789
|
+
return c.json({ error: "Proxy request failed" }, 502);
|
|
1790
|
+
}
|
|
1791
|
+
};
|
|
1792
|
+
for (const method of methods) {
|
|
1793
|
+
app[method](pattern, handler);
|
|
1794
|
+
}
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
function generateProxyCode(configs) {
|
|
1798
|
+
if (!configs || configs.length === 0) return "";
|
|
1799
|
+
for (const config of configs) {
|
|
1800
|
+
validateConfig(config);
|
|
1801
|
+
}
|
|
1802
|
+
const blocks = [];
|
|
1803
|
+
blocks.push(`
|
|
1804
|
+
// \u2500\u2500\u2500 \u6846\u67B6\u58F0\u660E\u5F0F\u4EE3\u7406\u8DEF\u7531 \u2500\u2500\u2500
|
|
1805
|
+
function _sanitizeProxyPath(raw) {
|
|
1806
|
+
if (raw.startsWith("//")) return null;
|
|
1807
|
+
return raw.startsWith("/") ? raw : "/" + raw;
|
|
1808
|
+
}
|
|
1809
|
+
`);
|
|
1810
|
+
for (const config of configs) {
|
|
1811
|
+
const methods = config.methods ?? ["all"];
|
|
1812
|
+
const pattern = `"${config.prefix}/*"`;
|
|
1813
|
+
const headersJson = JSON.stringify(config.headers ?? {});
|
|
1814
|
+
const cacheStr = config.cache ? JSON.stringify(config.cache) : "null";
|
|
1815
|
+
const redirect = config.followRedirects ? '"follow"' : '"manual"';
|
|
1816
|
+
let authCode = "";
|
|
1817
|
+
if (config.auth) {
|
|
1818
|
+
const envKey = JSON.stringify(config.auth.envKey);
|
|
1819
|
+
const prefix = config.auth.type === "bearer" ? "Bearer " : "Basic ";
|
|
1820
|
+
authCode = `
|
|
1821
|
+
const _token = (typeof process !== "undefined" && process.env && process.env[${envKey}]) || "";
|
|
1822
|
+
if (_token) _headers.Authorization = "${prefix}" + _token;`;
|
|
1823
|
+
}
|
|
1824
|
+
const handlerCode = `async (c) => {
|
|
1825
|
+
const _sub = _sanitizeProxyPath(c.req.path.replace(${JSON.stringify(
|
|
1826
|
+
config.prefix
|
|
1827
|
+
)}, ""));
|
|
1828
|
+
if (!_sub) return c.text("Invalid path", 400);
|
|
1829
|
+
const _target = new URL(_sub, ${JSON.stringify(config.target)});
|
|
1830
|
+
const _reqUrl = new URL(c.req.url);
|
|
1831
|
+
_reqUrl.searchParams.forEach((v, k) => _target.searchParams.set(k, v));
|
|
1832
|
+
const _headers = ${headersJson};${authCode}
|
|
1833
|
+
try {
|
|
1834
|
+
const _resp = await fetch(_target.toString(), { headers: _headers, redirect: ${redirect} });
|
|
1835
|
+
const _body = await _resp.text();
|
|
1836
|
+
const _rh = { "Content-Type": _resp.headers.get("Content-Type") || "application/json" };
|
|
1837
|
+
if (${cacheStr}) _rh["Cache-Control"] = ${cacheStr};
|
|
1838
|
+
return c.newResponse(_body, _resp.status, _rh);
|
|
1839
|
+
} catch (_e) {
|
|
1840
|
+
console.error("[Proxy ${config.prefix}]", _e);
|
|
1841
|
+
return c.json({ error: "Proxy request failed" }, 502);
|
|
1842
|
+
}
|
|
1843
|
+
}`;
|
|
1844
|
+
for (const method of methods) {
|
|
1845
|
+
blocks.push(`app.${method}(${pattern}, ${handlerCode});`);
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
return blocks.join("\n");
|
|
1849
|
+
}
|
|
1850
|
+
|
|
1729
1851
|
// ../server/src/adapters/shared.ts
|
|
1730
1852
|
var BUILD_TOOL_EXTERNALS = [
|
|
1731
1853
|
"vite",
|
|
@@ -1769,7 +1891,7 @@ function parseAcceptLanguage(header) {
|
|
|
1769
1891
|
if (!header) return DEFAULT_LOCALE;
|
|
1770
1892
|
const langs = header.split(",").map(p => {
|
|
1771
1893
|
const [l, q] = p.trim().split(";q=");
|
|
1772
|
-
return { l: l.trim().toLowerCase(), q: q ? +q : 1 };
|
|
1894
|
+
return { l: l.trim().toLowerCase(), q: q ? (+q || 0) : 1 };
|
|
1773
1895
|
}).sort((a, b) => b.q - a.q);
|
|
1774
1896
|
for (const { l } of langs) {
|
|
1775
1897
|
const prefix = l.split("-")[0];
|
|
@@ -1799,7 +1921,8 @@ function matchRenderMode(url) {
|
|
|
1799
1921
|
if (RENDER_MODES[path]) return RENDER_MODES[path];
|
|
1800
1922
|
for (const [pattern, mode] of Object.entries(RENDER_MODES)) {
|
|
1801
1923
|
if (pattern.includes("*")) {
|
|
1802
|
-
const
|
|
1924
|
+
const escaped = pattern.replace(/[.+?^\${}()|[\\]\\\\]/g, "\\\\$&");
|
|
1925
|
+
const re = new RegExp("^" + escaped.replace(/\\*/g, ".*") + "$");
|
|
1803
1926
|
if (re.test(path)) return mode;
|
|
1804
1927
|
}
|
|
1805
1928
|
}
|
|
@@ -1807,6 +1930,7 @@ function matchRenderMode(url) {
|
|
|
1807
1930
|
}
|
|
1808
1931
|
|
|
1809
1932
|
const app = new Hono();
|
|
1933
|
+
${generateProxyCode(ctx.proxies ?? [])}
|
|
1810
1934
|
${setupCall}
|
|
1811
1935
|
${opts.platformMiddleware ?? ""}
|
|
1812
1936
|
|
|
@@ -2359,7 +2483,8 @@ function resolveRenderMode(routePath, routeRenderMode, renderModes) {
|
|
|
2359
2483
|
if (renderModes[routePath]) return renderModes[routePath];
|
|
2360
2484
|
for (const [pattern, mode] of Object.entries(renderModes)) {
|
|
2361
2485
|
if (pattern.includes("*")) {
|
|
2362
|
-
const
|
|
2486
|
+
const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
|
|
2487
|
+
const re = new RegExp("^" + escaped.replace(/\*/g, ".*") + "$");
|
|
2363
2488
|
if (re.test(routePath)) return mode;
|
|
2364
2489
|
}
|
|
2365
2490
|
}
|
|
@@ -2665,6 +2790,7 @@ async function createServer(config = {}) {
|
|
|
2665
2790
|
defaultLocale,
|
|
2666
2791
|
port = Number(process.env.PORT) || 3e3,
|
|
2667
2792
|
setup,
|
|
2793
|
+
proxies,
|
|
2668
2794
|
ssr
|
|
2669
2795
|
} = config;
|
|
2670
2796
|
const root = rootOverride ?? process.cwd();
|
|
@@ -2701,6 +2827,9 @@ async function createServer(config = {}) {
|
|
|
2701
2827
|
});
|
|
2702
2828
|
}
|
|
2703
2829
|
const app = new import_hono3.Hono();
|
|
2830
|
+
if (proxies?.length) {
|
|
2831
|
+
registerProxyRoutes(app, proxies);
|
|
2832
|
+
}
|
|
2704
2833
|
if (setup) {
|
|
2705
2834
|
await setup(app);
|
|
2706
2835
|
}
|
|
@@ -2744,7 +2873,8 @@ function matchRenderModeConfig(url, renderModes) {
|
|
|
2744
2873
|
if (renderModes[path]) return renderModes[path];
|
|
2745
2874
|
for (const [pattern, mode] of Object.entries(renderModes)) {
|
|
2746
2875
|
if (pattern.includes("*")) {
|
|
2747
|
-
const
|
|
2876
|
+
const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
|
|
2877
|
+
const re = new RegExp("^" + escaped.replace(/\*/g, ".*") + "$");
|
|
2748
2878
|
if (re.test(path)) return mode;
|
|
2749
2879
|
}
|
|
2750
2880
|
}
|
|
@@ -2756,6 +2886,7 @@ function finesoftFrontViteConfig(options = {}) {
|
|
|
2756
2886
|
let resolvedCommand;
|
|
2757
2887
|
let resolvedResolve;
|
|
2758
2888
|
let resolvedCss;
|
|
2889
|
+
const CSS_EXTENSIONS = /\.(css|scss|less|sass|styl|stylus|pcss|postcss)($|\?)/;
|
|
2759
2890
|
return {
|
|
2760
2891
|
name: "finesoft-front",
|
|
2761
2892
|
config(userConfig, env) {
|
|
@@ -2775,6 +2906,82 @@ function finesoftFrontViteConfig(options = {}) {
|
|
|
2775
2906
|
resolvedCss = config.css;
|
|
2776
2907
|
root = config.root;
|
|
2777
2908
|
},
|
|
2909
|
+
/**
|
|
2910
|
+
* Dev 模式 CSS 内联 — 消除 SSR 首屏布局抖动
|
|
2911
|
+
*
|
|
2912
|
+
* Vite dev 模式下,global.scss 等非组件 CSS 通过 JS 模块系统异步加载,
|
|
2913
|
+
* 导致 SSR HTML 初次渲染缺少布局关键样式(box-sizing、flex 布局、padding-top 等)。
|
|
2914
|
+
*
|
|
2915
|
+
* 此 hook 在 HTML 模板变换阶段(SSR 渲染之前):
|
|
2916
|
+
* 1. 找到浏览器入口脚本(排除 /@vite/client 等内部脚本)
|
|
2917
|
+
* 2. 编译入口脚本,填充 Vite 模块图
|
|
2918
|
+
* 3. 遍历模块图收集所有 CSS 依赖(排除 .svelte 组件 CSS,由 SSR 渲染自行处理)
|
|
2919
|
+
* 4. 通过 ssrLoadModule 获取编译后 CSS(SCSS→CSS)
|
|
2920
|
+
* 5. 注入 <style data-vite-dev-id> 标签到 <head>
|
|
2921
|
+
*
|
|
2922
|
+
* data-vite-dev-id 确保 Vite HMR 客户端复用已有标签,避免重复注入。
|
|
2923
|
+
*/
|
|
2924
|
+
transformIndexHtml: {
|
|
2925
|
+
order: "pre",
|
|
2926
|
+
async handler(html, ctx) {
|
|
2927
|
+
const server = ctx.server;
|
|
2928
|
+
if (!server) return;
|
|
2929
|
+
const urlPath = (ctx.originalUrl || ctx.path || "").split(
|
|
2930
|
+
"?"
|
|
2931
|
+
)[0];
|
|
2932
|
+
if (/\.\w+$/.test(urlPath) && !urlPath.endsWith(".html")) {
|
|
2933
|
+
return;
|
|
2934
|
+
}
|
|
2935
|
+
const scripts = [
|
|
2936
|
+
...html.matchAll(
|
|
2937
|
+
/<script\b[^>]*\bsrc=["']([^"']+)["'][^>]*>/g
|
|
2938
|
+
)
|
|
2939
|
+
];
|
|
2940
|
+
const appEntry = scripts.find((m) => !m[1].startsWith("/@"));
|
|
2941
|
+
if (!appEntry) return;
|
|
2942
|
+
const browserEntry = appEntry[1];
|
|
2943
|
+
try {
|
|
2944
|
+
await server.transformRequest(browserEntry);
|
|
2945
|
+
} catch {
|
|
2946
|
+
return;
|
|
2947
|
+
}
|
|
2948
|
+
const cssUrls = [];
|
|
2949
|
+
const visited = /* @__PURE__ */ new Set();
|
|
2950
|
+
function walk(mod) {
|
|
2951
|
+
if (!mod?.url || visited.has(mod.url)) return;
|
|
2952
|
+
visited.add(mod.url);
|
|
2953
|
+
if (CSS_EXTENSIONS.test(mod.url) && !mod.url.includes(".svelte")) {
|
|
2954
|
+
cssUrls.push(mod.url);
|
|
2955
|
+
}
|
|
2956
|
+
if (mod.importedModules) {
|
|
2957
|
+
for (const imported of mod.importedModules) {
|
|
2958
|
+
walk(imported);
|
|
2959
|
+
}
|
|
2960
|
+
}
|
|
2961
|
+
}
|
|
2962
|
+
const mg = server.moduleGraph;
|
|
2963
|
+
const browserMod = await mg.getModuleByUrl(browserEntry);
|
|
2964
|
+
if (browserMod) walk(browserMod);
|
|
2965
|
+
if (cssUrls.length === 0) return;
|
|
2966
|
+
const tags = [];
|
|
2967
|
+
for (const url of cssUrls) {
|
|
2968
|
+
try {
|
|
2969
|
+
const mod = await server.ssrLoadModule(url);
|
|
2970
|
+
const css = mod?.default;
|
|
2971
|
+
if (typeof css === "string" && css.length > 0) {
|
|
2972
|
+
tags.push({
|
|
2973
|
+
tag: "style",
|
|
2974
|
+
attrs: { "data-vite-dev-id": url },
|
|
2975
|
+
children: css,
|
|
2976
|
+
injectTo: "head"
|
|
2977
|
+
});
|
|
2978
|
+
}
|
|
2979
|
+
} catch {
|
|
2980
|
+
}
|
|
2981
|
+
}
|
|
2982
|
+
return tags;
|
|
2983
|
+
}
|
|
2984
|
+
},
|
|
2778
2985
|
// ─── Dev ───────────────────────────────────────────────
|
|
2779
2986
|
configureServer(server) {
|
|
2780
2987
|
return async () => {
|
|
@@ -2788,6 +2995,9 @@ function finesoftFrontViteConfig(options = {}) {
|
|
|
2788
2995
|
"@hono/node-server"
|
|
2789
2996
|
);
|
|
2790
2997
|
const app = new HonoClass();
|
|
2998
|
+
if (options.proxies?.length) {
|
|
2999
|
+
registerProxyRoutes(app, options.proxies);
|
|
3000
|
+
}
|
|
2791
3001
|
if (typeof options.setup === "function") {
|
|
2792
3002
|
await options.setup(app);
|
|
2793
3003
|
} else if (typeof options.setup === "string") {
|
|
@@ -2838,6 +3048,9 @@ function finesoftFrontViteConfig(options = {}) {
|
|
|
2838
3048
|
);
|
|
2839
3049
|
const app = new HonoClass();
|
|
2840
3050
|
const isrCache = /* @__PURE__ */ new Map();
|
|
3051
|
+
if (options.proxies?.length) {
|
|
3052
|
+
registerProxyRoutes(app, options.proxies);
|
|
3053
|
+
}
|
|
2841
3054
|
if (typeof options.setup === "function") {
|
|
2842
3055
|
await options.setup(app);
|
|
2843
3056
|
} else if (typeof options.setup === "string") {
|
|
@@ -2992,6 +3205,7 @@ function finesoftFrontViteConfig(options = {}) {
|
|
|
2992
3205
|
defaultLocale,
|
|
2993
3206
|
templateHtml,
|
|
2994
3207
|
renderModes: options.renderModes,
|
|
3208
|
+
proxies: options.proxies,
|
|
2995
3209
|
resolvedResolve,
|
|
2996
3210
|
resolvedCss,
|
|
2997
3211
|
vite,
|
|
@@ -3049,6 +3263,7 @@ function finesoftFrontViteConfig(options = {}) {
|
|
|
3049
3263
|
deserializeServerData,
|
|
3050
3264
|
detectRuntime,
|
|
3051
3265
|
finesoftFrontViteConfig,
|
|
3266
|
+
generateProxyCode,
|
|
3052
3267
|
generateUuid,
|
|
3053
3268
|
getBaseUrl,
|
|
3054
3269
|
injectCSRShell,
|
|
@@ -3070,6 +3285,7 @@ function finesoftFrontViteConfig(options = {}) {
|
|
|
3070
3285
|
registerActionHandlers,
|
|
3071
3286
|
registerExternalUrlHandler,
|
|
3072
3287
|
registerFlowActionHandler,
|
|
3288
|
+
registerProxyRoutes,
|
|
3073
3289
|
removeHost,
|
|
3074
3290
|
removeQueryParams,
|
|
3075
3291
|
removeScheme,
|