@nasti-toolchain/nasti 2.3.1 → 2.4.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/README.md +97 -1
- package/bin/nasti.js +0 -0
- package/client/hmr.ts +4 -3
- package/dist/cli.cjs +1896 -583
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +1891 -575
- package/dist/cli.js.map +1 -1
- package/dist/client/hmr.cjs.map +1 -1
- package/dist/client/hmr.d.cts +4 -3
- package/dist/client/hmr.d.ts +4 -3
- package/dist/index.cjs +1810 -497
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +233 -18
- package/dist/index.d.ts +233 -18
- package/dist/index.js +1810 -494
- package/dist/index.js.map +1 -1
- package/package.json +8 -4
package/dist/index.cjs
CHANGED
|
@@ -5,10 +5,10 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __glob = (map) => (
|
|
9
|
-
var fn = map[
|
|
8
|
+
var __glob = (map) => (path19) => {
|
|
9
|
+
var fn = map[path19];
|
|
10
10
|
if (fn) return fn();
|
|
11
|
-
throw new Error("Module not found in bundle: " +
|
|
11
|
+
throw new Error("Module not found in bundle: " + path19);
|
|
12
12
|
};
|
|
13
13
|
var __esm = (fn, res) => function __init() {
|
|
14
14
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
@@ -66,7 +66,10 @@ var init_defaults = __esm({
|
|
|
66
66
|
target: "es2022",
|
|
67
67
|
rolldownOptions: {},
|
|
68
68
|
emptyOutDir: true,
|
|
69
|
-
css: {
|
|
69
|
+
css: {
|
|
70
|
+
inject: true,
|
|
71
|
+
emit: true
|
|
72
|
+
},
|
|
70
73
|
reportCompressedSize: true,
|
|
71
74
|
chunkSizeWarningLimit: 500,
|
|
72
75
|
cssCodeSplit: true,
|
|
@@ -418,7 +421,11 @@ async function resolveConfig(inlineConfig = {}, command) {
|
|
|
418
421
|
allowClearScreen: clearScreen2,
|
|
419
422
|
customLogger: merged.customLogger
|
|
420
423
|
});
|
|
421
|
-
const mergedBuild = {
|
|
424
|
+
const mergedBuild = {
|
|
425
|
+
...defaults.build,
|
|
426
|
+
...merged.build,
|
|
427
|
+
css: { ...defaults.build.css, ...merged.build?.css }
|
|
428
|
+
};
|
|
422
429
|
if (merged.build?.cssMinify === void 0) {
|
|
423
430
|
mergedBuild.cssMinify = !!mergedBuild.minify;
|
|
424
431
|
}
|
|
@@ -449,11 +456,17 @@ async function resolveConfig(inlineConfig = {}, command) {
|
|
|
449
456
|
bundledDev: merged.experimental?.bundledDev ?? defaults.experimental.bundledDev
|
|
450
457
|
}
|
|
451
458
|
};
|
|
452
|
-
const
|
|
459
|
+
const rawUserEnvironments = {
|
|
453
460
|
client: {},
|
|
454
461
|
ssr: {},
|
|
455
462
|
...merged.environments ?? {}
|
|
456
463
|
};
|
|
464
|
+
const userEnvironments = Object.fromEntries(
|
|
465
|
+
Object.entries(rawUserEnvironments).map(([name, options]) => [
|
|
466
|
+
name,
|
|
467
|
+
deepMerge({}, options)
|
|
468
|
+
])
|
|
469
|
+
);
|
|
457
470
|
for (const [name, envOptions] of Object.entries(userEnvironments)) {
|
|
458
471
|
for (const plugin of rawPlugins) {
|
|
459
472
|
if (plugin.configEnvironment) {
|
|
@@ -464,6 +477,7 @@ async function resolveConfig(inlineConfig = {}, command) {
|
|
|
464
477
|
}
|
|
465
478
|
for (const [name, envOptions] of Object.entries(userEnvironments)) {
|
|
466
479
|
const consumer = envOptions.consumer ?? (name === "client" ? "client" : "server");
|
|
480
|
+
const vueOptions = deepMerge({}, envOptions.vue ?? {});
|
|
467
481
|
if (name === "client") {
|
|
468
482
|
if (envOptions.resolve) {
|
|
469
483
|
Object.assign(resolved.resolve, {
|
|
@@ -471,9 +485,14 @@ async function resolveConfig(inlineConfig = {}, command) {
|
|
|
471
485
|
alias: { ...resolved.resolve.alias, ...envOptions.resolve.alias }
|
|
472
486
|
});
|
|
473
487
|
}
|
|
474
|
-
if (envOptions.build)
|
|
488
|
+
if (envOptions.build) {
|
|
489
|
+
const { css, ...environmentBuild } = envOptions.build;
|
|
490
|
+
Object.assign(resolved.build, environmentBuild);
|
|
491
|
+
if (css) resolved.build.css = { ...resolved.build.css, ...css };
|
|
492
|
+
}
|
|
475
493
|
resolved.environments.client = {
|
|
476
494
|
consumer,
|
|
495
|
+
buildEnabled: envOptions.buildEnabled ?? true,
|
|
477
496
|
entry: normalizeEnvironmentEntries(envOptions.entry, root),
|
|
478
497
|
html: import_node_path.default.resolve(
|
|
479
498
|
root,
|
|
@@ -482,15 +501,18 @@ async function resolveConfig(inlineConfig = {}, command) {
|
|
|
482
501
|
driver: envOptions.driver,
|
|
483
502
|
// 同引用 —— 精确镜像(assertClientEnvironmentMirror 校验)
|
|
484
503
|
resolve: resolved.resolve,
|
|
485
|
-
build: resolved.build
|
|
504
|
+
build: resolved.build,
|
|
505
|
+
vue: vueOptions
|
|
486
506
|
};
|
|
487
507
|
continue;
|
|
488
508
|
}
|
|
489
509
|
resolved.environments[name] = {
|
|
490
510
|
consumer,
|
|
511
|
+
buildEnabled: envOptions.buildEnabled ?? true,
|
|
491
512
|
entry: normalizeEnvironmentEntries(envOptions.entry, root),
|
|
492
513
|
html: envOptions.consumer === "client" && envOptions.html ? import_node_path.default.resolve(root, envOptions.html) : void 0,
|
|
493
514
|
driver: envOptions.driver,
|
|
515
|
+
vue: vueOptions,
|
|
494
516
|
resolve: {
|
|
495
517
|
alias: { ...resolved.resolve.alias, ...envOptions.resolve?.alias },
|
|
496
518
|
extensions: envOptions.resolve?.extensions ?? [...resolved.resolve.extensions],
|
|
@@ -501,6 +523,7 @@ async function resolveConfig(inlineConfig = {}, command) {
|
|
|
501
523
|
build: {
|
|
502
524
|
...resolved.build,
|
|
503
525
|
...envOptions.build,
|
|
526
|
+
css: { ...resolved.build.css, ...envOptions.build?.css },
|
|
504
527
|
// 非 client 环境默认产出到 <outDir>/<envName>(如 dist/ssr),可显式覆盖
|
|
505
528
|
outDir: envOptions.build?.outDir ?? import_node_path.default.join(resolved.build.outDir, name),
|
|
506
529
|
// server 产物默认不压缩(可调试性优先,与 Vite SSR 默认一致),可显式覆盖
|
|
@@ -714,6 +737,7 @@ function resolvePlugin(config) {
|
|
|
714
737
|
}
|
|
715
738
|
if (!source.startsWith("/") && !source.startsWith(".")) {
|
|
716
739
|
if (vueRuntimeEntry && source === "vue") return vueRuntimeEntry;
|
|
740
|
+
if (config.command === "build") return null;
|
|
717
741
|
try {
|
|
718
742
|
const resolved = require2.resolve(source, {
|
|
719
743
|
paths: [importer ? import_node_path2.default.dirname(importer) : config.root]
|
|
@@ -732,7 +756,7 @@ function resolvePlugin(config) {
|
|
|
732
756
|
const content = import_node_fs2.default.readFileSync(id, "utf-8");
|
|
733
757
|
return `export default ${content}`;
|
|
734
758
|
}
|
|
735
|
-
return
|
|
759
|
+
return null;
|
|
736
760
|
}
|
|
737
761
|
};
|
|
738
762
|
}
|
|
@@ -849,27 +873,27 @@ var require_process = __commonJS({
|
|
|
849
873
|
var require_filesystem = __commonJS({
|
|
850
874
|
"node_modules/detect-libc/lib/filesystem.js"(exports2, module2) {
|
|
851
875
|
"use strict";
|
|
852
|
-
var
|
|
876
|
+
var fs14 = require("fs");
|
|
853
877
|
var LDD_PATH = "/usr/bin/ldd";
|
|
854
878
|
var SELF_PATH = "/proc/self/exe";
|
|
855
879
|
var MAX_LENGTH = 2048;
|
|
856
|
-
var readFileSync = (
|
|
857
|
-
const fd =
|
|
880
|
+
var readFileSync = (path19) => {
|
|
881
|
+
const fd = fs14.openSync(path19, "r");
|
|
858
882
|
const buffer = Buffer.alloc(MAX_LENGTH);
|
|
859
|
-
const bytesRead =
|
|
860
|
-
|
|
883
|
+
const bytesRead = fs14.readSync(fd, buffer, 0, MAX_LENGTH, 0);
|
|
884
|
+
fs14.close(fd, () => {
|
|
861
885
|
});
|
|
862
886
|
return buffer.subarray(0, bytesRead);
|
|
863
887
|
};
|
|
864
|
-
var readFile = (
|
|
865
|
-
|
|
888
|
+
var readFile = (path19) => new Promise((resolve, reject) => {
|
|
889
|
+
fs14.open(path19, "r", (err, fd) => {
|
|
866
890
|
if (err) {
|
|
867
891
|
reject(err);
|
|
868
892
|
} else {
|
|
869
893
|
const buffer = Buffer.alloc(MAX_LENGTH);
|
|
870
|
-
|
|
894
|
+
fs14.read(fd, buffer, 0, MAX_LENGTH, 0, (_, bytesRead) => {
|
|
871
895
|
resolve(buffer.subarray(0, bytesRead));
|
|
872
|
-
|
|
896
|
+
fs14.close(fd, () => {
|
|
873
897
|
});
|
|
874
898
|
});
|
|
875
899
|
}
|
|
@@ -981,11 +1005,11 @@ var require_detect_libc = __commonJS({
|
|
|
981
1005
|
}
|
|
982
1006
|
return null;
|
|
983
1007
|
};
|
|
984
|
-
var familyFromInterpreterPath = (
|
|
985
|
-
if (
|
|
986
|
-
if (
|
|
1008
|
+
var familyFromInterpreterPath = (path19) => {
|
|
1009
|
+
if (path19) {
|
|
1010
|
+
if (path19.includes("/ld-musl-")) {
|
|
987
1011
|
return MUSL;
|
|
988
|
-
} else if (
|
|
1012
|
+
} else if (path19.includes("/ld-linux-")) {
|
|
989
1013
|
return GLIBC;
|
|
990
1014
|
}
|
|
991
1015
|
}
|
|
@@ -1032,8 +1056,8 @@ var require_detect_libc = __commonJS({
|
|
|
1032
1056
|
cachedFamilyInterpreter = null;
|
|
1033
1057
|
try {
|
|
1034
1058
|
const selfContent = await readFile(SELF_PATH);
|
|
1035
|
-
const
|
|
1036
|
-
cachedFamilyInterpreter = familyFromInterpreterPath(
|
|
1059
|
+
const path19 = interpreterPath(selfContent);
|
|
1060
|
+
cachedFamilyInterpreter = familyFromInterpreterPath(path19);
|
|
1037
1061
|
} catch (e) {
|
|
1038
1062
|
}
|
|
1039
1063
|
return cachedFamilyInterpreter;
|
|
@@ -1045,8 +1069,8 @@ var require_detect_libc = __commonJS({
|
|
|
1045
1069
|
cachedFamilyInterpreter = null;
|
|
1046
1070
|
try {
|
|
1047
1071
|
const selfContent = readFileSync(SELF_PATH);
|
|
1048
|
-
const
|
|
1049
|
-
cachedFamilyInterpreter = familyFromInterpreterPath(
|
|
1072
|
+
const path19 = interpreterPath(selfContent);
|
|
1073
|
+
cachedFamilyInterpreter = familyFromInterpreterPath(path19);
|
|
1050
1074
|
} catch (e) {
|
|
1051
1075
|
}
|
|
1052
1076
|
return cachedFamilyInterpreter;
|
|
@@ -1693,12 +1717,31 @@ var init_node = __esm({
|
|
|
1693
1717
|
function createCssEngine() {
|
|
1694
1718
|
return {
|
|
1695
1719
|
styles: /* @__PURE__ */ new Map(),
|
|
1720
|
+
modules: /* @__PURE__ */ new Map(),
|
|
1721
|
+
chunks: /* @__PURE__ */ new Map(),
|
|
1696
1722
|
entryCss: /* @__PURE__ */ new Map(),
|
|
1697
1723
|
allCss: [],
|
|
1698
1724
|
pendingSingle: [],
|
|
1699
1725
|
singleFileName: null
|
|
1700
1726
|
};
|
|
1701
1727
|
}
|
|
1728
|
+
function getCssMetadata(engine) {
|
|
1729
|
+
return {
|
|
1730
|
+
modules: Object.fromEntries(
|
|
1731
|
+
[...engine.modules].map(([id, module2]) => [id, { ...module2 }])
|
|
1732
|
+
),
|
|
1733
|
+
chunks: Object.fromEntries(
|
|
1734
|
+
[...engine.chunks].map(([fileName, chunk]) => [
|
|
1735
|
+
fileName,
|
|
1736
|
+
{
|
|
1737
|
+
fileName,
|
|
1738
|
+
moduleIds: [...chunk.moduleIds],
|
|
1739
|
+
cssFileNames: [...chunk.cssFileNames]
|
|
1740
|
+
}
|
|
1741
|
+
])
|
|
1742
|
+
)
|
|
1743
|
+
};
|
|
1744
|
+
}
|
|
1702
1745
|
function normalizeCssModuleId(id) {
|
|
1703
1746
|
return id.startsWith("\0") ? id.slice(1) : id;
|
|
1704
1747
|
}
|
|
@@ -1818,15 +1861,29 @@ function cssPlugin(config, engine, consumer = "client") {
|
|
|
1818
1861
|
}
|
|
1819
1862
|
const rewritten = rewriteCssUrls(cssSource, file, config.root);
|
|
1820
1863
|
const escaped = JSON.stringify(rewritten);
|
|
1864
|
+
const normalizedId = normalizeCssModuleId(id);
|
|
1865
|
+
const cssModule = { id: normalizedId, source: code, code: rewritten };
|
|
1866
|
+
const map = config.build.sourcemap ? createIdentitySourceMap(code, id) : void 0;
|
|
1867
|
+
engine?.modules.set(normalizedId, cssModule);
|
|
1868
|
+
this.environment?.setCssModule?.(cssModule);
|
|
1821
1869
|
if (query === "inline") {
|
|
1822
1870
|
return { code: `export default ${escaped};
|
|
1823
|
-
`, moduleType: "js" };
|
|
1871
|
+
`, map, moduleType: "js" };
|
|
1824
1872
|
}
|
|
1825
1873
|
if (consumer === "server") {
|
|
1826
1874
|
return { code: `export default ${escaped};
|
|
1827
|
-
`, moduleType: "js" };
|
|
1875
|
+
`, map, moduleType: "js" };
|
|
1828
1876
|
}
|
|
1829
1877
|
if (config.command === "serve") {
|
|
1878
|
+
if (config.build.css.inject === false) {
|
|
1879
|
+
return {
|
|
1880
|
+
code: `export default ${escaped};
|
|
1881
|
+
`,
|
|
1882
|
+
map,
|
|
1883
|
+
moduleType: "js",
|
|
1884
|
+
moduleSideEffects: "no-treeshake"
|
|
1885
|
+
};
|
|
1886
|
+
}
|
|
1830
1887
|
return {
|
|
1831
1888
|
code: `
|
|
1832
1889
|
const css = ${escaped};
|
|
@@ -1850,16 +1907,18 @@ if (import.meta.hot) {
|
|
|
1850
1907
|
|
|
1851
1908
|
export default css;
|
|
1852
1909
|
`,
|
|
1910
|
+
map,
|
|
1853
1911
|
// bundled dev(DevEngine)下该模块会进 Rolldown:不标 js 会按 .css
|
|
1854
1912
|
// 扩展名走 CSS 管线触发 #4271 报错;unbundled 中间件忽略此字段
|
|
1855
1913
|
moduleType: "js"
|
|
1856
1914
|
};
|
|
1857
1915
|
}
|
|
1858
1916
|
if (engine) {
|
|
1859
|
-
engine.styles.set(
|
|
1917
|
+
engine.styles.set(normalizedId, rewritten);
|
|
1860
1918
|
return {
|
|
1861
1919
|
code: `export default '';
|
|
1862
1920
|
`,
|
|
1921
|
+
map,
|
|
1863
1922
|
moduleType: "js",
|
|
1864
1923
|
// 防止空 stub 被 tree-shake 出 chunk.moduleIds(css-post 靠它定位)
|
|
1865
1924
|
moduleSideEffects: "no-treeshake"
|
|
@@ -1879,11 +1938,27 @@ document.head.appendChild(style);
|
|
|
1879
1938
|
|
|
1880
1939
|
export default css;
|
|
1881
1940
|
`,
|
|
1941
|
+
map,
|
|
1882
1942
|
moduleType: "js"
|
|
1883
1943
|
};
|
|
1884
1944
|
}
|
|
1885
1945
|
};
|
|
1886
1946
|
}
|
|
1947
|
+
function createIdentitySourceMap(code, id) {
|
|
1948
|
+
const map = new import_source_map_js.SourceMapGenerator({ file: id });
|
|
1949
|
+
const lines = code.split("\n");
|
|
1950
|
+
for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
|
|
1951
|
+
for (let column = 0; column <= lines[lineIndex].length; column++) {
|
|
1952
|
+
map.addMapping({
|
|
1953
|
+
generated: { line: lineIndex + 1, column },
|
|
1954
|
+
original: { line: lineIndex + 1, column },
|
|
1955
|
+
source: id
|
|
1956
|
+
});
|
|
1957
|
+
}
|
|
1958
|
+
}
|
|
1959
|
+
map.setSourceContent(id, code);
|
|
1960
|
+
return map.toJSON();
|
|
1961
|
+
}
|
|
1887
1962
|
function rewriteCssUrls(css, from, root) {
|
|
1888
1963
|
return css.replace(/url\(\s*['"]?([^'")\s]+)['"]?\s*\)/g, (match, url) => {
|
|
1889
1964
|
if (url.startsWith("/") || url.startsWith("data:") || url.startsWith("http")) {
|
|
@@ -1894,11 +1969,12 @@ function rewriteCssUrls(css, from, root) {
|
|
|
1894
1969
|
return `url(${relative})`;
|
|
1895
1970
|
});
|
|
1896
1971
|
}
|
|
1897
|
-
var import_node_path4;
|
|
1972
|
+
var import_node_path4, import_source_map_js;
|
|
1898
1973
|
var init_css = __esm({
|
|
1899
1974
|
"src/plugins/css.ts"() {
|
|
1900
1975
|
"use strict";
|
|
1901
1976
|
import_node_path4 = __toESM(require("path"), 1);
|
|
1977
|
+
import_source_map_js = require("source-map-js");
|
|
1902
1978
|
init_css_engine();
|
|
1903
1979
|
init_tailwind();
|
|
1904
1980
|
}
|
|
@@ -1908,19 +1984,27 @@ var init_css = __esm({
|
|
|
1908
1984
|
function collectChunkCss(chunk, engine) {
|
|
1909
1985
|
const ids = chunk.moduleIds ?? Object.keys(chunk.modules);
|
|
1910
1986
|
let css = "";
|
|
1987
|
+
const moduleIds = [];
|
|
1911
1988
|
for (const id of ids) {
|
|
1912
|
-
const
|
|
1913
|
-
|
|
1989
|
+
const normalizedId = normalizeCssModuleId(id);
|
|
1990
|
+
const styles = engine.styles.get(normalizedId);
|
|
1991
|
+
if (styles) {
|
|
1992
|
+
css += styles + "\n";
|
|
1993
|
+
moduleIds.push(normalizedId);
|
|
1994
|
+
}
|
|
1914
1995
|
}
|
|
1915
|
-
return css;
|
|
1996
|
+
return { css, moduleIds };
|
|
1916
1997
|
}
|
|
1917
1998
|
function cssPostPlugin(config, engine) {
|
|
1918
1999
|
return {
|
|
1919
2000
|
name: "nasti:css-post",
|
|
1920
2001
|
enforce: "post",
|
|
1921
2002
|
async renderChunk(code, chunk) {
|
|
1922
|
-
const css = collectChunkCss(chunk, engine);
|
|
2003
|
+
const { css, moduleIds } = collectChunkCss(chunk, engine);
|
|
1923
2004
|
if (!css) return null;
|
|
2005
|
+
const ownership = { moduleIds, cssFileNames: [] };
|
|
2006
|
+
engine.chunks.set(chunk.fileName, ownership);
|
|
2007
|
+
if (config.build.css.emit === false) return null;
|
|
1924
2008
|
if (!config.build.cssCodeSplit) {
|
|
1925
2009
|
engine.pendingSingle.push(css);
|
|
1926
2010
|
return null;
|
|
@@ -1933,6 +2017,7 @@ function cssPostPlugin(config, engine) {
|
|
|
1933
2017
|
});
|
|
1934
2018
|
const fileName = this.getFileName(ref);
|
|
1935
2019
|
engine.allCss.push(fileName);
|
|
2020
|
+
ownership.cssFileNames.push(fileName);
|
|
1936
2021
|
if (chunk.isEntry) {
|
|
1937
2022
|
const key = chunk.facadeModuleId ?? chunk.name;
|
|
1938
2023
|
const existing = engine.entryCss.get(key) ?? [];
|
|
@@ -1940,13 +2025,14 @@ function cssPostPlugin(config, engine) {
|
|
|
1940
2025
|
engine.entryCss.set(key, existing);
|
|
1941
2026
|
return null;
|
|
1942
2027
|
}
|
|
2028
|
+
if (config.build.css.inject === false) return null;
|
|
1943
2029
|
const href = JSON.stringify(config.base + fileName);
|
|
1944
2030
|
const snippet = `
|
|
1945
2031
|
;(function(){try{var d=document,h=${href};if(!d.querySelector('link[data-nasti-css="'+h+'"]')){var l=d.createElement('link');l.rel='stylesheet';l.href=h;l.setAttribute('data-nasti-css',h);d.head.appendChild(l);}}catch(e){}})();`;
|
|
1946
2032
|
return { code: code + snippet, map: null };
|
|
1947
2033
|
},
|
|
1948
2034
|
augmentChunkHash(chunk) {
|
|
1949
|
-
const css = collectChunkCss(chunk, engine);
|
|
2035
|
+
const { css } = collectChunkCss(chunk, engine);
|
|
1950
2036
|
return css || void 0;
|
|
1951
2037
|
},
|
|
1952
2038
|
async generateBundle() {
|
|
@@ -1957,6 +2043,9 @@ function cssPostPlugin(config, engine) {
|
|
|
1957
2043
|
const fileName = this.getFileName(ref);
|
|
1958
2044
|
engine.singleFileName = fileName;
|
|
1959
2045
|
engine.allCss.push(fileName);
|
|
2046
|
+
for (const ownership of engine.chunks.values()) {
|
|
2047
|
+
if (ownership.moduleIds.length > 0) ownership.cssFileNames.push(fileName);
|
|
2048
|
+
}
|
|
1960
2049
|
}
|
|
1961
2050
|
};
|
|
1962
2051
|
}
|
|
@@ -1969,6 +2058,7 @@ var init_css_post = __esm({
|
|
|
1969
2058
|
|
|
1970
2059
|
// src/plugins/assets.ts
|
|
1971
2060
|
function assetsPlugin(config) {
|
|
2061
|
+
const emittedAssets = /* @__PURE__ */ new Set();
|
|
1972
2062
|
return {
|
|
1973
2063
|
name: "nasti:assets",
|
|
1974
2064
|
resolveId(source) {
|
|
@@ -1997,12 +2087,29 @@ function assetsPlugin(config) {
|
|
|
1997
2087
|
const hash = import_node_crypto.default.createHash("sha256").update(content).digest("hex").slice(0, 8);
|
|
1998
2088
|
const basename = import_node_path5.default.basename(file, ext);
|
|
1999
2089
|
const hashedName = `${config.build.assetsDir}/${basename}.${hash}${ext}`;
|
|
2090
|
+
const environment = this.environment;
|
|
2091
|
+
if (!environment) {
|
|
2092
|
+
throw new Error("[nasti:assets] build environment is not initialized");
|
|
2093
|
+
}
|
|
2094
|
+
if (!emittedAssets.has(hashedName)) {
|
|
2095
|
+
this.emitFile({
|
|
2096
|
+
type: "asset",
|
|
2097
|
+
fileName: hashedName,
|
|
2098
|
+
source: content
|
|
2099
|
+
});
|
|
2100
|
+
emittedAssets.add(hashedName);
|
|
2101
|
+
}
|
|
2102
|
+
environment.setAssetModule(file, hashedName);
|
|
2000
2103
|
return `export default ${JSON.stringify(config.base + hashedName)}`;
|
|
2001
2104
|
}
|
|
2002
2105
|
return null;
|
|
2003
2106
|
}
|
|
2004
2107
|
};
|
|
2005
2108
|
}
|
|
2109
|
+
function isAssetFile(id) {
|
|
2110
|
+
const ext = import_node_path5.default.extname(id.replace(/\?.*$/, ""));
|
|
2111
|
+
return ASSET_EXTENSIONS.has(ext);
|
|
2112
|
+
}
|
|
2006
2113
|
var import_node_path5, import_node_fs3, import_node_crypto, ASSET_EXTENSIONS;
|
|
2007
2114
|
var init_assets = __esm({
|
|
2008
2115
|
"src/plugins/assets.ts"() {
|
|
@@ -2085,9 +2192,10 @@ async function loadVueCompiler() {
|
|
|
2085
2192
|
return null;
|
|
2086
2193
|
}
|
|
2087
2194
|
}
|
|
2088
|
-
function vuePlugin(config) {
|
|
2195
|
+
function vuePlugin(config, environmentName = "client") {
|
|
2089
2196
|
const isDev = config.command === "serve";
|
|
2090
2197
|
const descriptorCache = /* @__PURE__ */ new Map();
|
|
2198
|
+
const vueOptions = config.environments[environmentName]?.vue ?? {};
|
|
2091
2199
|
return {
|
|
2092
2200
|
name: "nasti:vue",
|
|
2093
2201
|
enforce: "pre",
|
|
@@ -2107,32 +2215,63 @@ function vuePlugin(config) {
|
|
|
2107
2215
|
const sfc = await loadVueCompiler();
|
|
2108
2216
|
if (!sfc) return null;
|
|
2109
2217
|
const [, filePath, indexStr] = match;
|
|
2110
|
-
let
|
|
2111
|
-
if (!
|
|
2218
|
+
let cached2 = descriptorCache.get(filePath);
|
|
2219
|
+
if (!cached2) {
|
|
2112
2220
|
try {
|
|
2113
|
-
const
|
|
2114
|
-
const
|
|
2115
|
-
const
|
|
2221
|
+
const fs14 = await import("fs");
|
|
2222
|
+
const rawSource = fs14.readFileSync(filePath, "utf-8");
|
|
2223
|
+
const transformedSfc = await applySourceTransform(
|
|
2224
|
+
vueOptions.transformSfc,
|
|
2225
|
+
rawSource,
|
|
2226
|
+
{ filename: filePath, environmentName, type: "sfc" }
|
|
2227
|
+
);
|
|
2228
|
+
const parsed = sfc.parse(transformedSfc.code, {
|
|
2229
|
+
...vueOptions.parse,
|
|
2230
|
+
filename: filePath,
|
|
2231
|
+
sourceMap: true
|
|
2232
|
+
});
|
|
2116
2233
|
if (parsed.errors.length) return null;
|
|
2117
|
-
|
|
2118
|
-
|
|
2234
|
+
cached2 = {
|
|
2235
|
+
descriptor: parsed.descriptor,
|
|
2236
|
+
sourceMap: transformedSfc.map
|
|
2237
|
+
};
|
|
2238
|
+
descriptorCache.set(filePath, cached2);
|
|
2119
2239
|
} catch {
|
|
2120
2240
|
return null;
|
|
2121
2241
|
}
|
|
2122
2242
|
}
|
|
2243
|
+
const { descriptor, sourceMap: sfcSourceMap } = cached2;
|
|
2123
2244
|
const index2 = parseInt(indexStr ?? "0", 10);
|
|
2124
2245
|
const style = descriptor.styles[index2];
|
|
2125
2246
|
if (!style) return null;
|
|
2126
2247
|
const scopeId = hashId(filePath);
|
|
2248
|
+
const transformedStyle = await applySourceTransform(
|
|
2249
|
+
vueOptions.transformStyle,
|
|
2250
|
+
style.content,
|
|
2251
|
+
{ filename: filePath, environmentName, type: "style", index: index2 }
|
|
2252
|
+
);
|
|
2253
|
+
const wantsStyleSourceMap = !!config.build.sourcemap || transformedStyle.map != null || sfcSourceMap != null;
|
|
2254
|
+
const styleInputMap = wantsStyleSourceMap ? composeSourceMapChain(
|
|
2255
|
+
[transformedStyle.map, style.map, sfcSourceMap],
|
|
2256
|
+
{ filename: filePath, environmentName, type: "style", index: index2 }
|
|
2257
|
+
) : void 0;
|
|
2127
2258
|
const result = await sfc.compileStyleAsync({
|
|
2128
|
-
|
|
2259
|
+
...vueOptions.style,
|
|
2260
|
+
source: transformedStyle.code,
|
|
2129
2261
|
filename: filePath,
|
|
2130
2262
|
id: `data-v-${scopeId}`,
|
|
2131
2263
|
scoped: style.scoped ?? false,
|
|
2264
|
+
inMap: styleInputMap,
|
|
2132
2265
|
// <style lang="scss|less|stylus"> 需经对应预处理器(缺省 undefined = 纯 CSS)
|
|
2133
2266
|
preprocessLang: style.lang
|
|
2134
2267
|
});
|
|
2135
|
-
|
|
2268
|
+
if (transformedStyle.map != null && result.map == null) {
|
|
2269
|
+
warnUnchainableMap(
|
|
2270
|
+
{ filename: filePath, environmentName, type: "style", index: index2 },
|
|
2271
|
+
"compiler-sfc did not return a style map"
|
|
2272
|
+
);
|
|
2273
|
+
}
|
|
2274
|
+
return wantsStyleSourceMap ? { code: result.code, map: result.map } : result.code;
|
|
2136
2275
|
},
|
|
2137
2276
|
async transform(code, id) {
|
|
2138
2277
|
if (!VUE_FILE_RE.test(id) && !VUE_QUERY_RE.test(id)) return null;
|
|
@@ -2144,57 +2283,144 @@ function vuePlugin(config) {
|
|
|
2144
2283
|
if (VUE_QUERY_RE.test(id)) {
|
|
2145
2284
|
return null;
|
|
2146
2285
|
}
|
|
2147
|
-
const
|
|
2286
|
+
const transformedSfc = await applySourceTransform(
|
|
2287
|
+
vueOptions.transformSfc,
|
|
2288
|
+
code,
|
|
2289
|
+
{ filename: id, environmentName, type: "sfc" }
|
|
2290
|
+
);
|
|
2291
|
+
code = transformedSfc.code;
|
|
2292
|
+
const { descriptor, errors } = sfc.parse(code, {
|
|
2293
|
+
...vueOptions.parse,
|
|
2294
|
+
filename: id,
|
|
2295
|
+
sourceMap: true
|
|
2296
|
+
});
|
|
2148
2297
|
if (errors.length) {
|
|
2149
|
-
|
|
2298
|
+
const firstError = errors[0];
|
|
2299
|
+
console.error(
|
|
2300
|
+
`[nasti:vue] Parse error in ${id}:`,
|
|
2301
|
+
typeof firstError === "string" ? firstError : firstError.message
|
|
2302
|
+
);
|
|
2150
2303
|
return null;
|
|
2151
2304
|
}
|
|
2152
|
-
descriptorCache.set(id,
|
|
2305
|
+
descriptorCache.set(id, {
|
|
2306
|
+
descriptor,
|
|
2307
|
+
sourceMap: transformedSfc.map
|
|
2308
|
+
});
|
|
2153
2309
|
const scopeId = hashId(id);
|
|
2310
|
+
const wantsSourceMap = !!config.build.sourcemap || transformedSfc.map != null;
|
|
2154
2311
|
let scriptCode = "";
|
|
2312
|
+
let scriptMap;
|
|
2155
2313
|
if (descriptor.script || descriptor.scriptSetup) {
|
|
2314
|
+
const inlineTemplate = vueOptions.script?.inlineTemplate !== false;
|
|
2156
2315
|
const compiled = sfc.compileScript(descriptor, {
|
|
2316
|
+
...vueOptions.script,
|
|
2157
2317
|
id: scopeId,
|
|
2158
2318
|
isProd: !isDev,
|
|
2159
|
-
inlineTemplate
|
|
2319
|
+
inlineTemplate,
|
|
2320
|
+
sourceMap: wantsSourceMap,
|
|
2160
2321
|
// 让 compileScript 产出 `const __sfc__ = ...`(而非默认的 `export default {...}`)。
|
|
2161
2322
|
// 否则下方追加的 `__sfc__.render` / `__sfc__.__scopeId` / HMR 记录会引用一个
|
|
2162
2323
|
// 不存在的 `__sfc__`,并与 compileScript 自带的 `export default` 形成双重默认导出。
|
|
2163
2324
|
genDefaultAs: "__sfc__"
|
|
2164
2325
|
});
|
|
2165
2326
|
scriptCode = compiled.content;
|
|
2327
|
+
scriptMap = composeSourceMapChain(
|
|
2328
|
+
[compiled.map, transformedSfc.map],
|
|
2329
|
+
{ filename: id, environmentName, type: "sfc" }
|
|
2330
|
+
);
|
|
2331
|
+
if (transformedSfc.map != null && scriptMap == null) {
|
|
2332
|
+
warnUnchainableMap(
|
|
2333
|
+
{ filename: id, environmentName, type: "sfc" },
|
|
2334
|
+
"compiler-sfc did not return a script map"
|
|
2335
|
+
);
|
|
2336
|
+
}
|
|
2166
2337
|
}
|
|
2167
2338
|
let templateCode = "";
|
|
2168
|
-
|
|
2339
|
+
let templateMap;
|
|
2340
|
+
const scriptSetupIsInline = !!descriptor.scriptSetup && vueOptions.script?.inlineTemplate !== false;
|
|
2341
|
+
if (descriptor.template && !scriptSetupIsInline) {
|
|
2342
|
+
const transformedTemplate = await applySourceTransform(
|
|
2343
|
+
vueOptions.transformTemplate,
|
|
2344
|
+
descriptor.template.content,
|
|
2345
|
+
{ filename: id, environmentName, type: "template" }
|
|
2346
|
+
);
|
|
2347
|
+
const templateInputMap = composeSourceMapChain(
|
|
2348
|
+
[
|
|
2349
|
+
transformedTemplate.map,
|
|
2350
|
+
descriptor.template.map,
|
|
2351
|
+
transformedSfc.map
|
|
2352
|
+
],
|
|
2353
|
+
{ filename: id, environmentName, type: "template" }
|
|
2354
|
+
);
|
|
2355
|
+
const customCompilerOptions = vueOptions.template?.compilerOptions ?? {};
|
|
2169
2356
|
const compiled = sfc.compileTemplate({
|
|
2170
|
-
|
|
2357
|
+
...vueOptions.template,
|
|
2358
|
+
source: transformedTemplate.code,
|
|
2171
2359
|
filename: id,
|
|
2172
2360
|
id: scopeId,
|
|
2173
|
-
|
|
2361
|
+
inMap: templateInputMap,
|
|
2362
|
+
compilerOptions: {
|
|
2363
|
+
...customCompilerOptions,
|
|
2364
|
+
scopeId: `data-v-${scopeId}`
|
|
2365
|
+
}
|
|
2174
2366
|
});
|
|
2175
2367
|
templateCode = compiled.code;
|
|
2368
|
+
if (wantsSourceMap || transformedTemplate.map != null) {
|
|
2369
|
+
templateMap = compiled.map;
|
|
2370
|
+
}
|
|
2371
|
+
if (transformedTemplate.map != null && templateMap == null) {
|
|
2372
|
+
warnUnchainableMap(
|
|
2373
|
+
{ filename: id, environmentName, type: "template" },
|
|
2374
|
+
"compiler-sfc did not return a template map"
|
|
2375
|
+
);
|
|
2376
|
+
}
|
|
2176
2377
|
}
|
|
2177
|
-
|
|
2378
|
+
const outputNode = new import_source_map_js2.SourceNode();
|
|
2379
|
+
let hasMappedOutput = false;
|
|
2380
|
+
const append = (fragment, map) => {
|
|
2381
|
+
const normalizedMap = normalizeSourceMap(
|
|
2382
|
+
map,
|
|
2383
|
+
{ filename: id, environmentName, type: "sfc" }
|
|
2384
|
+
);
|
|
2385
|
+
if (!normalizedMap) {
|
|
2386
|
+
outputNode.add(fragment);
|
|
2387
|
+
return;
|
|
2388
|
+
}
|
|
2389
|
+
try {
|
|
2390
|
+
outputNode.add(
|
|
2391
|
+
import_source_map_js2.SourceNode.fromStringWithSourceMap(
|
|
2392
|
+
fragment,
|
|
2393
|
+
new import_source_map_js2.SourceMapConsumer(normalizedMap)
|
|
2394
|
+
)
|
|
2395
|
+
);
|
|
2396
|
+
hasMappedOutput = true;
|
|
2397
|
+
} catch (error) {
|
|
2398
|
+
warnUnchainableMap(
|
|
2399
|
+
{ filename: id, environmentName, type: "sfc" },
|
|
2400
|
+
`source-map assembly failed: ${error instanceof Error ? error.message : String(error)}`
|
|
2401
|
+
);
|
|
2402
|
+
outputNode.add(fragment);
|
|
2403
|
+
}
|
|
2404
|
+
};
|
|
2405
|
+
append(scriptCode || "const __sfc__ = {}", scriptMap);
|
|
2178
2406
|
if (templateCode) {
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
__sfc__.render = render
|
|
2184
|
-
`;
|
|
2407
|
+
append("\n");
|
|
2408
|
+
append(templateCode, templateMap);
|
|
2409
|
+
append("\n");
|
|
2410
|
+
append("\n__sfc__.render = render\n");
|
|
2185
2411
|
}
|
|
2186
2412
|
if (descriptor.styles.length > 0) {
|
|
2187
2413
|
for (let i = 0; i < descriptor.styles.length; i++) {
|
|
2188
|
-
|
|
2414
|
+
append(`
|
|
2189
2415
|
import "${id}?vue&type=style&index=${i}&lang.css"
|
|
2190
|
-
|
|
2416
|
+
`);
|
|
2191
2417
|
}
|
|
2192
2418
|
}
|
|
2193
|
-
|
|
2419
|
+
append(`
|
|
2194
2420
|
__sfc__.__scopeId = "data-v-${scopeId}"
|
|
2195
|
-
|
|
2421
|
+
`);
|
|
2196
2422
|
if (isDev) {
|
|
2197
|
-
|
|
2423
|
+
append(`
|
|
2198
2424
|
__sfc__.__hmrId = ${JSON.stringify(scopeId)}
|
|
2199
2425
|
if (typeof __VUE_HMR_RUNTIME__ !== 'undefined') {
|
|
2200
2426
|
__VUE_HMR_RUNTIME__.createRecord(__sfc__.__hmrId, __sfc__)
|
|
@@ -2208,17 +2434,34 @@ if (import.meta.hot) {
|
|
|
2208
2434
|
}
|
|
2209
2435
|
})
|
|
2210
2436
|
}
|
|
2211
|
-
|
|
2437
|
+
`);
|
|
2438
|
+
}
|
|
2439
|
+
append("\nexport default __sfc__\n");
|
|
2440
|
+
const renderedOutput = outputNode.toStringWithSourceMap({ file: id });
|
|
2441
|
+
const output = renderedOutput.code;
|
|
2442
|
+
const outputMap = hasMappedOutput ? renderedOutput.map.toJSON() : void 0;
|
|
2443
|
+
if (transformedSfc.map != null && outputMap == null) {
|
|
2444
|
+
warnUnchainableMap(
|
|
2445
|
+
{ filename: id, environmentName, type: "sfc" },
|
|
2446
|
+
"the compiled SFC output contained no chainable mappings"
|
|
2447
|
+
);
|
|
2212
2448
|
}
|
|
2213
|
-
output += `
|
|
2214
|
-
export default __sfc__
|
|
2215
|
-
`;
|
|
2216
2449
|
const lang = descriptor.scriptSetup?.lang ?? descriptor.script?.lang;
|
|
2217
2450
|
if (lang === "ts") {
|
|
2218
|
-
const transpiled = transformCode(`${id}.ts`, output, {
|
|
2219
|
-
|
|
2451
|
+
const transpiled = transformCode(`${id}.ts`, output, {
|
|
2452
|
+
sourcemap: wantsSourceMap,
|
|
2453
|
+
target: config.build.target
|
|
2454
|
+
});
|
|
2455
|
+
const transpiledMap = transpiled.map ? JSON.parse(transpiled.map) : void 0;
|
|
2456
|
+
return {
|
|
2457
|
+
code: transpiled.code,
|
|
2458
|
+
map: composeSourceMapChain(
|
|
2459
|
+
[transpiledMap, outputMap],
|
|
2460
|
+
{ filename: id, environmentName, type: "sfc" }
|
|
2461
|
+
)
|
|
2462
|
+
};
|
|
2220
2463
|
}
|
|
2221
|
-
return { code: output };
|
|
2464
|
+
return { code: output, map: outputMap };
|
|
2222
2465
|
},
|
|
2223
2466
|
handleHotUpdate(ctx) {
|
|
2224
2467
|
const { file, modules } = ctx;
|
|
@@ -2232,17 +2475,77 @@ export default __sfc__
|
|
|
2232
2475
|
}
|
|
2233
2476
|
};
|
|
2234
2477
|
}
|
|
2478
|
+
async function applySourceTransform(transform2, source, context) {
|
|
2479
|
+
if (!transform2) return { code: source };
|
|
2480
|
+
const result = await transform2(source, context);
|
|
2481
|
+
return typeof result === "string" ? { code: result } : result;
|
|
2482
|
+
}
|
|
2483
|
+
function normalizeSourceMap(map, context) {
|
|
2484
|
+
if (map == null) return void 0;
|
|
2485
|
+
try {
|
|
2486
|
+
const value = typeof map === "string" ? JSON.parse(map) : map;
|
|
2487
|
+
if (value && typeof value === "object" && Array.isArray(value.sources) && Array.isArray(value.names) && typeof value.mappings === "string") {
|
|
2488
|
+
return value;
|
|
2489
|
+
}
|
|
2490
|
+
} catch {
|
|
2491
|
+
}
|
|
2492
|
+
warnUnchainableMap(context, "the provided map is not a valid source map");
|
|
2493
|
+
return void 0;
|
|
2494
|
+
}
|
|
2495
|
+
function composeSourceMapChain(maps, context) {
|
|
2496
|
+
const pending = maps.filter((map) => map != null);
|
|
2497
|
+
if (pending.length === 0) return void 0;
|
|
2498
|
+
let composed = normalizeSourceMap(pending.shift(), context);
|
|
2499
|
+
for (const map of pending) {
|
|
2500
|
+
const input = normalizeSourceMap(map, context);
|
|
2501
|
+
if (!input) continue;
|
|
2502
|
+
if (!composed) {
|
|
2503
|
+
composed = input;
|
|
2504
|
+
continue;
|
|
2505
|
+
}
|
|
2506
|
+
try {
|
|
2507
|
+
const consumer = new import_source_map_js2.SourceMapConsumer(composed);
|
|
2508
|
+
if (consumer.sources.length !== 1) {
|
|
2509
|
+
warnUnchainableMap(
|
|
2510
|
+
context,
|
|
2511
|
+
"a generated map has multiple sources and cannot be chained safely"
|
|
2512
|
+
);
|
|
2513
|
+
continue;
|
|
2514
|
+
}
|
|
2515
|
+
const generator = import_source_map_js2.SourceMapGenerator.fromSourceMap(consumer);
|
|
2516
|
+
generator.applySourceMap(
|
|
2517
|
+
new import_source_map_js2.SourceMapConsumer(input),
|
|
2518
|
+
consumer.sources[0]
|
|
2519
|
+
);
|
|
2520
|
+
composed = generator.toJSON();
|
|
2521
|
+
} catch (error) {
|
|
2522
|
+
warnUnchainableMap(
|
|
2523
|
+
context,
|
|
2524
|
+
`source-map composition failed: ${error instanceof Error ? error.message : String(error)}`
|
|
2525
|
+
);
|
|
2526
|
+
}
|
|
2527
|
+
}
|
|
2528
|
+
return composed;
|
|
2529
|
+
}
|
|
2530
|
+
function warnUnchainableMap(context, reason) {
|
|
2531
|
+
debug2?.(
|
|
2532
|
+
`source map warning for ${context.filename} (${context.type}, ${context.environmentName}): ${reason}`
|
|
2533
|
+
);
|
|
2534
|
+
}
|
|
2235
2535
|
function hashId(filename) {
|
|
2236
2536
|
return import_node_crypto2.default.createHash("sha256").update(filename).digest("hex").slice(0, 8);
|
|
2237
2537
|
}
|
|
2238
|
-
var import_node_crypto2, VUE_FILE_RE, VUE_QUERY_RE, compiler;
|
|
2538
|
+
var import_node_crypto2, import_source_map_js2, VUE_FILE_RE, VUE_QUERY_RE, debug2, compiler;
|
|
2239
2539
|
var init_vue = __esm({
|
|
2240
2540
|
"src/plugins/vue.ts"() {
|
|
2241
2541
|
"use strict";
|
|
2242
2542
|
import_node_crypto2 = __toESM(require("crypto"), 1);
|
|
2543
|
+
import_source_map_js2 = require("source-map-js");
|
|
2243
2544
|
init_transformer();
|
|
2545
|
+
init_debug();
|
|
2244
2546
|
VUE_FILE_RE = /\.vue$/;
|
|
2245
2547
|
VUE_QUERY_RE = /\.vue\?vue&type=(script|template|style)(&index=\d+)?(&lang[.=]\w+)?/;
|
|
2548
|
+
debug2 = createDebugger("nasti:vue");
|
|
2246
2549
|
compiler = null;
|
|
2247
2550
|
}
|
|
2248
2551
|
});
|
|
@@ -2333,16 +2636,27 @@ window.__vite_plugin_react_preamble_installed__ = true;
|
|
|
2333
2636
|
// src/plugins/builtins.ts
|
|
2334
2637
|
function resolvePluginList(config, userPlugins, opts = {}) {
|
|
2335
2638
|
const isServe = config.command === "serve";
|
|
2639
|
+
let environmentOptions;
|
|
2640
|
+
if (opts.environmentName) {
|
|
2641
|
+
environmentOptions = config.environments[opts.environmentName];
|
|
2642
|
+
if (!environmentOptions) {
|
|
2643
|
+
throw new Error(
|
|
2644
|
+
`[nasti] unknown environment "${opts.environmentName}" \u2014 declare it in config.environments`
|
|
2645
|
+
);
|
|
2646
|
+
}
|
|
2647
|
+
}
|
|
2648
|
+
const pluginConfig = environmentOptions ? { ...config, resolve: environmentOptions.resolve, build: environmentOptions.build } : config;
|
|
2649
|
+
const consumer = opts.consumer ?? environmentOptions?.consumer;
|
|
2336
2650
|
return [
|
|
2337
2651
|
// vuePlugin 排最前(enforce: 'pre' 语义):.vue 先编译成 JS 再走后续管道
|
|
2338
|
-
...config.framework === "vue" ? [vuePlugin(
|
|
2339
|
-
resolvePlugin(
|
|
2340
|
-
cssPlugin(
|
|
2341
|
-
assetsPlugin(
|
|
2342
|
-
...isServe ? [htmlPlugin(
|
|
2652
|
+
...config.framework === "vue" ? [vuePlugin(pluginConfig, opts.environmentName ?? "client")] : [],
|
|
2653
|
+
resolvePlugin(pluginConfig),
|
|
2654
|
+
cssPlugin(pluginConfig, opts.cssEngine, consumer),
|
|
2655
|
+
assetsPlugin(pluginConfig),
|
|
2656
|
+
...isServe ? [htmlPlugin(pluginConfig)] : [],
|
|
2343
2657
|
...userPlugins,
|
|
2344
2658
|
// cssPostPlugin 最后(enforce: 'post' 语义):renderChunk 聚合抽取
|
|
2345
|
-
...!isServe && opts.cssEngine ? [cssPostPlugin(
|
|
2659
|
+
...!isServe && opts.cssEngine ? [cssPostPlugin(pluginConfig, opts.cssEngine)] : []
|
|
2346
2660
|
];
|
|
2347
2661
|
}
|
|
2348
2662
|
var init_builtins = __esm({
|
|
@@ -2439,17 +2753,23 @@ var init_plugin_container = __esm({
|
|
|
2439
2753
|
}
|
|
2440
2754
|
async transform(code, id) {
|
|
2441
2755
|
let currentCode = code;
|
|
2756
|
+
let lastResult;
|
|
2442
2757
|
for (const plugin of this.plugins) {
|
|
2443
2758
|
if (!plugin.transform) continue;
|
|
2444
2759
|
const result = await plugin.transform.call(this.ctx, currentCode, id);
|
|
2445
2760
|
if (result == null) continue;
|
|
2446
2761
|
if (typeof result === "string") {
|
|
2447
2762
|
currentCode = result;
|
|
2763
|
+
lastResult = void 0;
|
|
2448
2764
|
} else {
|
|
2449
2765
|
currentCode = result.code;
|
|
2766
|
+
lastResult = result;
|
|
2450
2767
|
}
|
|
2451
2768
|
}
|
|
2452
|
-
return currentCode === code ? null : {
|
|
2769
|
+
return currentCode === code ? null : {
|
|
2770
|
+
...lastResult,
|
|
2771
|
+
code: currentCode
|
|
2772
|
+
};
|
|
2453
2773
|
}
|
|
2454
2774
|
/** 完整的模块处理管道: resolveId → load → transform */
|
|
2455
2775
|
async processModule(source, importer) {
|
|
@@ -2472,17 +2792,39 @@ var init_plugin_container = __esm({
|
|
|
2472
2792
|
}
|
|
2473
2793
|
});
|
|
2474
2794
|
|
|
2795
|
+
// src/core/url.ts
|
|
2796
|
+
function removeTimestampQuery(url) {
|
|
2797
|
+
const hashIndex = url.indexOf("#");
|
|
2798
|
+
const hash = hashIndex >= 0 ? url.slice(hashIndex) : "";
|
|
2799
|
+
const withoutHash = hashIndex >= 0 ? url.slice(0, hashIndex) : url;
|
|
2800
|
+
const queryIndex = withoutHash.indexOf("?");
|
|
2801
|
+
if (queryIndex < 0) return url;
|
|
2802
|
+
const pathname = withoutHash.slice(0, queryIndex);
|
|
2803
|
+
const query = withoutHash.slice(queryIndex + 1).split("&").filter((part) => !/^t=\d+$/.test(part)).join("&");
|
|
2804
|
+
return pathname + (query ? `?${query}` : "") + hash;
|
|
2805
|
+
}
|
|
2806
|
+
var init_url = __esm({
|
|
2807
|
+
"src/core/url.ts"() {
|
|
2808
|
+
"use strict";
|
|
2809
|
+
}
|
|
2810
|
+
});
|
|
2811
|
+
|
|
2475
2812
|
// src/core/module-graph.ts
|
|
2476
2813
|
var ModuleGraph;
|
|
2477
2814
|
var init_module_graph = __esm({
|
|
2478
2815
|
"src/core/module-graph.ts"() {
|
|
2479
2816
|
"use strict";
|
|
2817
|
+
init_url();
|
|
2480
2818
|
ModuleGraph = class {
|
|
2819
|
+
environmentName;
|
|
2481
2820
|
urlToModuleMap = /* @__PURE__ */ new Map();
|
|
2482
2821
|
idToModuleMap = /* @__PURE__ */ new Map();
|
|
2483
2822
|
fileToModulesMap = /* @__PURE__ */ new Map();
|
|
2823
|
+
constructor(environmentName = "client") {
|
|
2824
|
+
this.environmentName = environmentName;
|
|
2825
|
+
}
|
|
2484
2826
|
getModuleByUrl(url) {
|
|
2485
|
-
return this.urlToModuleMap.get(url);
|
|
2827
|
+
return this.urlToModuleMap.get(removeTimestampQuery(url));
|
|
2486
2828
|
}
|
|
2487
2829
|
getModuleById(id) {
|
|
2488
2830
|
return this.idToModuleMap.get(id);
|
|
@@ -2491,10 +2833,11 @@ var init_module_graph = __esm({
|
|
|
2491
2833
|
return this.fileToModulesMap.get(file);
|
|
2492
2834
|
}
|
|
2493
2835
|
async ensureEntryFromUrl(url) {
|
|
2494
|
-
|
|
2836
|
+
const normalizedUrl = removeTimestampQuery(url);
|
|
2837
|
+
let mod = this.urlToModuleMap.get(normalizedUrl);
|
|
2495
2838
|
if (mod) return mod;
|
|
2496
|
-
mod = this.createModule(
|
|
2497
|
-
this.urlToModuleMap.set(
|
|
2839
|
+
mod = this.createModule(normalizedUrl);
|
|
2840
|
+
this.urlToModuleMap.set(normalizedUrl, mod);
|
|
2498
2841
|
return mod;
|
|
2499
2842
|
}
|
|
2500
2843
|
createModule(url, id) {
|
|
@@ -2508,7 +2851,9 @@ var init_module_graph = __esm({
|
|
|
2508
2851
|
acceptedHmrDeps: /* @__PURE__ */ new Set(),
|
|
2509
2852
|
transformResult: null,
|
|
2510
2853
|
lastHMRTimestamp: 0,
|
|
2511
|
-
|
|
2854
|
+
invalidationVersion: 0,
|
|
2855
|
+
isSelfAccepting: false,
|
|
2856
|
+
environment: this.environmentName
|
|
2512
2857
|
};
|
|
2513
2858
|
this.idToModuleMap.set(mod.id, mod);
|
|
2514
2859
|
return mod;
|
|
@@ -2550,10 +2895,64 @@ var init_module_graph = __esm({
|
|
|
2550
2895
|
}
|
|
2551
2896
|
}
|
|
2552
2897
|
}
|
|
2898
|
+
/**
|
|
2899
|
+
* 用一次转换得到的信息原子更新 import 与 HMR accept 关系。
|
|
2900
|
+
* 依赖节点会在真正被浏览器请求前预先创建,这样入口模块先转换时也能建立完整图。
|
|
2901
|
+
*/
|
|
2902
|
+
async updateModuleInfo(mod, importedUrls, acceptedUrls, isSelfAccepting, expectedInvalidationVersion) {
|
|
2903
|
+
const importedModules = await Promise.all(
|
|
2904
|
+
[...importedUrls].map((url) => this.ensureEntryFromUrl(url))
|
|
2905
|
+
);
|
|
2906
|
+
const acceptedModules = await Promise.all(
|
|
2907
|
+
[...acceptedUrls].map((url) => this.ensureEntryFromUrl(url))
|
|
2908
|
+
);
|
|
2909
|
+
if (expectedInvalidationVersion !== void 0 && mod.invalidationVersion !== expectedInvalidationVersion) {
|
|
2910
|
+
return null;
|
|
2911
|
+
}
|
|
2912
|
+
const previousImports = new Set(mod.importedModules);
|
|
2913
|
+
for (const imported of previousImports) {
|
|
2914
|
+
imported.importers.delete(mod);
|
|
2915
|
+
}
|
|
2916
|
+
mod.importedModules.clear();
|
|
2917
|
+
mod.acceptedHmrDeps.clear();
|
|
2918
|
+
for (const imported of importedModules) {
|
|
2919
|
+
mod.importedModules.add(imported);
|
|
2920
|
+
imported.importers.add(mod);
|
|
2921
|
+
}
|
|
2922
|
+
for (const accepted of acceptedModules) {
|
|
2923
|
+
mod.acceptedHmrDeps.add(accepted);
|
|
2924
|
+
}
|
|
2925
|
+
mod.isSelfAccepting = isSelfAccepting;
|
|
2926
|
+
const pruned = /* @__PURE__ */ new Set();
|
|
2927
|
+
for (const imported of previousImports) {
|
|
2928
|
+
if (!mod.importedModules.has(imported) && imported.importers.size === 0) {
|
|
2929
|
+
pruned.add(imported);
|
|
2930
|
+
}
|
|
2931
|
+
}
|
|
2932
|
+
return pruned;
|
|
2933
|
+
}
|
|
2553
2934
|
/** 使模块的转换缓存失效 */
|
|
2554
|
-
invalidateModule(mod) {
|
|
2935
|
+
invalidateModule(mod, timestamp = Date.now()) {
|
|
2555
2936
|
mod.transformResult = null;
|
|
2556
|
-
mod.lastHMRTimestamp =
|
|
2937
|
+
mod.lastHMRTimestamp = timestamp;
|
|
2938
|
+
mod.invalidationVersion++;
|
|
2939
|
+
}
|
|
2940
|
+
/**
|
|
2941
|
+
* 仅失效到 HMR 边界:显式接受依赖的模块本身不会重执行;自接受模块需要失效,
|
|
2942
|
+
* 但不再继续影响其 importer。这样既能传播依赖时间戳,也不会隐式重复副作用。
|
|
2943
|
+
*/
|
|
2944
|
+
invalidateModuleAndImporters(mod, timestamp = Date.now(), seen = /* @__PURE__ */ new Set()) {
|
|
2945
|
+
if (seen.has(mod)) return;
|
|
2946
|
+
seen.add(mod);
|
|
2947
|
+
this.invalidateModule(mod, timestamp);
|
|
2948
|
+
for (const importer of mod.importers) {
|
|
2949
|
+
if (importer.acceptedHmrDeps.has(mod)) continue;
|
|
2950
|
+
if (importer.isSelfAccepting) {
|
|
2951
|
+
this.invalidateModule(importer, timestamp);
|
|
2952
|
+
continue;
|
|
2953
|
+
}
|
|
2954
|
+
this.invalidateModuleAndImporters(importer, timestamp, seen);
|
|
2955
|
+
}
|
|
2557
2956
|
}
|
|
2558
2957
|
/** 使所有模块缓存失效 */
|
|
2559
2958
|
invalidateAll() {
|
|
@@ -2564,34 +2963,32 @@ var init_module_graph = __esm({
|
|
|
2564
2963
|
/** 获取 HMR 传播边界 - 从变更模块向上遍历找到接受更新的边界 */
|
|
2565
2964
|
getHmrBoundaries(mod) {
|
|
2566
2965
|
const boundaries = [];
|
|
2567
|
-
const
|
|
2568
|
-
const
|
|
2569
|
-
if (
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
boundaries.push({ boundary
|
|
2573
|
-
return true;
|
|
2966
|
+
const traversed = /* @__PURE__ */ new Set();
|
|
2967
|
+
const addBoundary = (boundary, acceptedVia) => {
|
|
2968
|
+
if (!boundaries.some(
|
|
2969
|
+
(item) => item.boundary === boundary && item.acceptedVia === acceptedVia
|
|
2970
|
+
)) {
|
|
2971
|
+
boundaries.push({ boundary, acceptedVia });
|
|
2574
2972
|
}
|
|
2575
|
-
|
|
2576
|
-
|
|
2973
|
+
};
|
|
2974
|
+
const propagate = (node) => {
|
|
2975
|
+
if (traversed.has(node)) return true;
|
|
2976
|
+
traversed.add(node);
|
|
2977
|
+
if (node.isSelfAccepting) {
|
|
2978
|
+
addBoundary(node, node);
|
|
2577
2979
|
return true;
|
|
2578
2980
|
}
|
|
2579
2981
|
if (node.importers.size === 0) return false;
|
|
2580
2982
|
for (const importer of node.importers) {
|
|
2581
|
-
if (
|
|
2983
|
+
if (importer.acceptedHmrDeps.has(node)) {
|
|
2984
|
+
addBoundary(importer, node);
|
|
2985
|
+
continue;
|
|
2986
|
+
}
|
|
2987
|
+
if (!propagate(importer)) return false;
|
|
2582
2988
|
}
|
|
2583
2989
|
return true;
|
|
2584
2990
|
};
|
|
2585
|
-
|
|
2586
|
-
boundaries.push({ boundary: mod, acceptedVia: mod });
|
|
2587
|
-
return boundaries;
|
|
2588
|
-
}
|
|
2589
|
-
for (const importer of mod.importers) {
|
|
2590
|
-
if (!propagate(importer, mod)) {
|
|
2591
|
-
return [];
|
|
2592
|
-
}
|
|
2593
|
-
}
|
|
2594
|
-
return boundaries;
|
|
2991
|
+
return propagate(mod) ? boundaries : [];
|
|
2595
2992
|
}
|
|
2596
2993
|
};
|
|
2597
2994
|
}
|
|
@@ -2614,12 +3011,12 @@ function createNoopHotChannel() {
|
|
|
2614
3011
|
}
|
|
2615
3012
|
};
|
|
2616
3013
|
}
|
|
2617
|
-
function createWsHotChannel(ws) {
|
|
3014
|
+
function createWsHotChannel(ws, environmentName = "client") {
|
|
2618
3015
|
const listeners = /* @__PURE__ */ new Map();
|
|
2619
3016
|
let invokeHandlers;
|
|
2620
3017
|
return {
|
|
2621
3018
|
send(payload) {
|
|
2622
|
-
ws.send(payload);
|
|
3019
|
+
ws.send({ ...payload, environment: payload.environment ?? environmentName });
|
|
2623
3020
|
},
|
|
2624
3021
|
on(event, listener) {
|
|
2625
3022
|
let set = listeners.get(event);
|
|
@@ -2631,8 +3028,8 @@ function createWsHotChannel(ws) {
|
|
|
2631
3028
|
},
|
|
2632
3029
|
listen() {
|
|
2633
3030
|
},
|
|
3031
|
+
// 多个 environment 共享底层 WebSocket server;它由 DevServer.close() 统一关闭。
|
|
2634
3032
|
close() {
|
|
2635
|
-
ws.close();
|
|
2636
3033
|
},
|
|
2637
3034
|
setInvokeHandler(handlers) {
|
|
2638
3035
|
invokeHandlers = handlers;
|
|
@@ -2661,7 +3058,7 @@ function resolveEnvironmentPlugins(environment, plugins) {
|
|
|
2661
3058
|
}
|
|
2662
3059
|
});
|
|
2663
3060
|
}
|
|
2664
|
-
var
|
|
3061
|
+
var debug3, NastiEnvironment;
|
|
2665
3062
|
var init_environment = __esm({
|
|
2666
3063
|
"src/core/environment.ts"() {
|
|
2667
3064
|
"use strict";
|
|
@@ -2670,7 +3067,7 @@ var init_environment = __esm({
|
|
|
2670
3067
|
init_hot_channel();
|
|
2671
3068
|
init_debug();
|
|
2672
3069
|
init_plugin_api();
|
|
2673
|
-
|
|
3070
|
+
debug3 = createDebugger("nasti:environment");
|
|
2674
3071
|
NastiEnvironment = class {
|
|
2675
3072
|
name;
|
|
2676
3073
|
consumer;
|
|
@@ -2687,6 +3084,10 @@ var init_environment = __esm({
|
|
|
2687
3084
|
moduleGraph;
|
|
2688
3085
|
candidatePlugins;
|
|
2689
3086
|
pluginApi;
|
|
3087
|
+
buildMetadata = {};
|
|
3088
|
+
cssModules = /* @__PURE__ */ new Map();
|
|
3089
|
+
assetModules = /* @__PURE__ */ new Map();
|
|
3090
|
+
transformRequestHandler;
|
|
2690
3091
|
initialized = false;
|
|
2691
3092
|
constructor(name, config, init = {}) {
|
|
2692
3093
|
const options = config.environments[name];
|
|
@@ -2701,7 +3102,7 @@ var init_environment = __esm({
|
|
|
2701
3102
|
this.config = config;
|
|
2702
3103
|
this.options = options;
|
|
2703
3104
|
this.hot = init.hot ?? createNoopHotChannel();
|
|
2704
|
-
this.moduleGraph = new ModuleGraph();
|
|
3105
|
+
this.moduleGraph = new ModuleGraph(name);
|
|
2705
3106
|
this.candidatePlugins = init.plugins ?? config.plugins;
|
|
2706
3107
|
this.pluginApi = init.pluginApi ?? getPluginApi(config);
|
|
2707
3108
|
}
|
|
@@ -2731,9 +3132,9 @@ var init_environment = __esm({
|
|
|
2731
3132
|
);
|
|
2732
3133
|
}
|
|
2733
3134
|
this.driver = claimed[0].driver;
|
|
2734
|
-
|
|
3135
|
+
debug3?.(`env "${this.name}" uses driver "${this.driver.name}"`);
|
|
2735
3136
|
}
|
|
2736
|
-
|
|
3137
|
+
debug3?.(`env "${this.name}" initialized (${this.plugins.length} plugins)`);
|
|
2737
3138
|
}
|
|
2738
3139
|
getDriverContext() {
|
|
2739
3140
|
return {
|
|
@@ -2743,6 +3144,53 @@ var init_environment = __esm({
|
|
|
2743
3144
|
logger: this.config.logger
|
|
2744
3145
|
};
|
|
2745
3146
|
}
|
|
3147
|
+
configureDevPipeline(transformRequest2) {
|
|
3148
|
+
this.transformRequestHandler = transformRequest2;
|
|
3149
|
+
}
|
|
3150
|
+
async transformRequest(url) {
|
|
3151
|
+
if (!this.transformRequestHandler) {
|
|
3152
|
+
throw new Error(
|
|
3153
|
+
`[nasti] environment "${this.name}" does not have an initialized dev transform pipeline`
|
|
3154
|
+
);
|
|
3155
|
+
}
|
|
3156
|
+
return this.transformRequestHandler(url);
|
|
3157
|
+
}
|
|
3158
|
+
setCssModule(module2) {
|
|
3159
|
+
this.cssModules.set(module2.id, { ...module2 });
|
|
3160
|
+
}
|
|
3161
|
+
getCssModule(id) {
|
|
3162
|
+
const module2 = this.cssModules.get(id);
|
|
3163
|
+
return module2 ? { ...module2 } : void 0;
|
|
3164
|
+
}
|
|
3165
|
+
getCssModules() {
|
|
3166
|
+
return Object.freeze(
|
|
3167
|
+
Object.fromEntries(
|
|
3168
|
+
[...this.cssModules].map(([id, module2]) => [id, { ...module2 }])
|
|
3169
|
+
)
|
|
3170
|
+
);
|
|
3171
|
+
}
|
|
3172
|
+
setAssetModule(id, fileName) {
|
|
3173
|
+
this.assetModules.set(id, fileName);
|
|
3174
|
+
}
|
|
3175
|
+
getAssetModules() {
|
|
3176
|
+
return Object.freeze(Object.fromEntries(this.assetModules));
|
|
3177
|
+
}
|
|
3178
|
+
setBuildMetadata(metadata) {
|
|
3179
|
+
const { entries: currentEntries, ...currentMetadata } = this.buildMetadata;
|
|
3180
|
+
const { entries, ...nextMetadata } = metadata;
|
|
3181
|
+
this.buildMetadata = {
|
|
3182
|
+
...currentMetadata,
|
|
3183
|
+
...nextMetadata,
|
|
3184
|
+
...currentEntries || entries ? { entries: { ...currentEntries, ...entries } } : {}
|
|
3185
|
+
};
|
|
3186
|
+
}
|
|
3187
|
+
getBuildMetadata() {
|
|
3188
|
+
const { entries, ...metadata } = this.buildMetadata;
|
|
3189
|
+
return {
|
|
3190
|
+
...metadata,
|
|
3191
|
+
...entries ? { entries: { ...entries } } : {}
|
|
3192
|
+
};
|
|
3193
|
+
}
|
|
2746
3194
|
async close() {
|
|
2747
3195
|
try {
|
|
2748
3196
|
await this.driver?.close?.(this.getDriverContext());
|
|
@@ -2837,7 +3285,7 @@ async function tryNativeReporterPlugin(config, logger) {
|
|
|
2837
3285
|
logInfo: (msg) => logger.info(msg)
|
|
2838
3286
|
});
|
|
2839
3287
|
} catch (err) {
|
|
2840
|
-
|
|
3288
|
+
debug4?.(`native viteReporterPlugin unavailable, falling back to JS table: ${err}`);
|
|
2841
3289
|
return null;
|
|
2842
3290
|
}
|
|
2843
3291
|
}
|
|
@@ -2892,7 +3340,7 @@ function warnLargeChunks(output, config, logger) {
|
|
|
2892
3340
|
)
|
|
2893
3341
|
);
|
|
2894
3342
|
}
|
|
2895
|
-
var import_node_path8, import_node_zlib, import_picocolors3,
|
|
3343
|
+
var import_node_path8, import_node_zlib, import_picocolors3, debug4, numberFormatter;
|
|
2896
3344
|
var init_reporter = __esm({
|
|
2897
3345
|
"src/build/reporter.ts"() {
|
|
2898
3346
|
"use strict";
|
|
@@ -2900,7 +3348,7 @@ var init_reporter = __esm({
|
|
|
2900
3348
|
import_node_zlib = require("zlib");
|
|
2901
3349
|
import_picocolors3 = __toESM(require("picocolors"), 1);
|
|
2902
3350
|
init_debug();
|
|
2903
|
-
|
|
3351
|
+
debug4 = createDebugger("nasti:reporter");
|
|
2904
3352
|
numberFormatter = new Intl.NumberFormat("en", {
|
|
2905
3353
|
maximumFractionDigits: 2,
|
|
2906
3354
|
minimumFractionDigits: 2
|
|
@@ -2908,6 +3356,156 @@ var init_reporter = __esm({
|
|
|
2908
3356
|
}
|
|
2909
3357
|
});
|
|
2910
3358
|
|
|
3359
|
+
// src/core/build-app-context.ts
|
|
3360
|
+
function createBuildAppContext(config, results) {
|
|
3361
|
+
const output = [];
|
|
3362
|
+
const emitted = /* @__PURE__ */ new Set();
|
|
3363
|
+
const outDir = import_node_path9.default.resolve(config.root, config.build.outDir);
|
|
3364
|
+
let environmentArtifacts;
|
|
3365
|
+
return {
|
|
3366
|
+
config,
|
|
3367
|
+
results,
|
|
3368
|
+
get output() {
|
|
3369
|
+
return Object.freeze([...output]);
|
|
3370
|
+
},
|
|
3371
|
+
getResult(environmentName) {
|
|
3372
|
+
return results[environmentName];
|
|
3373
|
+
},
|
|
3374
|
+
getArtifact(environmentName, fileName) {
|
|
3375
|
+
const normalized = normalizeEnvironmentFileName(fileName);
|
|
3376
|
+
return results[environmentName]?.output.find(
|
|
3377
|
+
(artifact) => normalizeEnvironmentFileName(artifact.fileName) === normalized
|
|
3378
|
+
);
|
|
3379
|
+
},
|
|
3380
|
+
getEntry(environmentName, entryName) {
|
|
3381
|
+
const result = results[environmentName];
|
|
3382
|
+
const fileName = result?.entries?.[entryName];
|
|
3383
|
+
if (!fileName) return void 0;
|
|
3384
|
+
return result.output.find(
|
|
3385
|
+
(artifact) => normalizeEnvironmentFileName(artifact.fileName) === normalizeEnvironmentFileName(fileName)
|
|
3386
|
+
);
|
|
3387
|
+
},
|
|
3388
|
+
getManifest(environmentName) {
|
|
3389
|
+
return results[environmentName]?.manifest;
|
|
3390
|
+
},
|
|
3391
|
+
getChunk(environmentName, fileName) {
|
|
3392
|
+
const normalized = normalizeEnvironmentFileName(fileName);
|
|
3393
|
+
return results[environmentName]?.chunks?.[normalized];
|
|
3394
|
+
},
|
|
3395
|
+
getCss(environmentName) {
|
|
3396
|
+
return results[environmentName]?.css;
|
|
3397
|
+
},
|
|
3398
|
+
getSourceMap(environmentName, fileName) {
|
|
3399
|
+
const normalized = normalizeEnvironmentFileName(fileName);
|
|
3400
|
+
return results[environmentName]?.sourceMaps?.[normalized];
|
|
3401
|
+
},
|
|
3402
|
+
resolvePublicPath(environmentName, fileName) {
|
|
3403
|
+
const result = results[environmentName];
|
|
3404
|
+
if (!result) return void 0;
|
|
3405
|
+
const normalized = normalizeEnvironmentFileName(fileName);
|
|
3406
|
+
const base = result.publicPath ?? config.base;
|
|
3407
|
+
return joinPublicPath(base, normalized);
|
|
3408
|
+
},
|
|
3409
|
+
emitFile(file) {
|
|
3410
|
+
const fileName = normalizeAppFileName(file.fileName);
|
|
3411
|
+
const collisionKey = artifactCollisionKey(fileName);
|
|
3412
|
+
if (emitted.has(collisionKey)) {
|
|
3413
|
+
throw new Error(`[nasti] app artifact already emitted: ${fileName}`);
|
|
3414
|
+
}
|
|
3415
|
+
environmentArtifacts ??= collectEnvironmentArtifacts(config, results, outDir);
|
|
3416
|
+
if (environmentArtifacts.has(collisionKey)) {
|
|
3417
|
+
throw new Error(`[nasti] app artifact conflicts with environment output: ${fileName}`);
|
|
3418
|
+
}
|
|
3419
|
+
const target = import_node_path9.default.resolve(outDir, ...fileName.split("/"));
|
|
3420
|
+
const relative = import_node_path9.default.relative(outDir, target);
|
|
3421
|
+
if (relative.startsWith("..") || import_node_path9.default.isAbsolute(relative)) {
|
|
3422
|
+
throw new Error(`[nasti] app artifact must stay inside build.outDir: ${file.fileName}`);
|
|
3423
|
+
}
|
|
3424
|
+
assertNoSymlinkComponents(outDir, fileName);
|
|
3425
|
+
import_node_fs6.default.mkdirSync(import_node_path9.default.dirname(target), { recursive: true });
|
|
3426
|
+
import_node_fs6.default.writeFileSync(target, file.source);
|
|
3427
|
+
const artifact = {
|
|
3428
|
+
...file,
|
|
3429
|
+
fileName,
|
|
3430
|
+
type: "asset"
|
|
3431
|
+
};
|
|
3432
|
+
emitted.add(collisionKey);
|
|
3433
|
+
output.push(artifact);
|
|
3434
|
+
return fileName;
|
|
3435
|
+
}
|
|
3436
|
+
};
|
|
3437
|
+
}
|
|
3438
|
+
function joinPublicPath(base, fileName) {
|
|
3439
|
+
return `${base.endsWith("/") ? base : `${base}/`}${fileName.replace(/^\//, "")}`;
|
|
3440
|
+
}
|
|
3441
|
+
function normalizeEnvironmentFileName(fileName) {
|
|
3442
|
+
return import_node_path9.default.posix.normalize(fileName.replace(/\\/g, "/").replace(/^\.\//, ""));
|
|
3443
|
+
}
|
|
3444
|
+
function isInvalidEnvironmentFileName(fileName) {
|
|
3445
|
+
return !fileName || fileName === "." || fileName === ".." || fileName.startsWith("../") || import_node_path9.default.posix.isAbsolute(fileName) || /^[A-Za-z]:\//.test(fileName);
|
|
3446
|
+
}
|
|
3447
|
+
function normalizeAppFileName(fileName) {
|
|
3448
|
+
const normalized = normalizeEnvironmentFileName(fileName);
|
|
3449
|
+
if (isInvalidEnvironmentFileName(normalized)) {
|
|
3450
|
+
throw new Error(`[nasti] invalid app artifact fileName: ${fileName}`);
|
|
3451
|
+
}
|
|
3452
|
+
return normalized;
|
|
3453
|
+
}
|
|
3454
|
+
function artifactCollisionKey(fileName) {
|
|
3455
|
+
return normalizeEnvironmentFileName(fileName).toLowerCase();
|
|
3456
|
+
}
|
|
3457
|
+
function collectEnvironmentArtifacts(config, results, appOutDir) {
|
|
3458
|
+
const occupied = /* @__PURE__ */ new Set();
|
|
3459
|
+
for (const [environmentName, result] of Object.entries(results)) {
|
|
3460
|
+
const environment = config.environments[environmentName];
|
|
3461
|
+
if (!environment) continue;
|
|
3462
|
+
const environmentOutDir = import_node_path9.default.resolve(config.root, environment.build.outDir);
|
|
3463
|
+
for (const artifact of result.output) {
|
|
3464
|
+
const artifactPath = import_node_path9.default.resolve(
|
|
3465
|
+
environmentOutDir,
|
|
3466
|
+
...normalizeEnvironmentFileName(artifact.fileName).split("/")
|
|
3467
|
+
);
|
|
3468
|
+
const relative = import_node_path9.default.relative(appOutDir, artifactPath);
|
|
3469
|
+
if (!relative.startsWith("..") && !import_node_path9.default.isAbsolute(relative)) {
|
|
3470
|
+
occupied.add(artifactCollisionKey(relative));
|
|
3471
|
+
}
|
|
3472
|
+
}
|
|
3473
|
+
}
|
|
3474
|
+
return occupied;
|
|
3475
|
+
}
|
|
3476
|
+
function assertNoSymlinkComponents(outDir, fileName) {
|
|
3477
|
+
let current = outDir;
|
|
3478
|
+
for (const segment of fileName.split("/")) {
|
|
3479
|
+
current = import_node_path9.default.join(current, segment);
|
|
3480
|
+
let stats;
|
|
3481
|
+
try {
|
|
3482
|
+
stats = import_node_fs6.default.lstatSync(current);
|
|
3483
|
+
} catch (error) {
|
|
3484
|
+
if (error.code === "ENOENT") continue;
|
|
3485
|
+
throw error;
|
|
3486
|
+
}
|
|
3487
|
+
if (stats.isSymbolicLink()) {
|
|
3488
|
+
throw new Error(`[nasti] app artifact path cannot traverse a symlink: ${fileName}`);
|
|
3489
|
+
}
|
|
3490
|
+
}
|
|
3491
|
+
}
|
|
3492
|
+
function inferEnvironmentEntries(output) {
|
|
3493
|
+
const entries = {};
|
|
3494
|
+
for (const artifact of output) {
|
|
3495
|
+
if (artifact.type !== "chunk" || !artifact.isEntry || !artifact.name) continue;
|
|
3496
|
+
entries[artifact.name] = normalizeEnvironmentFileName(artifact.fileName);
|
|
3497
|
+
}
|
|
3498
|
+
return Object.keys(entries).length > 0 ? entries : void 0;
|
|
3499
|
+
}
|
|
3500
|
+
var import_node_fs6, import_node_path9;
|
|
3501
|
+
var init_build_app_context = __esm({
|
|
3502
|
+
"src/core/build-app-context.ts"() {
|
|
3503
|
+
"use strict";
|
|
3504
|
+
import_node_fs6 = __toESM(require("fs"), 1);
|
|
3505
|
+
import_node_path9 = __toESM(require("path"), 1);
|
|
3506
|
+
}
|
|
3507
|
+
});
|
|
3508
|
+
|
|
2911
3509
|
// src/build/index.ts
|
|
2912
3510
|
var build_exports = {};
|
|
2913
3511
|
__export(build_exports, {
|
|
@@ -2921,9 +3519,14 @@ function getRolldownOptions(environment, entryPoints, rolldownPlugins) {
|
|
|
2921
3519
|
const config = environment.config;
|
|
2922
3520
|
const envOptions = environment.options;
|
|
2923
3521
|
const isServer = environment.consumer === "server";
|
|
2924
|
-
const outDir =
|
|
3522
|
+
const outDir = import_node_path10.default.resolve(config.root, envOptions.build.outDir);
|
|
2925
3523
|
const assetsDir = envOptions.build.assetsDir;
|
|
2926
|
-
const {
|
|
3524
|
+
const {
|
|
3525
|
+
output: userOutput,
|
|
3526
|
+
transform: userTransform,
|
|
3527
|
+
resolve: userResolve,
|
|
3528
|
+
...restInputOptions
|
|
3529
|
+
} = envOptions.build.rolldownOptions;
|
|
2927
3530
|
const vueDefine = config.framework === "vue" ? {
|
|
2928
3531
|
__VUE_OPTIONS_API__: "true",
|
|
2929
3532
|
__VUE_PROD_DEVTOOLS__: "false",
|
|
@@ -2935,27 +3538,34 @@ function getRolldownOptions(environment, entryPoints, rolldownPlugins) {
|
|
|
2935
3538
|
const inputOptions = {
|
|
2936
3539
|
...restInputOptions,
|
|
2937
3540
|
input: entryPoints,
|
|
2938
|
-
transform: {
|
|
3541
|
+
transform: {
|
|
3542
|
+
...userTransform,
|
|
3543
|
+
target: userTransform?.target ?? envOptions.build.target,
|
|
3544
|
+
define: mergedDefine
|
|
3545
|
+
},
|
|
2939
3546
|
plugins: rolldownPlugins,
|
|
3547
|
+
// client/server consumer 都必须使用当前环境的 conditions/mainFields;Lynx
|
|
3548
|
+
// BG/MT 通常同为 client consumer,但仍可能声明不同的运行时条件。
|
|
3549
|
+
resolve: {
|
|
3550
|
+
...userResolve ?? {},
|
|
3551
|
+
// Environment API 是条件解析的唯一高层入口,优先于继承来的底层选项。
|
|
3552
|
+
conditionNames: envOptions.resolve.conditions,
|
|
3553
|
+
mainFields: envOptions.resolve.mainFields
|
|
3554
|
+
},
|
|
2940
3555
|
...isServer ? {
|
|
2941
3556
|
platform: restInputOptions.platform ?? "node",
|
|
2942
|
-
resolve: {
|
|
2943
|
-
conditionNames: envOptions.resolve.conditions,
|
|
2944
|
-
mainFields: envOptions.resolve.mainFields,
|
|
2945
|
-
...restInputOptions.resolve
|
|
2946
|
-
},
|
|
2947
3557
|
// server 产物:node 内建恒外部化;bare specifier 默认外部化
|
|
2948
3558
|
//(同 Vite ssr.external 默认 —— 依赖由 node_modules 运行时解析),
|
|
2949
3559
|
// 相对/绝对/虚拟模块照常打包。需要内联依赖时经 rolldownOptions.external 覆盖。
|
|
2950
3560
|
external: restInputOptions.external ?? ((id) => {
|
|
2951
3561
|
if (NODE_BUILTINS.has(id)) return true;
|
|
2952
|
-
return !id.startsWith(".") && !
|
|
3562
|
+
return !id.startsWith(".") && !import_node_path10.default.isAbsolute(id) && !id.startsWith("\0");
|
|
2953
3563
|
})
|
|
2954
3564
|
} : {}
|
|
2955
3565
|
};
|
|
2956
3566
|
const outputOptions = isServer ? {
|
|
2957
3567
|
format: "esm",
|
|
2958
|
-
sourcemap:
|
|
3568
|
+
sourcemap: envOptions.build.sourcemap,
|
|
2959
3569
|
minify: !!envOptions.build.minify,
|
|
2960
3570
|
entryFileNames: "[name].js",
|
|
2961
3571
|
chunkFileNames: "chunks/[name]-[hash].js",
|
|
@@ -2964,7 +3574,7 @@ function getRolldownOptions(environment, entryPoints, rolldownPlugins) {
|
|
|
2964
3574
|
dir: outDir
|
|
2965
3575
|
} : {
|
|
2966
3576
|
format: "esm",
|
|
2967
|
-
sourcemap:
|
|
3577
|
+
sourcemap: envOptions.build.sourcemap,
|
|
2968
3578
|
minify: !!envOptions.build.minify,
|
|
2969
3579
|
entryFileNames: `${assetsDir}/[name].[hash].js`,
|
|
2970
3580
|
chunkFileNames: `${assetsDir}/[name].[hash].js`,
|
|
@@ -2976,27 +3586,177 @@ function getRolldownOptions(environment, entryPoints, rolldownPlugins) {
|
|
|
2976
3586
|
};
|
|
2977
3587
|
return { inputOptions, outputOptions, outDir };
|
|
2978
3588
|
}
|
|
2979
|
-
function toRolldownPlugins(plugins) {
|
|
3589
|
+
function toRolldownPlugins(plugins, environment) {
|
|
3590
|
+
const wrap = (hook) => {
|
|
3591
|
+
if (!hook) return hook;
|
|
3592
|
+
return function(...args) {
|
|
3593
|
+
return hook.apply(attachEnvironment(this, environment), args);
|
|
3594
|
+
};
|
|
3595
|
+
};
|
|
2980
3596
|
return plugins.map((p) => ({
|
|
2981
3597
|
name: p.name,
|
|
2982
|
-
resolveId: p.resolveId,
|
|
2983
|
-
load: p.load,
|
|
2984
|
-
transform: p.transform,
|
|
2985
|
-
buildStart: p.buildStart,
|
|
2986
|
-
buildEnd: p.buildEnd,
|
|
3598
|
+
resolveId: wrap(p.resolveId),
|
|
3599
|
+
load: wrap(p.load),
|
|
3600
|
+
transform: wrap(p.transform),
|
|
3601
|
+
buildStart: wrap(p.buildStart),
|
|
3602
|
+
buildEnd: wrap(p.buildEnd),
|
|
2987
3603
|
// closeBundle 在 bundle.close() 时触发 —— PWA manifest/SW 等终态产物依赖
|
|
2988
|
-
closeBundle: p.closeBundle,
|
|
2989
|
-
renderChunk: p.renderChunk,
|
|
2990
|
-
augmentChunkHash: p.augmentChunkHash,
|
|
2991
|
-
generateBundle: p.generateBundle
|
|
3604
|
+
closeBundle: wrap(p.closeBundle),
|
|
3605
|
+
renderChunk: wrap(p.renderChunk),
|
|
3606
|
+
augmentChunkHash: wrap(p.augmentChunkHash),
|
|
3607
|
+
generateBundle: wrap(p.generateBundle)
|
|
2992
3608
|
}));
|
|
2993
3609
|
}
|
|
3610
|
+
function attachEnvironment(context, environment) {
|
|
3611
|
+
if (context?.environment === environment) return context;
|
|
3612
|
+
try {
|
|
3613
|
+
Object.defineProperty(context, "environment", {
|
|
3614
|
+
configurable: true,
|
|
3615
|
+
enumerable: false,
|
|
3616
|
+
writable: false,
|
|
3617
|
+
value: environment
|
|
3618
|
+
});
|
|
3619
|
+
return context;
|
|
3620
|
+
} catch {
|
|
3621
|
+
return new Proxy(context, {
|
|
3622
|
+
get(target, property) {
|
|
3623
|
+
if (property === "environment") return environment;
|
|
3624
|
+
const value = Reflect.get(target, property, target);
|
|
3625
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
3626
|
+
},
|
|
3627
|
+
set(target, property, value) {
|
|
3628
|
+
return Reflect.set(target, property, value, target);
|
|
3629
|
+
}
|
|
3630
|
+
});
|
|
3631
|
+
}
|
|
3632
|
+
}
|
|
3633
|
+
function finalizeEnvironmentResult(environment, result) {
|
|
3634
|
+
const metadata = environment.getBuildMetadata();
|
|
3635
|
+
const inferredEntries = inferEnvironmentEntries(result.output);
|
|
3636
|
+
const entries = {
|
|
3637
|
+
...inferredEntries,
|
|
3638
|
+
...metadata.entries,
|
|
3639
|
+
...result.entries
|
|
3640
|
+
};
|
|
3641
|
+
const normalizedEntries = Object.fromEntries(
|
|
3642
|
+
Object.entries(entries).map(([name, fileName]) => {
|
|
3643
|
+
const normalized = normalizeEnvironmentFileName(fileName);
|
|
3644
|
+
if (isInvalidEnvironmentFileName(normalized)) {
|
|
3645
|
+
throw new Error(
|
|
3646
|
+
`[nasti] environment "${environment.name}" returned invalid entry "${name}": ${fileName}`
|
|
3647
|
+
);
|
|
3648
|
+
}
|
|
3649
|
+
return [name, normalized];
|
|
3650
|
+
})
|
|
3651
|
+
);
|
|
3652
|
+
const inferredMetadata = inferOutputMetadata(environment, result.output);
|
|
3653
|
+
return {
|
|
3654
|
+
publicPath: environment.config.base,
|
|
3655
|
+
...inferredMetadata,
|
|
3656
|
+
...metadata,
|
|
3657
|
+
...result,
|
|
3658
|
+
output: result.output,
|
|
3659
|
+
chunks: {
|
|
3660
|
+
...inferredMetadata.chunks,
|
|
3661
|
+
...metadata.chunks,
|
|
3662
|
+
...result.chunks
|
|
3663
|
+
},
|
|
3664
|
+
assets: {
|
|
3665
|
+
...inferredMetadata.assets,
|
|
3666
|
+
...metadata.assets,
|
|
3667
|
+
...result.assets
|
|
3668
|
+
},
|
|
3669
|
+
sourceMaps: {
|
|
3670
|
+
...inferredMetadata.sourceMaps,
|
|
3671
|
+
...metadata.sourceMaps,
|
|
3672
|
+
...result.sourceMaps
|
|
3673
|
+
},
|
|
3674
|
+
...Object.keys(normalizedEntries).length > 0 ? { entries: normalizedEntries } : {}
|
|
3675
|
+
};
|
|
3676
|
+
}
|
|
3677
|
+
function inferOutputMetadata(environment, output) {
|
|
3678
|
+
const chunks = {};
|
|
3679
|
+
const assets = {};
|
|
3680
|
+
const sourceMaps = {};
|
|
3681
|
+
const cssChunks = environment.getBuildMetadata().css?.chunks ?? {};
|
|
3682
|
+
const assetModules = environment.getAssetModules();
|
|
3683
|
+
const publicPath = environment.config.base;
|
|
3684
|
+
for (const artifact of output) {
|
|
3685
|
+
const fileName = normalizeEnvironmentFileName(artifact.fileName);
|
|
3686
|
+
if (artifact.map != null) sourceMaps[fileName] = artifact.map;
|
|
3687
|
+
if (artifact.type === "chunk") {
|
|
3688
|
+
const moduleIds = [...artifact.moduleIds ?? []];
|
|
3689
|
+
chunks[fileName] = {
|
|
3690
|
+
fileName,
|
|
3691
|
+
name: artifact.name ?? fileName,
|
|
3692
|
+
isEntry: !!artifact.isEntry,
|
|
3693
|
+
isDynamicEntry: !!artifact.isDynamicEntry,
|
|
3694
|
+
imports: [...artifact.imports ?? []],
|
|
3695
|
+
dynamicImports: [...artifact.dynamicImports ?? []],
|
|
3696
|
+
moduleIds,
|
|
3697
|
+
css: [...cssChunks[fileName]?.cssFileNames ?? []],
|
|
3698
|
+
assets: [
|
|
3699
|
+
...new Set(
|
|
3700
|
+
moduleIds.map((id) => assetModules[id]).filter((asset) => !!asset)
|
|
3701
|
+
)
|
|
3702
|
+
]
|
|
3703
|
+
};
|
|
3704
|
+
} else if (artifact.type === "asset") {
|
|
3705
|
+
assets[fileName] = {
|
|
3706
|
+
fileName,
|
|
3707
|
+
names: [...artifact.names ?? (artifact.name ? [artifact.name] : [])],
|
|
3708
|
+
publicPath: joinPublicPath(publicPath, fileName)
|
|
3709
|
+
};
|
|
3710
|
+
}
|
|
3711
|
+
}
|
|
3712
|
+
return { chunks, assets, sourceMaps };
|
|
3713
|
+
}
|
|
3714
|
+
function prepareBuildOutputDirectories(config, buildableNames) {
|
|
3715
|
+
const directories = /* @__PURE__ */ new Set();
|
|
3716
|
+
const protectedPaths = /* @__PURE__ */ new Set();
|
|
3717
|
+
const clientIsBuilt = buildableNames.includes("client");
|
|
3718
|
+
if (!clientIsBuilt && config.build.emptyOutDir) {
|
|
3719
|
+
directories.add(import_node_path10.default.resolve(config.root, config.build.outDir));
|
|
3720
|
+
}
|
|
3721
|
+
for (const name of buildableNames) {
|
|
3722
|
+
const environment = config.environments[name];
|
|
3723
|
+
const outDir = import_node_path10.default.resolve(config.root, environment.build.outDir);
|
|
3724
|
+
if (!environment.build.emptyOutDir) {
|
|
3725
|
+
protectedPaths.add(outDir);
|
|
3726
|
+
continue;
|
|
3727
|
+
}
|
|
3728
|
+
if (!environment.driver) directories.add(outDir);
|
|
3729
|
+
}
|
|
3730
|
+
const containsPath = (parent, child) => {
|
|
3731
|
+
const relative = import_node_path10.default.relative(parent, child);
|
|
3732
|
+
return relative === "" || !relative.startsWith("..") && !import_node_path10.default.isAbsolute(relative);
|
|
3733
|
+
};
|
|
3734
|
+
const roots = [...directories].filter(
|
|
3735
|
+
(directory) => ![...protectedPaths].some((protectedPath) => containsPath(directory, protectedPath))
|
|
3736
|
+
).sort((a, b) => a.length - b.length).filter(
|
|
3737
|
+
(directory, index2, all) => !all.slice(0, index2).some((parent) => containsPath(parent, directory))
|
|
3738
|
+
);
|
|
3739
|
+
for (const directory of roots) {
|
|
3740
|
+
if (import_node_fs7.default.existsSync(directory)) import_node_fs7.default.rmSync(directory, { recursive: true, force: true });
|
|
3741
|
+
}
|
|
3742
|
+
}
|
|
3743
|
+
function assertDriverBuildResult(environment, result) {
|
|
3744
|
+
const output = result != null && typeof result === "object" ? result.output : void 0;
|
|
3745
|
+
const hasValidOutput = Array.isArray(output) && output.every(
|
|
3746
|
+
(artifact) => artifact != null && typeof artifact === "object" && typeof artifact.fileName === "string" && typeof artifact.type === "string"
|
|
3747
|
+
);
|
|
3748
|
+
if (!hasValidOutput) {
|
|
3749
|
+
throw new Error(
|
|
3750
|
+
`[nasti] environment "${environment.name}" driver "${environment.driver?.name}" returned an invalid build result; expected { output: EnvironmentBuildOutput[] }`
|
|
3751
|
+
);
|
|
3752
|
+
}
|
|
3753
|
+
}
|
|
2994
3754
|
function resolveClientEntries(config, html) {
|
|
2995
3755
|
const configuredEntries = config.environments.client?.entry ?? [];
|
|
2996
3756
|
if (configuredEntries.length > 0) return configuredEntries;
|
|
2997
3757
|
const entryPoints = [];
|
|
2998
3758
|
const htmlFile = config.environments.client?.html;
|
|
2999
|
-
const htmlDir = htmlFile ?
|
|
3759
|
+
const htmlDir = htmlFile ? import_node_path10.default.dirname(htmlFile) : config.root;
|
|
3000
3760
|
if (html) {
|
|
3001
3761
|
const scriptMatches = html.matchAll(/<script[^>]+src=["']([^"']+)["'][^>]*>/gi);
|
|
3002
3762
|
for (const match of scriptMatches) {
|
|
@@ -3004,7 +3764,7 @@ function resolveClientEntries(config, html) {
|
|
|
3004
3764
|
if (src && !src.startsWith("http")) {
|
|
3005
3765
|
const cleanSrc = src.split(/[?#]/, 1)[0];
|
|
3006
3766
|
entryPoints.push(
|
|
3007
|
-
cleanSrc.startsWith("/") ?
|
|
3767
|
+
cleanSrc.startsWith("/") ? import_node_path10.default.resolve(config.root, cleanSrc.replace(/^\//, "")) : import_node_path10.default.resolve(htmlDir, cleanSrc)
|
|
3008
3768
|
);
|
|
3009
3769
|
}
|
|
3010
3770
|
}
|
|
@@ -3012,8 +3772,8 @@ function resolveClientEntries(config, html) {
|
|
|
3012
3772
|
if (entryPoints.length === 0) {
|
|
3013
3773
|
const fallbackEntries = ["src/main.ts", "src/main.tsx", "src/main.js", "src/index.ts", "src/index.tsx", "src/index.js"];
|
|
3014
3774
|
for (const entry of fallbackEntries) {
|
|
3015
|
-
const fullPath =
|
|
3016
|
-
if (
|
|
3775
|
+
const fullPath = import_node_path10.default.resolve(config.root, entry);
|
|
3776
|
+
if (import_node_fs7.default.existsSync(fullPath)) {
|
|
3017
3777
|
entryPoints.push(fullPath);
|
|
3018
3778
|
break;
|
|
3019
3779
|
}
|
|
@@ -3028,6 +3788,7 @@ function createOxcTransformPlugin(config, environment) {
|
|
|
3028
3788
|
if (!shouldTransform(id)) return null;
|
|
3029
3789
|
const result = transformCode(id, code, {
|
|
3030
3790
|
sourcemap: !!environment.options.build.sourcemap,
|
|
3791
|
+
target: environment.options.build.target,
|
|
3031
3792
|
jsxRuntime: "automatic",
|
|
3032
3793
|
jsxImportSource: config.framework === "vue" ? "vue" : "react"
|
|
3033
3794
|
});
|
|
@@ -3041,16 +3802,20 @@ async function build(inlineConfig = {}) {
|
|
|
3041
3802
|
const startTime = performance.now();
|
|
3042
3803
|
logger.info(
|
|
3043
3804
|
import_picocolors4.default.cyan(`
|
|
3044
|
-
nasti v${"2.
|
|
3045
|
-
);
|
|
3046
|
-
debug4?.(`root: ${config.root}`);
|
|
3047
|
-
const buildableNames = Object.keys(config.environments).filter(
|
|
3048
|
-
(name) => name === "client" || config.environments[name].entry.length > 0 || !!config.environments[name].driver
|
|
3805
|
+
nasti v${"2.4.1"} `) + import_picocolors4.default.green(`building for ${config.mode}...`)
|
|
3049
3806
|
);
|
|
3807
|
+
debug5?.(`root: ${config.root}`);
|
|
3808
|
+
const buildableNames = Object.keys(config.environments).filter((name) => {
|
|
3809
|
+
const environment = config.environments[name];
|
|
3810
|
+
if (!environment.buildEnabled) return false;
|
|
3811
|
+
return name === "client" || environment.entry.length > 0 || !!environment.driver;
|
|
3812
|
+
});
|
|
3050
3813
|
buildableNames.sort((a, b) => a === "client" ? -1 : b === "client" ? 1 : 0);
|
|
3814
|
+
prepareBuildOutputDirectories(config, buildableNames);
|
|
3051
3815
|
const environments = {};
|
|
3052
3816
|
const environmentResults = {};
|
|
3053
3817
|
const initializedEnvironments = [];
|
|
3818
|
+
const buildAppContext = createBuildAppContext(config, environmentResults);
|
|
3054
3819
|
let clientOutput = [];
|
|
3055
3820
|
let buildFailed = false;
|
|
3056
3821
|
try {
|
|
@@ -3061,12 +3826,12 @@ nasti v${"2.3.1"} `) + import_picocolors4.default.green(`building for ${config.m
|
|
|
3061
3826
|
environmentResults[name] = built.result;
|
|
3062
3827
|
if (name === "client") clientOutput = built.result.output;
|
|
3063
3828
|
if (buildableNames.length > 1) {
|
|
3064
|
-
|
|
3829
|
+
debug5?.(`environment "${name}" built (${built.result.output.length} files)`);
|
|
3065
3830
|
}
|
|
3066
3831
|
}
|
|
3067
3832
|
const pluginApi = getPluginApi(config);
|
|
3068
3833
|
for (const plugin of config.plugins) {
|
|
3069
|
-
await plugin.afterBuildApp?.(environmentResults, pluginApi);
|
|
3834
|
+
await plugin.afterBuildApp?.(environmentResults, pluginApi, buildAppContext);
|
|
3070
3835
|
}
|
|
3071
3836
|
} catch (error) {
|
|
3072
3837
|
buildFailed = true;
|
|
@@ -3093,22 +3858,31 @@ nasti v${"2.3.1"} `) + import_picocolors4.default.green(`building for ${config.m
|
|
|
3093
3858
|
}
|
|
3094
3859
|
}
|
|
3095
3860
|
const elapsed = ((performance.now() - startTime) / 1e3).toFixed(2);
|
|
3096
|
-
const
|
|
3861
|
+
const allOutput = [...Object.values(environments).flat(), ...buildAppContext.output];
|
|
3862
|
+
const totalSize = allOutput.reduce((sum, chunk) => {
|
|
3097
3863
|
const content = chunk.type === "chunk" ? chunk.code : chunk.source;
|
|
3098
3864
|
if (content == null) return sum;
|
|
3099
3865
|
return sum + (typeof content === "string" ? Buffer.byteLength(content) : content.byteLength);
|
|
3100
3866
|
}, 0);
|
|
3101
|
-
const fileCount =
|
|
3867
|
+
const fileCount = allOutput.length;
|
|
3102
3868
|
const envSuffix = buildableNames.length > 1 ? ` (${buildableNames.join(" + ")})` : "";
|
|
3103
3869
|
logger.info(import_picocolors4.default.green(`\u2713 built in ${elapsed}s`) + import_picocolors4.default.dim(envSuffix));
|
|
3104
3870
|
logger.info(import_picocolors4.default.dim(` ${fileCount} files, ${displaySize(totalSize)} total \u2192 ${config.build.outDir}/`));
|
|
3105
|
-
return {
|
|
3871
|
+
return {
|
|
3872
|
+
output: clientOutput,
|
|
3873
|
+
environments,
|
|
3874
|
+
environmentResults,
|
|
3875
|
+
appOutput: [...buildAppContext.output]
|
|
3876
|
+
};
|
|
3106
3877
|
}
|
|
3107
3878
|
async function buildClientEnvironment(config) {
|
|
3108
3879
|
const logger = config.logger;
|
|
3109
|
-
const outDir =
|
|
3880
|
+
const outDir = import_node_path10.default.resolve(config.root, config.build.outDir);
|
|
3110
3881
|
const cssEngine = createCssEngine();
|
|
3111
|
-
const pluginList = resolvePluginList(config, config.plugins, {
|
|
3882
|
+
const pluginList = resolvePluginList(config, config.plugins, {
|
|
3883
|
+
cssEngine,
|
|
3884
|
+
environmentName: "client"
|
|
3885
|
+
});
|
|
3112
3886
|
const clientEnv = new NastiEnvironment("client", config, {
|
|
3113
3887
|
mode: "build",
|
|
3114
3888
|
plugins: pluginList,
|
|
@@ -3123,13 +3897,11 @@ async function buildClientEnvironment(config) {
|
|
|
3123
3897
|
);
|
|
3124
3898
|
}
|
|
3125
3899
|
const result = await clientEnv.driver.build(clientEnv.getDriverContext());
|
|
3126
|
-
|
|
3900
|
+
assertDriverBuildResult(clientEnv, result);
|
|
3901
|
+
return { environment: clientEnv, result: finalizeEnvironmentResult(clientEnv, result) };
|
|
3127
3902
|
}
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
}
|
|
3131
|
-
import_node_fs6.default.mkdirSync(outDir, { recursive: true });
|
|
3132
|
-
const htmlFile = config.environments.client.html ?? import_node_path9.default.resolve(config.root, "index.html");
|
|
3903
|
+
import_node_fs7.default.mkdirSync(outDir, { recursive: true });
|
|
3904
|
+
const htmlFile = config.environments.client.html ?? import_node_path10.default.resolve(config.root, "index.html");
|
|
3133
3905
|
const html = await readHtmlFile(config.root, htmlFile);
|
|
3134
3906
|
const entryPoints = resolveClientEntries(config, html);
|
|
3135
3907
|
if (entryPoints.length === 0) {
|
|
@@ -3139,7 +3911,7 @@ async function buildClientEnvironment(config) {
|
|
|
3139
3911
|
const nativeReporter = config.logLevel === "silent" ? null : await tryNativeReporterPlugin(config, logger);
|
|
3140
3912
|
const rolldownPlugins = [
|
|
3141
3913
|
createOxcTransformPlugin(config, clientEnv),
|
|
3142
|
-
...toRolldownPlugins(allPlugins),
|
|
3914
|
+
...toRolldownPlugins(allPlugins, clientEnv),
|
|
3143
3915
|
...nativeReporter ? [nativeReporter] : []
|
|
3144
3916
|
];
|
|
3145
3917
|
const { inputOptions, outputOptions } = getRolldownOptions(
|
|
@@ -3150,6 +3922,7 @@ async function buildClientEnvironment(config) {
|
|
|
3150
3922
|
const bundle2 = await (0, import_rolldown.rolldown)(inputOptions);
|
|
3151
3923
|
const { output } = await bundle2.write(outputOptions);
|
|
3152
3924
|
await bundle2.close();
|
|
3925
|
+
clientEnv.setBuildMetadata({ css: getCssMetadata(cssEngine) });
|
|
3153
3926
|
if (html) {
|
|
3154
3927
|
let processedHtml = html;
|
|
3155
3928
|
const htmlPlugins = [...allPlugins.filter((p) => p.transformIndexHtml), htmlPlugin(config)];
|
|
@@ -3163,7 +3936,9 @@ async function buildClientEnvironment(config) {
|
|
|
3163
3936
|
processedHtml = processHtml(processedHtml, result);
|
|
3164
3937
|
}
|
|
3165
3938
|
}
|
|
3166
|
-
|
|
3939
|
+
if (clientEnv.options.build.css.inject !== false) {
|
|
3940
|
+
processedHtml = injectCssLinks(processedHtml, cssEngine, config);
|
|
3941
|
+
}
|
|
3167
3942
|
for (const chunk of output) {
|
|
3168
3943
|
if (chunk.type === "chunk" && chunk.isEntry && chunk.facadeModuleId) {
|
|
3169
3944
|
processedHtml = replaceEntryScript(
|
|
@@ -3176,13 +3951,16 @@ async function buildClientEnvironment(config) {
|
|
|
3176
3951
|
);
|
|
3177
3952
|
}
|
|
3178
3953
|
}
|
|
3179
|
-
|
|
3954
|
+
import_node_fs7.default.writeFileSync(import_node_path10.default.resolve(outDir, "index.html"), processedHtml);
|
|
3180
3955
|
}
|
|
3181
3956
|
if (!nativeReporter && config.logLevel !== "silent") {
|
|
3182
3957
|
reportBuildOutput(output, config, logger);
|
|
3183
3958
|
}
|
|
3184
3959
|
warnLargeChunks(output, config, logger);
|
|
3185
|
-
return {
|
|
3960
|
+
return {
|
|
3961
|
+
environment: clientEnv,
|
|
3962
|
+
result: finalizeEnvironmentResult(clientEnv, { output })
|
|
3963
|
+
};
|
|
3186
3964
|
} catch (error) {
|
|
3187
3965
|
try {
|
|
3188
3966
|
await clientEnv.close();
|
|
@@ -3198,7 +3976,12 @@ async function buildClientEnvironment(config) {
|
|
|
3198
3976
|
async function buildServerEnvironment(config, name) {
|
|
3199
3977
|
const envOptions = config.environments[name];
|
|
3200
3978
|
const logger = config.logger;
|
|
3201
|
-
const
|
|
3979
|
+
const cssEngine = envOptions.consumer === "client" ? createCssEngine() : void 0;
|
|
3980
|
+
const pluginList = resolvePluginList(config, config.plugins, {
|
|
3981
|
+
consumer: envOptions.consumer,
|
|
3982
|
+
environmentName: name,
|
|
3983
|
+
cssEngine
|
|
3984
|
+
});
|
|
3202
3985
|
const environment = new NastiEnvironment(name, config, {
|
|
3203
3986
|
mode: "build",
|
|
3204
3987
|
plugins: pluginList,
|
|
@@ -3214,38 +3997,40 @@ async function buildServerEnvironment(config, name) {
|
|
|
3214
3997
|
}
|
|
3215
3998
|
try {
|
|
3216
3999
|
const result = await environment.driver.build(environment.getDriverContext());
|
|
3217
|
-
|
|
4000
|
+
assertDriverBuildResult(environment, result);
|
|
4001
|
+
return { environment, result: finalizeEnvironmentResult(environment, result) };
|
|
3218
4002
|
} catch (error) {
|
|
3219
4003
|
await environment.close();
|
|
3220
4004
|
throw error;
|
|
3221
4005
|
}
|
|
3222
4006
|
}
|
|
3223
4007
|
for (const entry of envOptions.entry) {
|
|
3224
|
-
if (!
|
|
4008
|
+
if (!import_node_fs7.default.existsSync(entry)) {
|
|
3225
4009
|
await environment.close();
|
|
3226
4010
|
throw new Error(`[nasti] environment "${name}" entry not found: ${entry}`);
|
|
3227
4011
|
}
|
|
3228
4012
|
}
|
|
3229
4013
|
const rolldownPlugins = [
|
|
3230
4014
|
createOxcTransformPlugin(config, environment),
|
|
3231
|
-
...toRolldownPlugins(environment.plugins)
|
|
4015
|
+
...toRolldownPlugins(environment.plugins, environment)
|
|
3232
4016
|
];
|
|
3233
4017
|
const { inputOptions, outputOptions, outDir } = getRolldownOptions(
|
|
3234
4018
|
environment,
|
|
3235
4019
|
envOptions.entry,
|
|
3236
4020
|
rolldownPlugins
|
|
3237
4021
|
);
|
|
3238
|
-
|
|
3239
|
-
import_node_fs6.default.rmSync(outDir, { recursive: true, force: true });
|
|
3240
|
-
}
|
|
3241
|
-
import_node_fs6.default.mkdirSync(outDir, { recursive: true });
|
|
4022
|
+
import_node_fs7.default.mkdirSync(outDir, { recursive: true });
|
|
3242
4023
|
const bundle2 = await (0, import_rolldown.rolldown)(inputOptions);
|
|
3243
4024
|
const { output } = await bundle2.write(outputOptions);
|
|
3244
4025
|
await bundle2.close();
|
|
4026
|
+
if (cssEngine) environment.setBuildMetadata({ css: getCssMetadata(cssEngine) });
|
|
3245
4027
|
logger.info(
|
|
3246
|
-
import_picocolors4.default.dim(` [${name}] `) + output.map((o) =>
|
|
4028
|
+
import_picocolors4.default.dim(` [${name}] `) + output.map((o) => import_node_path10.default.join(envOptions.build.outDir, o.fileName)).join(import_picocolors4.default.dim(", "))
|
|
3247
4029
|
);
|
|
3248
|
-
return {
|
|
4030
|
+
return {
|
|
4031
|
+
environment,
|
|
4032
|
+
result: finalizeEnvironmentResult(environment, { output })
|
|
4033
|
+
};
|
|
3249
4034
|
}
|
|
3250
4035
|
function injectCssLinks(html, cssEngine, config) {
|
|
3251
4036
|
const cssLinkTags = [];
|
|
@@ -3272,9 +4057,9 @@ function escapeRegExp(string) {
|
|
|
3272
4057
|
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3273
4058
|
}
|
|
3274
4059
|
function replaceEntryScript(html, facadeModuleId, fileName, config, htmlFile, urlPrefix) {
|
|
3275
|
-
const rootRelative =
|
|
3276
|
-
const resolvedHtmlFile =
|
|
3277
|
-
const htmlRelative =
|
|
4060
|
+
const rootRelative = import_node_path10.default.relative(config.root, facadeModuleId).split(import_node_path10.default.sep).join("/");
|
|
4061
|
+
const resolvedHtmlFile = import_node_path10.default.resolve(config.root, htmlFile);
|
|
4062
|
+
const htmlRelative = import_node_path10.default.relative(import_node_path10.default.dirname(resolvedHtmlFile), facadeModuleId).split(import_node_path10.default.sep).join("/");
|
|
3278
4063
|
const candidates = /* @__PURE__ */ new Set([
|
|
3279
4064
|
rootRelative,
|
|
3280
4065
|
`/${rootRelative}`,
|
|
@@ -3290,12 +4075,12 @@ function replaceEntryScript(html, facadeModuleId, fileName, config, htmlFile, ur
|
|
|
3290
4075
|
}
|
|
3291
4076
|
return processed;
|
|
3292
4077
|
}
|
|
3293
|
-
var
|
|
4078
|
+
var import_node_path10, import_node_fs7, import_node_module3, import_rolldown, import_picocolors4, debug5, NODE_BUILTINS;
|
|
3294
4079
|
var init_build = __esm({
|
|
3295
4080
|
"src/build/index.ts"() {
|
|
3296
4081
|
"use strict";
|
|
3297
|
-
|
|
3298
|
-
|
|
4082
|
+
import_node_path10 = __toESM(require("path"), 1);
|
|
4083
|
+
import_node_fs7 = __toESM(require("fs"), 1);
|
|
3299
4084
|
import_node_module3 = require("module");
|
|
3300
4085
|
import_rolldown = require("rolldown");
|
|
3301
4086
|
init_config();
|
|
@@ -3308,8 +4093,9 @@ var init_build = __esm({
|
|
|
3308
4093
|
init_reporter();
|
|
3309
4094
|
init_debug();
|
|
3310
4095
|
init_plugin_api();
|
|
4096
|
+
init_build_app_context();
|
|
3311
4097
|
import_picocolors4 = __toESM(require("picocolors"), 1);
|
|
3312
|
-
|
|
4098
|
+
debug5 = createDebugger("nasti:build");
|
|
3313
4099
|
NODE_BUILTINS = /* @__PURE__ */ new Set([...import_node_module3.builtinModules, ...import_node_module3.builtinModules.map((m) => `node:${m}`)]);
|
|
3314
4100
|
}
|
|
3315
4101
|
});
|
|
@@ -3360,22 +4146,17 @@ var init_ws = __esm({
|
|
|
3360
4146
|
});
|
|
3361
4147
|
|
|
3362
4148
|
// src/server/middleware.ts
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
transformMiddleware: () => transformMiddleware,
|
|
3368
|
-
transformRequest: () => transformRequest
|
|
3369
|
-
});
|
|
3370
|
-
function getReactRefreshRuntimeEsm() {
|
|
3371
|
-
if (__refreshRuntimeCache) return __refreshRuntimeCache;
|
|
4149
|
+
function getReactRefreshRuntimeEsm(includeBoundaryHelpers = false) {
|
|
4150
|
+
if (__refreshRuntimeCache) {
|
|
4151
|
+
return includeBoundaryHelpers ? __refreshRuntimeCache + REACT_REFRESH_BOUNDARY_HELPERS : __refreshRuntimeCache;
|
|
4152
|
+
}
|
|
3372
4153
|
let cjsPath;
|
|
3373
4154
|
try {
|
|
3374
4155
|
const pkgPath = __require.resolve("react-refresh/package.json");
|
|
3375
|
-
cjsPath =
|
|
4156
|
+
cjsPath = import_node_path12.default.join(import_node_path12.default.dirname(pkgPath), "cjs", "react-refresh-runtime.development.js");
|
|
3376
4157
|
} catch (err) {
|
|
3377
|
-
cjsPath =
|
|
3378
|
-
if (!
|
|
4158
|
+
cjsPath = import_node_path12.default.resolve(__dirname_esm, "../../node_modules/react-refresh/cjs/react-refresh-runtime.development.js");
|
|
4159
|
+
if (!import_node_fs9.default.existsSync(cjsPath)) {
|
|
3379
4160
|
const origMsg = err instanceof Error ? err.message : String(err);
|
|
3380
4161
|
throw new Error(
|
|
3381
4162
|
`[nasti] Missing dependency "react-refresh". Install it with: npm install react-refresh
|
|
@@ -3383,7 +4164,7 @@ Original resolve error: ${origMsg}`
|
|
|
3383
4164
|
);
|
|
3384
4165
|
}
|
|
3385
4166
|
}
|
|
3386
|
-
const cjsSource =
|
|
4167
|
+
const cjsSource = import_node_fs9.default.readFileSync(cjsPath, "utf-8");
|
|
3387
4168
|
__refreshRuntimeCache = `// Wrapped react-refresh runtime -> ESM
|
|
3388
4169
|
const exports = {};
|
|
3389
4170
|
const module = { exports };
|
|
@@ -3403,7 +4184,7 @@ export const findAffectedHostInstances = __rt.findAffectedHostInstances;
|
|
|
3403
4184
|
export const collectCustomHooksForSignature = __rt.collectCustomHooksForSignature;
|
|
3404
4185
|
export default __rt;
|
|
3405
4186
|
`;
|
|
3406
|
-
return __refreshRuntimeCache;
|
|
4187
|
+
return includeBoundaryHelpers ? __refreshRuntimeCache + REACT_REFRESH_BOUNDARY_HELPERS : __refreshRuntimeCache;
|
|
3407
4188
|
}
|
|
3408
4189
|
function buildReactRefreshWrapper(moduleUrl, transformedCode) {
|
|
3409
4190
|
const urlLit = JSON.stringify(moduleUrl);
|
|
@@ -3429,27 +4210,46 @@ window.$RefreshReg$ = prevRefreshReg;
|
|
|
3429
4210
|
window.$RefreshSig$ = prevRefreshSig;
|
|
3430
4211
|
|
|
3431
4212
|
if (__nasti_hot__) {
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
4213
|
+
let __nasti_current_exports__;
|
|
4214
|
+
__nasti_hot__.accept((nextExports) => {
|
|
4215
|
+
if (!nextExports) return;
|
|
4216
|
+
if (!__nasti_current_exports__) {
|
|
4217
|
+
__nasti_hot__.invalidate('Could not Fast Refresh (previous exports unavailable)');
|
|
4218
|
+
return;
|
|
4219
|
+
}
|
|
4220
|
+
const invalidateMessage = RefreshRuntime.validateRefreshBoundaryAndEnqueueUpdate(
|
|
4221
|
+
${urlLit},
|
|
4222
|
+
__nasti_current_exports__,
|
|
4223
|
+
nextExports,
|
|
4224
|
+
);
|
|
4225
|
+
if (invalidateMessage) __nasti_hot__.invalidate(invalidateMessage);
|
|
4226
|
+
});
|
|
4227
|
+
RefreshRuntime.__hmr_import(import.meta.url).then((currentExports) => {
|
|
4228
|
+
__nasti_current_exports__ = currentExports;
|
|
4229
|
+
RefreshRuntime.registerExportsForReactRefresh(${urlLit}, currentExports);
|
|
3437
4230
|
});
|
|
3438
4231
|
}
|
|
3439
4232
|
`;
|
|
3440
4233
|
}
|
|
3441
4234
|
function injectImportMetaHot(code, moduleUrl) {
|
|
3442
|
-
|
|
4235
|
+
const hotRE = /\bimport\.meta\.hot\b/g;
|
|
4236
|
+
const matches = [...maskStringsAndComments(code).matchAll(hotRE)];
|
|
4237
|
+
if (matches.length === 0) return code;
|
|
4238
|
+
for (const match of matches.reverse()) {
|
|
4239
|
+
const start = match.index;
|
|
4240
|
+
code = code.slice(0, start) + "__nasti_hot__" + code.slice(start + match[0].length);
|
|
4241
|
+
}
|
|
3443
4242
|
const urlLit = JSON.stringify(moduleUrl);
|
|
3444
4243
|
const header = `import { createHotContext as __nasti_createHotContext__ } from "/@nasti/client";
|
|
3445
4244
|
const __nasti_hot__ = __nasti_createHotContext__(${urlLit});
|
|
3446
4245
|
`;
|
|
3447
|
-
return header + code
|
|
4246
|
+
return header + code;
|
|
3448
4247
|
}
|
|
3449
4248
|
function transformMiddleware(ctx) {
|
|
3450
4249
|
ctx.envDefine = buildEnvDefine(
|
|
3451
4250
|
loadEnv(ctx.config.mode, ctx.config.root, ctx.config.envPrefix),
|
|
3452
|
-
ctx.config.mode
|
|
4251
|
+
ctx.config.mode,
|
|
4252
|
+
ssrDefineOverrides(ctx.environment?.consumer ?? "client")
|
|
3453
4253
|
);
|
|
3454
4254
|
return async (req, res, next) => {
|
|
3455
4255
|
const url = req.url ?? "/";
|
|
@@ -3494,7 +4294,7 @@ function transformMiddleware(ctx) {
|
|
|
3494
4294
|
return;
|
|
3495
4295
|
}
|
|
3496
4296
|
}
|
|
3497
|
-
if (isModuleRequest(url)) {
|
|
4297
|
+
if (isModuleRequest(url, req.headers["sec-fetch-dest"])) {
|
|
3498
4298
|
try {
|
|
3499
4299
|
const result = await transformRequest(url, ctx);
|
|
3500
4300
|
if (result) {
|
|
@@ -3520,13 +4320,14 @@ function transformMiddleware(ctx) {
|
|
|
3520
4320
|
}
|
|
3521
4321
|
async function transformRequest(url, ctx) {
|
|
3522
4322
|
const { config, pluginContainer, moduleGraph } = ctx;
|
|
4323
|
+
url = removeTimestampQuery(url);
|
|
3523
4324
|
const cleanReqUrl = url.split("?")[0];
|
|
3524
4325
|
const cached2 = moduleGraph.getModuleByUrl(url);
|
|
3525
4326
|
if (cached2?.transformResult) {
|
|
3526
4327
|
return cached2.transformResult;
|
|
3527
4328
|
}
|
|
3528
4329
|
if (cleanReqUrl === "/@react-refresh") {
|
|
3529
|
-
return { code: getReactRefreshRuntimeEsm() };
|
|
4330
|
+
return { code: getReactRefreshRuntimeEsm(true) };
|
|
3530
4331
|
}
|
|
3531
4332
|
if (cleanReqUrl.startsWith("/@modules/") && url.includes("?")) {
|
|
3532
4333
|
const idParam = new URLSearchParams(url.slice(url.indexOf("?") + 1)).get("id");
|
|
@@ -3534,8 +4335,8 @@ async function transformRequest(url, ctx) {
|
|
|
3534
4335
|
let realIdValid = false;
|
|
3535
4336
|
try {
|
|
3536
4337
|
if (idParam) {
|
|
3537
|
-
realId =
|
|
3538
|
-
realIdValid =
|
|
4338
|
+
realId = import_node_fs9.default.realpathSync(idParam);
|
|
4339
|
+
realIdValid = import_node_fs9.default.statSync(realId).isFile() && (realId.includes(`${import_node_path12.default.sep}node_modules${import_node_path12.default.sep}`) || isUnderRoot(realId, config.root));
|
|
3539
4340
|
}
|
|
3540
4341
|
} catch {
|
|
3541
4342
|
realId = null;
|
|
@@ -3562,40 +4363,63 @@ async function transformRequest(url, ctx) {
|
|
|
3562
4363
|
}
|
|
3563
4364
|
const rawQuery = url.includes("?") ? url.slice(url.indexOf("?") + 1) : "";
|
|
3564
4365
|
if (rawQuery && !/^t=\d+$/.test(rawQuery)) {
|
|
3565
|
-
const
|
|
3566
|
-
|
|
3567
|
-
|
|
4366
|
+
const mod2 = await moduleGraph.ensureEntryFromUrl(url);
|
|
4367
|
+
const transformVersion2 = mod2.invalidationVersion;
|
|
4368
|
+
const loaded2 = await pluginContainer.load(url);
|
|
4369
|
+
if (loaded2 != null) {
|
|
4370
|
+
let code2 = typeof loaded2 === "string" ? loaded2 : loaded2.code;
|
|
4371
|
+
let map2 = typeof loaded2 === "string" ? void 0 : loaded2.map;
|
|
3568
4372
|
const transformed = await pluginContainer.transform(code2, url);
|
|
3569
4373
|
if (transformed != null) {
|
|
3570
4374
|
code2 = typeof transformed === "string" ? transformed : transformed.code;
|
|
4375
|
+
if (typeof transformed !== "string" && transformed.map != null) {
|
|
4376
|
+
map2 = transformed.map;
|
|
4377
|
+
}
|
|
3571
4378
|
}
|
|
3572
|
-
const
|
|
3573
|
-
moduleGraph.registerModule(mod2,
|
|
3574
|
-
|
|
4379
|
+
const parentFile = resolveUrlToFile(cleanReqUrl, config.root) ?? cleanReqUrl;
|
|
4380
|
+
moduleGraph.registerModule(mod2, parentFile);
|
|
4381
|
+
const hotInfo2 = rewriteHotAcceptDeps(code2, config, parentFile);
|
|
4382
|
+
code2 = injectImportMetaHot(hotInfo2.code, url);
|
|
3575
4383
|
code2 = replaceEnvInCode(code2, ctx.envDefine ?? buildEnvDefine(
|
|
3576
4384
|
loadEnv(config.mode, config.root, config.envPrefix),
|
|
3577
|
-
config.mode
|
|
4385
|
+
config.mode,
|
|
4386
|
+
ssrDefineOverrides(ctx.environment?.consumer ?? "client")
|
|
3578
4387
|
));
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
4388
|
+
const importedUrls2 = /* @__PURE__ */ new Set();
|
|
4389
|
+
code2 = rewriteImports(code2, config, parentFile, importedUrls2, moduleGraph);
|
|
4390
|
+
const pruned2 = await moduleGraph.updateModuleInfo(
|
|
4391
|
+
mod2,
|
|
4392
|
+
importedUrls2,
|
|
4393
|
+
hotInfo2.acceptedUrls,
|
|
4394
|
+
hotInfo2.isSelfAccepting,
|
|
4395
|
+
transformVersion2
|
|
4396
|
+
);
|
|
4397
|
+
const transformResult2 = { code: code2, map: map2 };
|
|
4398
|
+
if (pruned2) {
|
|
4399
|
+
if (pruned2.size > 0) ctx.onPrune?.([...pruned2].map((item) => item.url));
|
|
4400
|
+
mod2.transformResult = transformResult2;
|
|
4401
|
+
}
|
|
3582
4402
|
return transformResult2;
|
|
3583
4403
|
}
|
|
3584
4404
|
}
|
|
3585
4405
|
const filePath = resolveUrlToFile(url, config.root);
|
|
3586
|
-
if (!filePath || !
|
|
4406
|
+
if (!filePath || !import_node_fs9.default.existsSync(filePath)) return null;
|
|
3587
4407
|
const mod = await moduleGraph.ensureEntryFromUrl(url);
|
|
3588
4408
|
moduleGraph.registerModule(mod, filePath);
|
|
4409
|
+
const transformVersion = mod.invalidationVersion;
|
|
3589
4410
|
if (cleanReqUrl.startsWith("/@modules/")) {
|
|
3590
4411
|
const code2 = await bundlePackageAsEsm(filePath, config.root);
|
|
3591
4412
|
const transformResult2 = { code: code2 };
|
|
3592
4413
|
mod.transformResult = transformResult2;
|
|
3593
4414
|
return transformResult2;
|
|
3594
4415
|
}
|
|
3595
|
-
|
|
4416
|
+
const loaded = await pluginContainer.load(filePath);
|
|
4417
|
+
let code = loaded == null ? import_node_fs9.default.readFileSync(filePath, "utf-8") : typeof loaded === "string" ? loaded : loaded.code;
|
|
4418
|
+
let map = loaded && typeof loaded !== "string" ? loaded.map : void 0;
|
|
3596
4419
|
const pluginResult = await pluginContainer.transform(code, filePath);
|
|
3597
4420
|
if (pluginResult) {
|
|
3598
4421
|
code = typeof pluginResult === "string" ? pluginResult : pluginResult.code;
|
|
4422
|
+
if (typeof pluginResult !== "string") map = pluginResult.map;
|
|
3599
4423
|
}
|
|
3600
4424
|
const stableUrl = cleanReqUrl;
|
|
3601
4425
|
let wrappedWithRefresh = false;
|
|
@@ -3606,26 +4430,41 @@ async function transformRequest(url, ctx) {
|
|
|
3606
4430
|
sourcemap: true,
|
|
3607
4431
|
jsxRuntime: "automatic",
|
|
3608
4432
|
jsxImportSource: config.framework === "vue" ? "vue" : "react",
|
|
3609
|
-
reactRefresh: useRefresh
|
|
4433
|
+
reactRefresh: useRefresh,
|
|
4434
|
+
target: ctx.environment?.options.build.target ?? config.build.target
|
|
3610
4435
|
});
|
|
3611
4436
|
code = result.code;
|
|
4437
|
+
if (result.map) map = JSON.parse(result.map);
|
|
3612
4438
|
if (useRefresh) {
|
|
3613
4439
|
code = buildReactRefreshWrapper(stableUrl, code);
|
|
3614
4440
|
wrappedWithRefresh = true;
|
|
3615
|
-
mod.isSelfAccepting = true;
|
|
3616
4441
|
}
|
|
3617
4442
|
}
|
|
4443
|
+
const hotInfo = rewriteHotAcceptDeps(code, config, filePath);
|
|
4444
|
+
code = hotInfo.code;
|
|
3618
4445
|
if (!wrappedWithRefresh) {
|
|
3619
4446
|
code = injectImportMetaHot(code, stableUrl);
|
|
3620
4447
|
}
|
|
3621
4448
|
const envDefine = ctx.envDefine ?? buildEnvDefine(
|
|
3622
4449
|
loadEnv(config.mode, config.root, config.envPrefix),
|
|
3623
|
-
config.mode
|
|
4450
|
+
config.mode,
|
|
4451
|
+
ssrDefineOverrides(ctx.environment?.consumer ?? "client")
|
|
3624
4452
|
);
|
|
3625
4453
|
code = replaceEnvInCode(code, envDefine);
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
4454
|
+
const importedUrls = /* @__PURE__ */ new Set();
|
|
4455
|
+
code = rewriteImports(code, config, filePath, importedUrls, moduleGraph);
|
|
4456
|
+
const pruned = await moduleGraph.updateModuleInfo(
|
|
4457
|
+
mod,
|
|
4458
|
+
importedUrls,
|
|
4459
|
+
hotInfo.acceptedUrls,
|
|
4460
|
+
wrappedWithRefresh || hotInfo.isSelfAccepting,
|
|
4461
|
+
transformVersion
|
|
4462
|
+
);
|
|
4463
|
+
const transformResult = { code, map };
|
|
4464
|
+
if (pruned) {
|
|
4465
|
+
if (pruned.size > 0) ctx.onPrune?.([...pruned].map((item) => item.url));
|
|
4466
|
+
mod.transformResult = transformResult;
|
|
4467
|
+
}
|
|
3629
4468
|
return transformResult;
|
|
3630
4469
|
}
|
|
3631
4470
|
async function loadVirtualModule(spec, ctx) {
|
|
@@ -3633,7 +4472,7 @@ async function loadVirtualModule(spec, ctx) {
|
|
|
3633
4472
|
const resolved = await pluginContainer.resolveId(spec);
|
|
3634
4473
|
if (resolved == null) return null;
|
|
3635
4474
|
const resolvedId = typeof resolved === "string" ? resolved : resolved.id;
|
|
3636
|
-
const looksVirtual = resolvedId.startsWith("\0") || !
|
|
4475
|
+
const looksVirtual = resolvedId.startsWith("\0") || !import_node_fs9.default.existsSync(resolvedId);
|
|
3637
4476
|
if (!looksVirtual) return null;
|
|
3638
4477
|
const loadResult = await pluginContainer.load(resolvedId);
|
|
3639
4478
|
if (loadResult == null) return null;
|
|
@@ -3644,9 +4483,10 @@ async function loadVirtualModule(spec, ctx) {
|
|
|
3644
4483
|
}
|
|
3645
4484
|
code = replaceEnvInCode(code, ctx.envDefine ?? buildEnvDefine(
|
|
3646
4485
|
loadEnv(config.mode, config.root, config.envPrefix),
|
|
3647
|
-
config.mode
|
|
4486
|
+
config.mode,
|
|
4487
|
+
ssrDefineOverrides(ctx.environment?.consumer ?? "client")
|
|
3648
4488
|
));
|
|
3649
|
-
const anchor =
|
|
4489
|
+
const anchor = import_node_path12.default.join(config.root, "__nasti_virtual__.ts");
|
|
3650
4490
|
code = rewriteImports(code, config, anchor);
|
|
3651
4491
|
return { id: resolvedId, result: { code } };
|
|
3652
4492
|
}
|
|
@@ -3672,7 +4512,7 @@ async function doBundlePackage(entryFile, root) {
|
|
|
3672
4512
|
await bundle2.close();
|
|
3673
4513
|
let code = result.output[0].code;
|
|
3674
4514
|
code = code.replace(/process\.env\.NODE_ENV/g, '"development"');
|
|
3675
|
-
const externalBaseDir =
|
|
4515
|
+
const externalBaseDir = import_node_path12.default.dirname(entryFile);
|
|
3676
4516
|
code = code.replace(
|
|
3677
4517
|
/^(import\b[^;'"]*?\bfrom\s+)(['"])([^'"./][^'"]*)(\2)/gm,
|
|
3678
4518
|
(_, prefix, q, spec) => `${prefix}${q}${externalSpecToModuleUrl(spec, externalBaseDir, root)}${q}`
|
|
@@ -3690,16 +4530,16 @@ async function doBundlePackage(entryFile, root) {
|
|
|
3690
4530
|
return code;
|
|
3691
4531
|
}
|
|
3692
4532
|
async function tryGenerateSubpathShim(entryFile, root) {
|
|
3693
|
-
const NM = `${
|
|
4533
|
+
const NM = `${import_node_path12.default.sep}node_modules${import_node_path12.default.sep}`;
|
|
3694
4534
|
if (!entryFile.includes(NM)) return null;
|
|
3695
4535
|
let pkgDir = null;
|
|
3696
4536
|
let pkgName = null;
|
|
3697
|
-
let dir =
|
|
4537
|
+
let dir = import_node_path12.default.dirname(entryFile);
|
|
3698
4538
|
while (true) {
|
|
3699
|
-
const pkgJsonPath =
|
|
3700
|
-
if (
|
|
4539
|
+
const pkgJsonPath = import_node_path12.default.join(dir, "package.json");
|
|
4540
|
+
if (import_node_fs9.default.existsSync(pkgJsonPath)) {
|
|
3701
4541
|
try {
|
|
3702
|
-
const pkg = JSON.parse(
|
|
4542
|
+
const pkg = JSON.parse(import_node_fs9.default.readFileSync(pkgJsonPath, "utf-8"));
|
|
3703
4543
|
if (typeof pkg?.name === "string" && pkg.name) {
|
|
3704
4544
|
pkgDir = dir;
|
|
3705
4545
|
pkgName = pkg.name;
|
|
@@ -3708,16 +4548,16 @@ async function tryGenerateSubpathShim(entryFile, root) {
|
|
|
3708
4548
|
} catch {
|
|
3709
4549
|
}
|
|
3710
4550
|
}
|
|
3711
|
-
const parent =
|
|
4551
|
+
const parent = import_node_path12.default.dirname(dir);
|
|
3712
4552
|
if (parent === dir) return null;
|
|
3713
4553
|
dir = parent;
|
|
3714
4554
|
if (!dir.includes(NM)) return null;
|
|
3715
4555
|
}
|
|
3716
4556
|
if (!pkgDir || !pkgName) return null;
|
|
3717
|
-
const entryExt =
|
|
4557
|
+
const entryExt = import_node_path12.default.extname(entryFile);
|
|
3718
4558
|
const mainEntry = pickMainEntryByExtension(pkgDir, entryExt);
|
|
3719
4559
|
if (!mainEntry) return null;
|
|
3720
|
-
if (
|
|
4560
|
+
if (import_node_path12.default.resolve(mainEntry) === import_node_path12.default.resolve(entryFile)) return null;
|
|
3721
4561
|
let mainNs;
|
|
3722
4562
|
let subNs;
|
|
3723
4563
|
try {
|
|
@@ -3741,7 +4581,7 @@ async function tryGenerateSubpathShim(entryFile, root) {
|
|
|
3741
4581
|
if (mainNs["default"] !== subNs["default"]) return null;
|
|
3742
4582
|
}
|
|
3743
4583
|
const rootMain = resolveNodeModule(root, pkgName);
|
|
3744
|
-
const mainEntryUrl = rootMain && rootMain.startsWith(pkgDir +
|
|
4584
|
+
const mainEntryUrl = rootMain && rootMain.startsWith(pkgDir + import_node_path12.default.sep) ? `/@modules/${pkgName}` : `/@modules/${pkgName}?id=${encodeURIComponent(mainEntry)}`;
|
|
3745
4585
|
const lines = [
|
|
3746
4586
|
`// Nasti subpath shim \u2192 ${pkgName} (avoid duplicate bundling)`,
|
|
3747
4587
|
`import * as __pkg from "${mainEntryUrl}";`
|
|
@@ -3755,10 +4595,10 @@ async function tryGenerateSubpathShim(entryFile, root) {
|
|
|
3755
4595
|
return lines.join("\n") + "\n";
|
|
3756
4596
|
}
|
|
3757
4597
|
function pickMainEntryByExtension(pkgDir, preferredExt) {
|
|
3758
|
-
const pkgJsonPath =
|
|
4598
|
+
const pkgJsonPath = import_node_path12.default.join(pkgDir, "package.json");
|
|
3759
4599
|
let pkg;
|
|
3760
4600
|
try {
|
|
3761
|
-
pkg = JSON.parse(
|
|
4601
|
+
pkg = JSON.parse(import_node_fs9.default.readFileSync(pkgJsonPath, "utf-8"));
|
|
3762
4602
|
} catch {
|
|
3763
4603
|
return null;
|
|
3764
4604
|
}
|
|
@@ -3777,14 +4617,14 @@ function pickMainEntryByExtension(pkgDir, preferredExt) {
|
|
|
3777
4617
|
if (typeof pkg.module === "string") candidates.push(pkg.module);
|
|
3778
4618
|
if (typeof pkg.main === "string") candidates.push(pkg.main);
|
|
3779
4619
|
for (const cand of candidates) {
|
|
3780
|
-
if (
|
|
3781
|
-
const full =
|
|
3782
|
-
if (
|
|
4620
|
+
if (import_node_path12.default.extname(cand) === preferredExt) {
|
|
4621
|
+
const full = import_node_path12.default.resolve(pkgDir, cand);
|
|
4622
|
+
if (import_node_fs9.default.existsSync(full)) return full;
|
|
3783
4623
|
}
|
|
3784
4624
|
}
|
|
3785
4625
|
for (const cand of candidates) {
|
|
3786
|
-
const full =
|
|
3787
|
-
if (
|
|
4626
|
+
const full = import_node_path12.default.resolve(pkgDir, cand);
|
|
4627
|
+
if (import_node_fs9.default.existsSync(full)) return full;
|
|
3788
4628
|
}
|
|
3789
4629
|
return null;
|
|
3790
4630
|
}
|
|
@@ -3830,72 +4670,231 @@ async function injectCjsNamedExports(code, entryFile) {
|
|
|
3830
4670
|
return code;
|
|
3831
4671
|
}
|
|
3832
4672
|
}
|
|
3833
|
-
function rewriteImports(code, config, filePath) {
|
|
4673
|
+
function rewriteImports(code, config, filePath, importedUrls, moduleGraph) {
|
|
4674
|
+
const resolveSpec = createModuleSpecifierResolver(config, filePath);
|
|
4675
|
+
const transformSpec = (spec) => {
|
|
4676
|
+
const resolved = removeTimestampQuery(resolveSpec(spec));
|
|
4677
|
+
importedUrls?.add(resolved);
|
|
4678
|
+
const timestamp = moduleGraph?.getModuleByUrl(resolved)?.lastHMRTimestamp ?? 0;
|
|
4679
|
+
return timestamp > 0 ? appendTimestampQuery(resolved, timestamp) : resolved;
|
|
4680
|
+
};
|
|
4681
|
+
return code.replace(
|
|
4682
|
+
/\bfrom\s+(['"])([^'"]+)\1/g,
|
|
4683
|
+
(_m, q, s) => `from ${q}${transformSpec(s)}${q}`
|
|
4684
|
+
).replace(
|
|
4685
|
+
/\bimport\s+(['"])([^'"]+)\1/g,
|
|
4686
|
+
(_m, q, s) => `import ${q}${transformSpec(s)}${q}`
|
|
4687
|
+
).replace(
|
|
4688
|
+
/\bimport\s*\(\s*(['"])([^'"]+)\1\s*\)/g,
|
|
4689
|
+
(_m, q, s) => `import(${q}${transformSpec(s)}${q})`
|
|
4690
|
+
);
|
|
4691
|
+
}
|
|
4692
|
+
function createModuleSpecifierResolver(config, filePath) {
|
|
3834
4693
|
const root = config.root;
|
|
3835
|
-
const fileDir =
|
|
4694
|
+
const fileDir = import_node_path12.default.dirname(filePath);
|
|
3836
4695
|
const aliasEntries = Object.entries(config.resolve.alias).sort(
|
|
3837
4696
|
([a], [b]) => b.length - a.length
|
|
3838
4697
|
);
|
|
3839
|
-
const toRootUrl = (abs) => "/" +
|
|
3840
|
-
|
|
3841
|
-
const suffixMatch =
|
|
4698
|
+
const toRootUrl = (abs) => "/" + import_node_path12.default.relative(root, abs).replace(/\\/g, "/");
|
|
4699
|
+
return (specifier) => {
|
|
4700
|
+
const suffixMatch = specifier.match(/[?#].*$/);
|
|
3842
4701
|
const suffix = suffixMatch ? suffixMatch[0] : "";
|
|
3843
|
-
const baseSpec = suffix ?
|
|
4702
|
+
const baseSpec = suffix ? specifier.slice(0, -suffix.length) : specifier;
|
|
3844
4703
|
for (const [key, value] of aliasEntries) {
|
|
3845
4704
|
if (baseSpec === key || baseSpec.startsWith(key + "/")) {
|
|
3846
4705
|
const aliasBase = resolveAliasTarget2(value, root);
|
|
3847
4706
|
const sub = baseSpec.slice(key.length).replace(/^\//, "");
|
|
3848
|
-
const target = sub ?
|
|
4707
|
+
const target = sub ? import_node_path12.default.join(aliasBase, sub) : aliasBase;
|
|
3849
4708
|
const resolved = tryResolveDiskPath(target);
|
|
3850
|
-
return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix :
|
|
4709
|
+
return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix : specifier;
|
|
3851
4710
|
}
|
|
3852
4711
|
}
|
|
3853
4712
|
if (baseSpec.startsWith("./") || baseSpec.startsWith("../")) {
|
|
3854
|
-
const
|
|
3855
|
-
|
|
3856
|
-
return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix : spec;
|
|
4713
|
+
const resolved = tryResolveDiskPath(import_node_path12.default.resolve(fileDir, baseSpec));
|
|
4714
|
+
return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix : specifier;
|
|
3857
4715
|
}
|
|
3858
4716
|
if (baseSpec.startsWith("/") && !baseSpec.startsWith("/@")) {
|
|
3859
|
-
const
|
|
3860
|
-
|
|
3861
|
-
return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix : spec;
|
|
4717
|
+
const resolved = tryResolveDiskPath(import_node_path12.default.join(root, baseSpec.replace(/^\//, "")));
|
|
4718
|
+
return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix : specifier;
|
|
3862
4719
|
}
|
|
3863
|
-
if (baseSpec.startsWith("/")) return
|
|
3864
|
-
return `/@modules/${
|
|
4720
|
+
if (baseSpec.startsWith("/")) return specifier;
|
|
4721
|
+
return `/@modules/${specifier}`;
|
|
3865
4722
|
};
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
)
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
)
|
|
4723
|
+
}
|
|
4724
|
+
function rewriteHotAcceptDeps(code, config, filePath) {
|
|
4725
|
+
const acceptedUrls = /* @__PURE__ */ new Set();
|
|
4726
|
+
const edits = [];
|
|
4727
|
+
const resolveSpec = createModuleSpecifierResolver(config, filePath);
|
|
4728
|
+
const acceptRE = /(?:\bimport\.meta\.hot|\b__nasti_hot__)(?:(?:\?\.)|\.)accept\s*\(/g;
|
|
4729
|
+
const searchableCode = maskStringsAndComments(code);
|
|
4730
|
+
let isSelfAccepting = false;
|
|
4731
|
+
let match;
|
|
4732
|
+
while (match = acceptRE.exec(searchableCode)) {
|
|
4733
|
+
let cursor = match.index + match[0].length;
|
|
4734
|
+
const skipTrivia = () => {
|
|
4735
|
+
while (cursor < code.length) {
|
|
4736
|
+
if (/\s/.test(code[cursor])) {
|
|
4737
|
+
cursor++;
|
|
4738
|
+
continue;
|
|
4739
|
+
}
|
|
4740
|
+
if (code[cursor] === "/" && code[cursor + 1] === "/") {
|
|
4741
|
+
cursor += 2;
|
|
4742
|
+
while (cursor < code.length && code[cursor] !== "\n") cursor++;
|
|
4743
|
+
continue;
|
|
4744
|
+
}
|
|
4745
|
+
if (code[cursor] === "/" && code[cursor + 1] === "*") {
|
|
4746
|
+
cursor += 2;
|
|
4747
|
+
while (cursor < code.length && !(code[cursor] === "*" && code[cursor + 1] === "/")) cursor++;
|
|
4748
|
+
cursor += 2;
|
|
4749
|
+
continue;
|
|
4750
|
+
}
|
|
4751
|
+
break;
|
|
4752
|
+
}
|
|
4753
|
+
};
|
|
4754
|
+
skipTrivia();
|
|
4755
|
+
const first = code[cursor];
|
|
4756
|
+
if (!first || first === ")" || first !== "[" && first !== "'" && first !== '"' && first !== "`") {
|
|
4757
|
+
isSelfAccepting = true;
|
|
4758
|
+
continue;
|
|
4759
|
+
}
|
|
4760
|
+
const readLiteral = () => {
|
|
4761
|
+
const quote = code[cursor];
|
|
4762
|
+
if (quote !== "'" && quote !== '"' && quote !== "`") return;
|
|
4763
|
+
const start = cursor;
|
|
4764
|
+
cursor++;
|
|
4765
|
+
let raw = "";
|
|
4766
|
+
while (cursor < code.length) {
|
|
4767
|
+
const char = code[cursor];
|
|
4768
|
+
if (char === "\\") {
|
|
4769
|
+
raw += code[cursor + 1] ?? "";
|
|
4770
|
+
cursor += 2;
|
|
4771
|
+
continue;
|
|
4772
|
+
}
|
|
4773
|
+
if (char === quote) {
|
|
4774
|
+
cursor++;
|
|
4775
|
+
const resolved = removeTimestampQuery(resolveSpec(raw));
|
|
4776
|
+
acceptedUrls.add(resolved);
|
|
4777
|
+
edits.push({ start, end: cursor, value: JSON.stringify(resolved) });
|
|
4778
|
+
return;
|
|
4779
|
+
}
|
|
4780
|
+
if (quote === "`" && char === "$" && code[cursor + 1] === "{") return;
|
|
4781
|
+
raw += char;
|
|
4782
|
+
cursor++;
|
|
4783
|
+
}
|
|
4784
|
+
};
|
|
4785
|
+
if (first === "[") {
|
|
4786
|
+
cursor++;
|
|
4787
|
+
while (cursor < code.length) {
|
|
4788
|
+
skipTrivia();
|
|
4789
|
+
if (code[cursor] === ",") {
|
|
4790
|
+
cursor++;
|
|
4791
|
+
skipTrivia();
|
|
4792
|
+
}
|
|
4793
|
+
if (code[cursor] === "]") break;
|
|
4794
|
+
const before = cursor;
|
|
4795
|
+
readLiteral();
|
|
4796
|
+
if (cursor === before) break;
|
|
4797
|
+
}
|
|
4798
|
+
} else {
|
|
4799
|
+
readLiteral();
|
|
4800
|
+
}
|
|
4801
|
+
}
|
|
4802
|
+
for (const edit of edits.sort((a, b) => b.start - a.start)) {
|
|
4803
|
+
code = code.slice(0, edit.start) + edit.value + code.slice(edit.end);
|
|
4804
|
+
}
|
|
4805
|
+
return { code, acceptedUrls, isSelfAccepting };
|
|
4806
|
+
}
|
|
4807
|
+
function maskStringsAndComments(code) {
|
|
4808
|
+
const masked = code.split("");
|
|
4809
|
+
let state = "code";
|
|
4810
|
+
const isRegexStart = (index2) => {
|
|
4811
|
+
let previous = index2 - 1;
|
|
4812
|
+
while (previous >= 0 && /\s/.test(code[previous])) previous--;
|
|
4813
|
+
return previous < 0 || "=(:,!&|?{};[]+-*%^~<>".includes(code[previous]);
|
|
4814
|
+
};
|
|
4815
|
+
for (let i = 0; i < code.length; i++) {
|
|
4816
|
+
const char = code[i];
|
|
4817
|
+
const next = code[i + 1];
|
|
4818
|
+
if (state === "code") {
|
|
4819
|
+
if (char === "'") state = "single";
|
|
4820
|
+
else if (char === '"') state = "double";
|
|
4821
|
+
else if (char === "`") state = "template";
|
|
4822
|
+
else if (char === "/" && next === "/") state = "line-comment";
|
|
4823
|
+
else if (char === "/" && next === "*") state = "block-comment";
|
|
4824
|
+
else if (char === "/" && isRegexStart(i)) state = "regex";
|
|
4825
|
+
else continue;
|
|
4826
|
+
masked[i] = " ";
|
|
4827
|
+
continue;
|
|
4828
|
+
}
|
|
4829
|
+
if (state === "line-comment") {
|
|
4830
|
+
if (char === "\n") {
|
|
4831
|
+
state = "code";
|
|
4832
|
+
} else {
|
|
4833
|
+
masked[i] = " ";
|
|
4834
|
+
}
|
|
4835
|
+
continue;
|
|
4836
|
+
}
|
|
4837
|
+
if (state === "block-comment") {
|
|
4838
|
+
masked[i] = char === "\n" ? "\n" : " ";
|
|
4839
|
+
if (char === "*" && next === "/") {
|
|
4840
|
+
masked[i + 1] = " ";
|
|
4841
|
+
i++;
|
|
4842
|
+
state = "code";
|
|
4843
|
+
}
|
|
4844
|
+
continue;
|
|
4845
|
+
}
|
|
4846
|
+
if (state === "regex" || state === "regex-class") {
|
|
4847
|
+
masked[i] = char === "\n" ? "\n" : " ";
|
|
4848
|
+
if (char === "\\") {
|
|
4849
|
+
if (i + 1 < code.length) masked[++i] = " ";
|
|
4850
|
+
} else if (state === "regex" && char === "[") {
|
|
4851
|
+
state = "regex-class";
|
|
4852
|
+
} else if (state === "regex-class" && char === "]") {
|
|
4853
|
+
state = "regex";
|
|
4854
|
+
} else if (state === "regex" && char === "/") {
|
|
4855
|
+
state = "code";
|
|
4856
|
+
}
|
|
4857
|
+
continue;
|
|
4858
|
+
}
|
|
4859
|
+
masked[i] = char === "\n" ? "\n" : " ";
|
|
4860
|
+
if (char === "\\") {
|
|
4861
|
+
if (i + 1 < code.length) masked[++i] = " ";
|
|
4862
|
+
continue;
|
|
4863
|
+
}
|
|
4864
|
+
if (state === "single" && char === "'" || state === "double" && char === '"' || state === "template" && char === "`") {
|
|
4865
|
+
state = "code";
|
|
4866
|
+
}
|
|
4867
|
+
}
|
|
4868
|
+
return masked.join("");
|
|
3876
4869
|
}
|
|
3877
4870
|
function resolveAliasTarget2(value, root) {
|
|
3878
|
-
if (
|
|
3879
|
-
if (value.startsWith("/")) return
|
|
3880
|
-
return
|
|
4871
|
+
if (import_node_path12.default.isAbsolute(value) && import_node_fs9.default.existsSync(value)) return value;
|
|
4872
|
+
if (value.startsWith("/")) return import_node_path12.default.join(root, value.slice(1));
|
|
4873
|
+
return import_node_path12.default.resolve(root, value);
|
|
3881
4874
|
}
|
|
3882
4875
|
function tryResolveDiskPath(target) {
|
|
3883
|
-
if (
|
|
4876
|
+
if (import_node_fs9.default.existsSync(target) && import_node_fs9.default.statSync(target).isFile()) return target;
|
|
3884
4877
|
for (const ext of RESOLVE_EXTENSIONS) {
|
|
3885
4878
|
const withExt = target + ext;
|
|
3886
|
-
if (
|
|
4879
|
+
if (import_node_fs9.default.existsSync(withExt) && import_node_fs9.default.statSync(withExt).isFile()) return withExt;
|
|
3887
4880
|
}
|
|
3888
|
-
if (
|
|
4881
|
+
if (import_node_fs9.default.existsSync(target) && import_node_fs9.default.statSync(target).isDirectory()) {
|
|
3889
4882
|
for (const ext of RESOLVE_EXTENSIONS) {
|
|
3890
|
-
const idx =
|
|
3891
|
-
if (
|
|
4883
|
+
const idx = import_node_path12.default.join(target, "index" + ext);
|
|
4884
|
+
if (import_node_fs9.default.existsSync(idx) && import_node_fs9.default.statSync(idx).isFile()) return idx;
|
|
3892
4885
|
}
|
|
3893
4886
|
}
|
|
3894
4887
|
return null;
|
|
3895
4888
|
}
|
|
3896
4889
|
function isUnderRoot(abs, root) {
|
|
3897
|
-
const rel =
|
|
3898
|
-
return !!rel && !rel.startsWith("..") && !
|
|
4890
|
+
const rel = import_node_path12.default.relative(root, abs);
|
|
4891
|
+
return !!rel && !rel.startsWith("..") && !import_node_path12.default.isAbsolute(rel);
|
|
4892
|
+
}
|
|
4893
|
+
function appendTimestampQuery(url, timestamp) {
|
|
4894
|
+
const hashIndex = url.indexOf("#");
|
|
4895
|
+
const hash = hashIndex >= 0 ? url.slice(hashIndex) : "";
|
|
4896
|
+
const withoutHash = hashIndex >= 0 ? url.slice(0, hashIndex) : url;
|
|
4897
|
+
return `${withoutHash}${withoutHash.includes("?") ? "&" : "?"}t=${timestamp}${hash}`;
|
|
3899
4898
|
}
|
|
3900
4899
|
function externalSpecToModuleUrl(spec, baseDir, root) {
|
|
3901
4900
|
const resolved = resolveNodeModule(baseDir, spec);
|
|
@@ -3908,7 +4907,7 @@ function resolveNodeModule(baseDir, moduleName) {
|
|
|
3908
4907
|
const resolved = resolveNodeModuleEntry(baseDir, moduleName);
|
|
3909
4908
|
if (!resolved) return null;
|
|
3910
4909
|
try {
|
|
3911
|
-
return
|
|
4910
|
+
return import_node_fs9.default.realpathSync(resolved);
|
|
3912
4911
|
} catch {
|
|
3913
4912
|
return resolved;
|
|
3914
4913
|
}
|
|
@@ -3928,21 +4927,21 @@ function resolveNodeModuleEntry(root, moduleName) {
|
|
|
3928
4927
|
let pkgDir = null;
|
|
3929
4928
|
let dir = root;
|
|
3930
4929
|
for (; ; ) {
|
|
3931
|
-
const candidate =
|
|
3932
|
-
if (
|
|
4930
|
+
const candidate = import_node_path12.default.join(dir, "node_modules", pkgName);
|
|
4931
|
+
if (import_node_fs9.default.existsSync(candidate)) {
|
|
3933
4932
|
pkgDir = candidate;
|
|
3934
4933
|
break;
|
|
3935
4934
|
}
|
|
3936
|
-
const parent =
|
|
4935
|
+
const parent = import_node_path12.default.dirname(dir);
|
|
3937
4936
|
if (parent === dir) break;
|
|
3938
4937
|
dir = parent;
|
|
3939
4938
|
}
|
|
3940
4939
|
if (!pkgDir) return null;
|
|
3941
|
-
const pkgJsonPath =
|
|
3942
|
-
if (!
|
|
4940
|
+
const pkgJsonPath = import_node_path12.default.join(pkgDir, "package.json");
|
|
4941
|
+
if (!import_node_fs9.default.existsSync(pkgJsonPath)) return null;
|
|
3943
4942
|
let pkg;
|
|
3944
4943
|
try {
|
|
3945
|
-
pkg = JSON.parse(
|
|
4944
|
+
pkg = JSON.parse(import_node_fs9.default.readFileSync(pkgJsonPath, "utf-8"));
|
|
3946
4945
|
} catch {
|
|
3947
4946
|
return null;
|
|
3948
4947
|
}
|
|
@@ -3955,32 +4954,32 @@ function resolveNodeModuleEntry(root, moduleName) {
|
|
|
3955
4954
|
const subDirs = [""];
|
|
3956
4955
|
for (const field of ["module", "main"]) {
|
|
3957
4956
|
if (typeof pkg[field] === "string") {
|
|
3958
|
-
const dir2 =
|
|
4957
|
+
const dir2 = import_node_path12.default.dirname(pkg[field]);
|
|
3959
4958
|
if (dir2 && dir2 !== "." && !subDirs.includes(dir2)) subDirs.push(dir2);
|
|
3960
4959
|
}
|
|
3961
4960
|
}
|
|
3962
4961
|
for (const dir2 of subDirs) {
|
|
3963
|
-
const direct =
|
|
3964
|
-
if (
|
|
4962
|
+
const direct = import_node_path12.default.join(pkgDir, dir2, subpath);
|
|
4963
|
+
if (import_node_fs9.default.existsSync(direct) && import_node_fs9.default.statSync(direct).isFile()) return direct;
|
|
3965
4964
|
for (const ext of RESOLVE_EXTENSIONS) {
|
|
3966
|
-
if (
|
|
4965
|
+
if (import_node_fs9.default.existsSync(direct + ext)) return direct + ext;
|
|
3967
4966
|
}
|
|
3968
4967
|
}
|
|
3969
4968
|
return null;
|
|
3970
4969
|
}
|
|
3971
4970
|
for (const field of ["module", "jsnext:main", "jsnext", "main"]) {
|
|
3972
4971
|
if (typeof pkg[field] === "string") {
|
|
3973
|
-
const entry =
|
|
3974
|
-
if (
|
|
4972
|
+
const entry = import_node_path12.default.join(pkgDir, pkg[field]);
|
|
4973
|
+
if (import_node_fs9.default.existsSync(entry)) return entry;
|
|
3975
4974
|
}
|
|
3976
4975
|
}
|
|
3977
|
-
const indexFallback =
|
|
3978
|
-
if (
|
|
4976
|
+
const indexFallback = import_node_path12.default.join(pkgDir, "index.js");
|
|
4977
|
+
if (import_node_fs9.default.existsSync(indexFallback)) return indexFallback;
|
|
3979
4978
|
return null;
|
|
3980
4979
|
}
|
|
3981
4980
|
function resolvePackageExports(exports2, key, pkgDir) {
|
|
3982
4981
|
if (typeof exports2 === "string") {
|
|
3983
|
-
return key === "." ?
|
|
4982
|
+
return key === "." ? import_node_path12.default.join(pkgDir, exports2) : null;
|
|
3984
4983
|
}
|
|
3985
4984
|
const entry = exports2[key];
|
|
3986
4985
|
if (entry === void 0) {
|
|
@@ -3992,7 +4991,7 @@ function resolvePackageExports(exports2, key, pkgDir) {
|
|
|
3992
4991
|
return resolveExportValue(entry, pkgDir);
|
|
3993
4992
|
}
|
|
3994
4993
|
function resolveExportValue(value, pkgDir) {
|
|
3995
|
-
if (typeof value === "string") return
|
|
4994
|
+
if (typeof value === "string") return import_node_path12.default.join(pkgDir, value);
|
|
3996
4995
|
if (Array.isArray(value)) {
|
|
3997
4996
|
for (const item of value) {
|
|
3998
4997
|
const r = resolveExportValue(item, pkgDir);
|
|
@@ -4016,54 +5015,62 @@ function resolveUrlToFile(url, root) {
|
|
|
4016
5015
|
const moduleName = cleanUrl.slice("/@modules/".length);
|
|
4017
5016
|
return resolveNodeModule(root, moduleName);
|
|
4018
5017
|
}
|
|
4019
|
-
const filePath =
|
|
4020
|
-
if (
|
|
5018
|
+
const filePath = import_node_path12.default.resolve(root, cleanUrl.replace(/^\//, ""));
|
|
5019
|
+
if (import_node_fs9.default.existsSync(filePath) && import_node_fs9.default.statSync(filePath).isFile()) {
|
|
4021
5020
|
return filePath;
|
|
4022
5021
|
}
|
|
4023
5022
|
for (const ext of RESOLVE_EXTENSIONS) {
|
|
4024
5023
|
const withExt = filePath + ext;
|
|
4025
|
-
if (
|
|
5024
|
+
if (import_node_fs9.default.existsSync(withExt)) return withExt;
|
|
4026
5025
|
}
|
|
4027
5026
|
for (const ext of RESOLVE_EXTENSIONS) {
|
|
4028
|
-
const indexFile =
|
|
4029
|
-
if (
|
|
5027
|
+
const indexFile = import_node_path12.default.join(filePath, "index" + ext);
|
|
5028
|
+
if (import_node_fs9.default.existsSync(indexFile)) return indexFile;
|
|
4030
5029
|
}
|
|
4031
5030
|
return null;
|
|
4032
5031
|
}
|
|
4033
|
-
function isModuleRequest(url) {
|
|
5032
|
+
function isModuleRequest(url, destination) {
|
|
4034
5033
|
const cleanUrl = url.split("?")[0];
|
|
4035
5034
|
if (/\.(ts|tsx|jsx|js|mjs|vue|css|json)$/.test(cleanUrl)) return true;
|
|
4036
5035
|
if (cleanUrl.startsWith("/@modules/")) return true;
|
|
4037
|
-
if (
|
|
5036
|
+
if (isAssetFile(cleanUrl)) {
|
|
5037
|
+
const query = url.includes("?") ? url.slice(url.indexOf("?") + 1) : "";
|
|
5038
|
+
const isExplicitAssetModule = /(?:^|&)(?:url|raw)(?:&|$)/.test(query);
|
|
5039
|
+
return isExplicitAssetModule || destination === "script";
|
|
5040
|
+
}
|
|
5041
|
+
if (!import_node_path12.default.extname(cleanUrl)) return true;
|
|
4038
5042
|
return false;
|
|
4039
5043
|
}
|
|
4040
5044
|
function getHmrClientCode() {
|
|
4041
5045
|
return `
|
|
4042
5046
|
// Nasti HMR Client
|
|
4043
|
-
const
|
|
5047
|
+
const socketProtocol = location.protocol === 'https:' ? 'wss' : 'ws';
|
|
5048
|
+
const socket = new WebSocket(socketProtocol + '://' + location.host, 'nasti-hmr');
|
|
4044
5049
|
const hotModulesMap = new Map();
|
|
4045
5050
|
const disposeMap = new Map();
|
|
4046
5051
|
const pruneMap = new Map();
|
|
5052
|
+
const dataMap = new Map();
|
|
5053
|
+
const customListenersMap = new Map();
|
|
5054
|
+
let updateQueue = [];
|
|
5055
|
+
let pendingUpdateQueue = false;
|
|
4047
5056
|
|
|
4048
5057
|
socket.addEventListener('message', async ({ data }) => {
|
|
4049
5058
|
const payload = JSON.parse(data);
|
|
5059
|
+
// \u9ED8\u8BA4\u6D4F\u89C8\u5668 client \u53EA\u6D88\u8D39\u81EA\u5DF1\u7684 HMR \u6D88\u606F\uFF1Bnative/worker \u73AF\u5883\u901A\u8FC7\u5404\u81EA\u7684
|
|
5060
|
+
// HotChannel \u6216 app-level HMR \u534F\u8C03\u5668\u5904\u7406\u540C\u4E00 transport \u4E0A\u7684\u547D\u540D\u6D88\u606F\u3002
|
|
5061
|
+
if (payload.environment && payload.environment !== 'client') return;
|
|
4050
5062
|
switch (payload.type) {
|
|
4051
5063
|
case 'connected':
|
|
4052
|
-
console.
|
|
5064
|
+
console.debug('[nasti] connected.');
|
|
4053
5065
|
clearErrorOverlay();
|
|
4054
5066
|
break;
|
|
4055
5067
|
case 'update':
|
|
4056
5068
|
try {
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
} else if (update.type === 'css-update') {
|
|
4061
|
-
return updateCss(update.path);
|
|
4062
|
-
}
|
|
4063
|
-
}));
|
|
5069
|
+
// CSS \u5728 unbundled \u6A21\u5F0F\u4E0B\u4E5F\u662F\u4F1A\u6CE8\u5165 <style> \u7684 JS \u6A21\u5757\uFF0C\u548C\u666E\u901A JS
|
|
5070
|
+
// \u4E00\u6837\u91CD\u65B0 import \u624D\u80FD\u6267\u884C dispose/accept \u5E76\u4FDD\u6301\u9875\u9762\u72B6\u6001\u3002
|
|
5071
|
+
await Promise.all(payload.updates.map(queueUpdate));
|
|
4064
5072
|
clearErrorOverlay();
|
|
4065
|
-
console.
|
|
4066
|
-
location.reload();
|
|
5073
|
+
console.debug('[nasti] HMR update complete.');
|
|
4067
5074
|
} catch (err) {
|
|
4068
5075
|
console.error('[nasti] HMR update failed:', err);
|
|
4069
5076
|
showErrorOverlay(err);
|
|
@@ -4074,11 +5081,34 @@ socket.addEventListener('message', async ({ data }) => {
|
|
|
4074
5081
|
location.reload();
|
|
4075
5082
|
break;
|
|
4076
5083
|
case 'prune':
|
|
4077
|
-
payload.paths.
|
|
4078
|
-
const
|
|
4079
|
-
|
|
4080
|
-
|
|
5084
|
+
await Promise.all(payload.paths.map(async (path) => {
|
|
5085
|
+
const data = dataMap.get(path);
|
|
5086
|
+
const dispose = disposeMap.get(path);
|
|
5087
|
+
const prune = pruneMap.get(path);
|
|
5088
|
+
if (dispose) await dispose(data);
|
|
5089
|
+
if (prune) await prune(data);
|
|
5090
|
+
hotModulesMap.delete(path);
|
|
5091
|
+
disposeMap.delete(path);
|
|
5092
|
+
pruneMap.delete(path);
|
|
5093
|
+
dataMap.delete(path);
|
|
5094
|
+
clearCustomListeners(path);
|
|
5095
|
+
}));
|
|
4081
5096
|
break;
|
|
5097
|
+
case 'custom': {
|
|
5098
|
+
const listenersByOwner = customListenersMap.get(payload.event);
|
|
5099
|
+
if (!listenersByOwner) break;
|
|
5100
|
+
const results = await Promise.allSettled(
|
|
5101
|
+
[...listenersByOwner.values()]
|
|
5102
|
+
.flatMap((listeners) => [...listeners])
|
|
5103
|
+
.map((listener) => Promise.resolve().then(() => listener(payload.data)))
|
|
5104
|
+
);
|
|
5105
|
+
for (const result of results) {
|
|
5106
|
+
if (result.status === 'rejected') {
|
|
5107
|
+
console.error('[nasti] custom HMR event listener failed:', result.reason);
|
|
5108
|
+
}
|
|
5109
|
+
}
|
|
5110
|
+
break;
|
|
5111
|
+
}
|
|
4082
5112
|
case 'error':
|
|
4083
5113
|
console.error('[nasti] error:', payload.err.message);
|
|
4084
5114
|
showErrorOverlay(payload.err);
|
|
@@ -4086,33 +5116,64 @@ socket.addEventListener('message', async ({ data }) => {
|
|
|
4086
5116
|
}
|
|
4087
5117
|
});
|
|
4088
5118
|
|
|
4089
|
-
// \
|
|
5119
|
+
// \u670D\u52A1\u91CD\u542F\u540E\u65E7\u6A21\u5757\u56FE\u5DF2\u5931\u6548\uFF0C\u91CD\u8FDE\u65F6\u6574\u9875\u5237\u65B0\u662F\u5FC5\u8981\u515C\u5E95\uFF1B\u6B63\u5E38 update \u4E0D\u518D\u5237\u65B0\u3002
|
|
4090
5120
|
let reconnectTimer = 0;
|
|
4091
5121
|
socket.addEventListener('close', () => {
|
|
4092
5122
|
clearTimeout(reconnectTimer);
|
|
4093
5123
|
reconnectTimer = setTimeout(() => location.reload(), 1000);
|
|
4094
5124
|
});
|
|
4095
5125
|
|
|
5126
|
+
/**
|
|
5127
|
+
* \u540C\u4E00\u6279\u66F4\u65B0\u5148\u5168\u90E8\u62C9\u53D6\uFF0C\u518D\u6309\u670D\u52A1\u7AEF\u6D88\u606F\u987A\u5E8F\u6267\u884C accept \u56DE\u8C03\uFF0C\u907F\u514D HTTP \u5F80\u8FD4\u901F\u5EA6
|
|
5128
|
+
* \u6539\u53D8\u6A21\u5757\u5E94\u7528\u987A\u5E8F\u3002\u8FD9\u4E0E Vite HMRClient \u7684 fetch/apply \u4E24\u9636\u6BB5\u4E00\u81F4\u3002
|
|
5129
|
+
*/
|
|
5130
|
+
async function queueUpdate(update) {
|
|
5131
|
+
updateQueue.push(fetchUpdate(update));
|
|
5132
|
+
if (pendingUpdateQueue) return;
|
|
5133
|
+
|
|
5134
|
+
pendingUpdateQueue = true;
|
|
5135
|
+
await Promise.resolve();
|
|
5136
|
+
pendingUpdateQueue = false;
|
|
5137
|
+
const loading = updateQueue;
|
|
5138
|
+
updateQueue = [];
|
|
5139
|
+
const applyUpdates = await Promise.all(loading);
|
|
5140
|
+
for (const apply of applyUpdates) {
|
|
5141
|
+
if (apply) apply();
|
|
5142
|
+
}
|
|
5143
|
+
}
|
|
5144
|
+
|
|
4096
5145
|
async function fetchUpdate(update) {
|
|
4097
5146
|
const mod = hotModulesMap.get(update.path);
|
|
4098
|
-
// \
|
|
4099
|
-
|
|
4100
|
-
if (dispose) dispose();
|
|
5147
|
+
// \u5C1A\u672A\u5728\u5F53\u524D\u9875\u9762\u52A0\u8F7D\u7684\u52A8\u6001\u6A21\u5757\u4E0D\u9700\u8981\u66F4\u65B0\u3002
|
|
5148
|
+
if (!mod) return;
|
|
4101
5149
|
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
5150
|
+
// \u5FC5\u987B\u5728\u91CD\u65B0 import \u524D\u786E\u5B9A\u65E7\u56DE\u8C03\uFF1B\u65B0\u6A21\u5757\u6267\u884C createHotContext \u65F6\u4F1A\u6E05\u7A7A\u5E76\u6CE8\u518C\u65B0\u56DE\u8C03\u3002
|
|
5151
|
+
const qualifiedCallbacks = mod.callbacks.filter(({ deps }) =>
|
|
5152
|
+
deps.includes(update.acceptedPath)
|
|
5153
|
+
);
|
|
5154
|
+
const isSelfUpdate = update.path === update.acceptedPath;
|
|
5155
|
+
if (!isSelfUpdate && qualifiedCallbacks.length === 0) return;
|
|
5156
|
+
|
|
5157
|
+
const dispose = disposeMap.get(update.acceptedPath);
|
|
5158
|
+
if (dispose) await dispose(dataMap.get(update.acceptedPath));
|
|
5159
|
+
const newMod = await import(appendTimestampQuery(update.acceptedPath, update.timestamp));
|
|
5160
|
+
|
|
5161
|
+
return () => {
|
|
5162
|
+
for (const { deps, fn } of qualifiedCallbacks) {
|
|
5163
|
+
fn(deps.map((dep) => dep === update.acceptedPath ? newMod : undefined));
|
|
5164
|
+
}
|
|
5165
|
+
const detail = isSelfUpdate
|
|
5166
|
+
? update.path
|
|
5167
|
+
: update.acceptedPath + ' via ' + update.path;
|
|
5168
|
+
console.debug('[nasti] hot updated:', detail);
|
|
5169
|
+
};
|
|
4107
5170
|
}
|
|
4108
5171
|
|
|
4109
|
-
function
|
|
4110
|
-
const
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
.then(css => { el.textContent = css; });
|
|
4115
|
-
}
|
|
5172
|
+
function appendTimestampQuery(url, timestamp) {
|
|
5173
|
+
const hashIndex = url.indexOf('#');
|
|
5174
|
+
const hash = hashIndex >= 0 ? url.slice(hashIndex) : '';
|
|
5175
|
+
const withoutHash = hashIndex >= 0 ? url.slice(0, hashIndex) : url;
|
|
5176
|
+
return withoutHash + (withoutHash.includes('?') ? '&' : '?') + 't=' + timestamp + hash;
|
|
4116
5177
|
}
|
|
4117
5178
|
|
|
4118
5179
|
function clearErrorOverlay() {
|
|
@@ -4140,23 +5201,31 @@ function showErrorOverlay(err) {
|
|
|
4140
5201
|
document.body.appendChild(overlay);
|
|
4141
5202
|
}
|
|
4142
5203
|
|
|
4143
|
-
/**
|
|
4144
|
-
* \u751F\u6210 import.meta.hot \u7684 hot context\u3002
|
|
4145
|
-
* \u5173\u952E\u7EA6\u675F\uFF1A\u540C\u4E00 ownerPath \u7684 accept \u56DE\u8C03\u5FC5\u987B\u66FF\u6362\uFF08\u4E0D\u662F append\uFF09\u3002
|
|
4146
|
-
* \u6BCF\u6B21\u6A21\u5757\u91CD\u65B0 import \u90FD\u4F1A\u8C03\u7528 createHotContext\uFF0C\u65E7\u56DE\u8C03\u4F1A\u88AB fetchUpdate \u8C03\u7528\u540E\u7ACB\u5373\u88AB\u65B0 import
|
|
4147
|
-
* \u91CC\u7684 accept \u66FF\u6362\u3002\u4E0D\u66FF\u6362\u7684\u8BDD\u6BCF\u7F16\u8F91\u4E00\u6B21\u5C31\u591A\u4E00\u4E2A\u56DE\u8C03\uFF0C\u8D8A\u8DD1\u8D8A\u6162\u3002
|
|
4148
|
-
*/
|
|
4149
5204
|
export function createHotContext(ownerPath) {
|
|
5205
|
+
if (!dataMap.has(ownerPath)) dataMap.set(ownerPath, {});
|
|
5206
|
+
|
|
5207
|
+
// \u6A21\u5757\u91CD\u65B0\u6267\u884C\u65F6\u4E22\u5F03\u65E7 accept \u56DE\u8C03\uFF0C\u4F46\u4FDD\u7559\u540C\u4E00\u4E2A hot.data \u5BF9\u8C61\u3002
|
|
5208
|
+
const existing = hotModulesMap.get(ownerPath);
|
|
5209
|
+
if (existing) existing.callbacks = [];
|
|
5210
|
+
clearCustomListeners(ownerPath);
|
|
5211
|
+
|
|
5212
|
+
const acceptDeps = (deps, callback = () => {}) => {
|
|
5213
|
+
const mod = hotModulesMap.get(ownerPath) || { id: ownerPath, callbacks: [] };
|
|
5214
|
+
mod.callbacks.push({ deps, fn: callback });
|
|
5215
|
+
hotModulesMap.set(ownerPath, mod);
|
|
5216
|
+
};
|
|
5217
|
+
|
|
4150
5218
|
return {
|
|
4151
5219
|
accept(deps, callback) {
|
|
4152
|
-
// \u81EA\u63A5\u53D7: hot.accept() \u6216 hot.accept(callback)
|
|
4153
5220
|
if (typeof deps === 'function' || deps === undefined) {
|
|
4154
|
-
|
|
4155
|
-
|
|
5221
|
+
acceptDeps([ownerPath], ([mod]) => deps?.(mod));
|
|
5222
|
+
} else if (typeof deps === 'string') {
|
|
5223
|
+
acceptDeps([deps], ([mod]) => callback?.(mod));
|
|
5224
|
+
} else if (Array.isArray(deps)) {
|
|
5225
|
+
acceptDeps(deps, callback);
|
|
5226
|
+
} else {
|
|
5227
|
+
throw new Error('invalid hot.accept() usage');
|
|
4156
5228
|
}
|
|
4157
|
-
// \u4F9D\u8D56\u63A5\u53D7: hot.accept(deps, callback)\uFF0C\u591A\u6B21\u8C03\u7528\u8FFD\u52A0
|
|
4158
|
-
const existing = hotModulesMap.get(ownerPath)?.callbacks ?? [];
|
|
4159
|
-
hotModulesMap.set(ownerPath, { callbacks: [...existing, callback] });
|
|
4160
5229
|
},
|
|
4161
5230
|
prune(callback) {
|
|
4162
5231
|
pruneMap.set(ownerPath, callback);
|
|
@@ -4164,30 +5233,122 @@ export function createHotContext(ownerPath) {
|
|
|
4164
5233
|
dispose(callback) {
|
|
4165
5234
|
disposeMap.set(ownerPath, callback);
|
|
4166
5235
|
},
|
|
5236
|
+
on(event, callback) {
|
|
5237
|
+
let listenersByOwner = customListenersMap.get(event);
|
|
5238
|
+
if (!listenersByOwner) {
|
|
5239
|
+
listenersByOwner = new Map();
|
|
5240
|
+
customListenersMap.set(event, listenersByOwner);
|
|
5241
|
+
}
|
|
5242
|
+
let listeners = listenersByOwner.get(ownerPath);
|
|
5243
|
+
if (!listeners) {
|
|
5244
|
+
listeners = new Set();
|
|
5245
|
+
listenersByOwner.set(ownerPath, listeners);
|
|
5246
|
+
}
|
|
5247
|
+
listeners.add(callback);
|
|
5248
|
+
},
|
|
5249
|
+
off(event, callback) {
|
|
5250
|
+
const listenersByOwner = customListenersMap.get(event);
|
|
5251
|
+
const listeners = listenersByOwner?.get(ownerPath);
|
|
5252
|
+
listeners?.delete(callback);
|
|
5253
|
+
if (listeners?.size === 0) listenersByOwner.delete(ownerPath);
|
|
5254
|
+
if (listenersByOwner?.size === 0) customListenersMap.delete(event);
|
|
5255
|
+
},
|
|
4167
5256
|
invalidate() {
|
|
4168
5257
|
location.reload();
|
|
4169
5258
|
},
|
|
4170
|
-
data:
|
|
5259
|
+
data: dataMap.get(ownerPath),
|
|
4171
5260
|
};
|
|
4172
5261
|
}
|
|
5262
|
+
|
|
5263
|
+
function clearCustomListeners(ownerPath) {
|
|
5264
|
+
for (const [event, listenersByOwner] of customListenersMap) {
|
|
5265
|
+
listenersByOwner.delete(ownerPath);
|
|
5266
|
+
if (listenersByOwner.size === 0) customListenersMap.delete(event);
|
|
5267
|
+
}
|
|
5268
|
+
}
|
|
4173
5269
|
`;
|
|
4174
5270
|
}
|
|
4175
|
-
var
|
|
5271
|
+
var import_node_path12, import_node_fs9, import_node_module5, import_node_url3, import_picocolors6, import_meta, __dirname_esm, __require, __refreshRuntimeCache, REACT_REFRESH_BOUNDARY_HELPERS, REACT_REFRESH_GLOBAL_PREAMBLE, esmBundleCache, VALID_IDENT, RESOLVE_EXTENSIONS, ESM_CONDITIONS;
|
|
4176
5272
|
var init_middleware = __esm({
|
|
4177
5273
|
"src/server/middleware.ts"() {
|
|
4178
5274
|
"use strict";
|
|
4179
|
-
|
|
4180
|
-
|
|
5275
|
+
import_node_path12 = __toESM(require("path"), 1);
|
|
5276
|
+
import_node_fs9 = __toESM(require("fs"), 1);
|
|
4181
5277
|
import_node_module5 = require("module");
|
|
4182
5278
|
import_node_url3 = require("url");
|
|
4183
5279
|
import_picocolors6 = __toESM(require("picocolors"), 1);
|
|
4184
5280
|
init_transformer();
|
|
4185
5281
|
init_html();
|
|
4186
5282
|
init_env();
|
|
5283
|
+
init_url();
|
|
5284
|
+
init_assets();
|
|
4187
5285
|
import_meta = {};
|
|
4188
|
-
__dirname_esm =
|
|
5286
|
+
__dirname_esm = import_node_path12.default.dirname((0, import_node_url3.fileURLToPath)(import_meta.url));
|
|
4189
5287
|
__require = (0, import_node_module5.createRequire)(import_meta.url);
|
|
4190
5288
|
__refreshRuntimeCache = null;
|
|
5289
|
+
REACT_REFRESH_BOUNDARY_HELPERS = `
|
|
5290
|
+
function __nastiIsPlainObject(obj) {
|
|
5291
|
+
return Object.prototype.toString.call(obj) === '[object Object]' &&
|
|
5292
|
+
(obj.constructor === Object || obj.constructor === undefined);
|
|
5293
|
+
}
|
|
5294
|
+
function __nastiIsCompoundComponent(type) {
|
|
5295
|
+
if (!__nastiIsPlainObject(type)) return false;
|
|
5296
|
+
for (const key in type) {
|
|
5297
|
+
if (!isLikelyComponentType(type[key])) return false;
|
|
5298
|
+
}
|
|
5299
|
+
return true;
|
|
5300
|
+
}
|
|
5301
|
+
export function registerExportsForReactRefresh(filename, moduleExports) {
|
|
5302
|
+
for (const key in moduleExports) {
|
|
5303
|
+
if (key === '__esModule') continue;
|
|
5304
|
+
const value = moduleExports[key];
|
|
5305
|
+
if (isLikelyComponentType(value)) {
|
|
5306
|
+
register(value, filename + ' export ' + key);
|
|
5307
|
+
} else if (__nastiIsCompoundComponent(value)) {
|
|
5308
|
+
for (const subKey in value) {
|
|
5309
|
+
register(value[subKey], filename + ' export ' + key + '-' + subKey);
|
|
5310
|
+
}
|
|
5311
|
+
}
|
|
5312
|
+
}
|
|
5313
|
+
}
|
|
5314
|
+
let __nastiRefreshTimer;
|
|
5315
|
+
function __nastiEnqueueRefresh() {
|
|
5316
|
+
clearTimeout(__nastiRefreshTimer);
|
|
5317
|
+
__nastiRefreshTimer = setTimeout(() => performReactRefresh(), 16);
|
|
5318
|
+
}
|
|
5319
|
+
function __nastiCheckExports(ignored, exports, predicate) {
|
|
5320
|
+
for (const key in exports) {
|
|
5321
|
+
if (ignored.includes(key)) continue;
|
|
5322
|
+
if (!predicate(key, exports[key])) return key;
|
|
5323
|
+
}
|
|
5324
|
+
return true;
|
|
5325
|
+
}
|
|
5326
|
+
export function validateRefreshBoundaryAndEnqueueUpdate(id, prevExports, nextExports) {
|
|
5327
|
+
const ignored = window.__getReactRefreshIgnoredExports?.({ id }) ?? [];
|
|
5328
|
+
if (__nastiCheckExports(ignored, prevExports, (key) => key in nextExports) !== true) {
|
|
5329
|
+
return 'Could not Fast Refresh (export removed)';
|
|
5330
|
+
}
|
|
5331
|
+
if (__nastiCheckExports(ignored, nextExports, (key) => key in prevExports) !== true) {
|
|
5332
|
+
return 'Could not Fast Refresh (new export)';
|
|
5333
|
+
}
|
|
5334
|
+
let hasExports = false;
|
|
5335
|
+
const compatible = __nastiCheckExports(ignored, nextExports, (key, value) => {
|
|
5336
|
+
hasExports = true;
|
|
5337
|
+
return isLikelyComponentType(value) ||
|
|
5338
|
+
__nastiIsCompoundComponent(value) ||
|
|
5339
|
+
prevExports[key] === value;
|
|
5340
|
+
});
|
|
5341
|
+
if (!hasExports) {
|
|
5342
|
+
return 'Could not Fast Refresh (no exports)';
|
|
5343
|
+
}
|
|
5344
|
+
if (compatible === true) {
|
|
5345
|
+
__nastiEnqueueRefresh();
|
|
5346
|
+
return;
|
|
5347
|
+
}
|
|
5348
|
+
return 'Could not Fast Refresh ("' + compatible + '" export is incompatible)';
|
|
5349
|
+
}
|
|
5350
|
+
export const __hmr_import = (module) => import(module);
|
|
5351
|
+
`;
|
|
4191
5352
|
REACT_REFRESH_GLOBAL_PREAMBLE = `
|
|
4192
5353
|
import RefreshRuntime from "/@react-refresh";
|
|
4193
5354
|
RefreshRuntime.injectIntoGlobalHook(window);
|
|
@@ -4203,28 +5364,37 @@ window.__vite_plugin_react_preamble_installed__ = true;
|
|
|
4203
5364
|
});
|
|
4204
5365
|
|
|
4205
5366
|
// src/server/hmr.ts
|
|
4206
|
-
async function handleFileChange(file, server) {
|
|
4207
|
-
const {
|
|
5367
|
+
async function handleFileChange(file, server, environmentName = "client", timestamp = Date.now()) {
|
|
5368
|
+
const { config } = server;
|
|
5369
|
+
const environment = server.environments[environmentName];
|
|
5370
|
+
if (!environment) {
|
|
5371
|
+
throw new Error(`[nasti] unknown dev environment "${environmentName}"`);
|
|
5372
|
+
}
|
|
5373
|
+
const moduleGraph = environment.moduleGraph;
|
|
4208
5374
|
const logger = config.logger;
|
|
4209
|
-
const relativePath = "/" +
|
|
4210
|
-
const shortFile =
|
|
5375
|
+
const relativePath = "/" + import_node_path13.default.relative(config.root, file);
|
|
5376
|
+
const shortFile = import_node_path13.default.relative(config.root, file);
|
|
4211
5377
|
const mods = moduleGraph.getModulesByFile(file);
|
|
4212
5378
|
if (!mods || mods.size === 0) {
|
|
4213
|
-
return;
|
|
5379
|
+
return null;
|
|
4214
5380
|
}
|
|
4215
5381
|
const updates = [];
|
|
4216
|
-
const
|
|
5382
|
+
const graph = moduleGraph;
|
|
5383
|
+
const invalidatedModules = /* @__PURE__ */ new Set();
|
|
5384
|
+
const affectedSet = /* @__PURE__ */ new Set();
|
|
5385
|
+
let fullReload = false;
|
|
4217
5386
|
for (const mod of mods) {
|
|
4218
|
-
|
|
5387
|
+
graph.invalidateModuleAndImporters(mod, timestamp, invalidatedModules);
|
|
4219
5388
|
const ctx = {
|
|
4220
5389
|
file,
|
|
4221
5390
|
timestamp,
|
|
4222
5391
|
modules: [mod],
|
|
4223
|
-
read: () =>
|
|
4224
|
-
server
|
|
5392
|
+
read: () => import_node_fs10.default.readFileSync(file, "utf-8"),
|
|
5393
|
+
server,
|
|
5394
|
+
environment
|
|
4225
5395
|
};
|
|
4226
5396
|
let affectedModules = [mod];
|
|
4227
|
-
for (const plugin of
|
|
5397
|
+
for (const plugin of environment.plugins) {
|
|
4228
5398
|
if (plugin.handleHotUpdate) {
|
|
4229
5399
|
const result = await plugin.handleHotUpdate(ctx);
|
|
4230
5400
|
if (result) {
|
|
@@ -4233,36 +5403,59 @@ async function handleFileChange(file, server) {
|
|
|
4233
5403
|
}
|
|
4234
5404
|
}
|
|
4235
5405
|
for (const affected of affectedModules) {
|
|
4236
|
-
|
|
5406
|
+
affectedSet.add(affected);
|
|
5407
|
+
graph.invalidateModuleAndImporters(affected, timestamp, invalidatedModules);
|
|
5408
|
+
const boundaries = graph.getHmrBoundaries(affected);
|
|
4237
5409
|
if (boundaries.length === 0) {
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
return;
|
|
5410
|
+
fullReload = true;
|
|
5411
|
+
continue;
|
|
4241
5412
|
}
|
|
4242
|
-
for (const { boundary } of boundaries) {
|
|
4243
|
-
|
|
5413
|
+
for (const { boundary, acceptedVia } of boundaries) {
|
|
5414
|
+
const update = {
|
|
4244
5415
|
type: boundary.type === "css" ? "css-update" : "js-update",
|
|
4245
5416
|
path: boundary.url,
|
|
4246
|
-
acceptedPath:
|
|
5417
|
+
acceptedPath: acceptedVia.url,
|
|
4247
5418
|
timestamp
|
|
4248
|
-
}
|
|
5419
|
+
};
|
|
5420
|
+
if (!updates.some(
|
|
5421
|
+
(existing) => existing.type === update.type && existing.path === update.path && existing.acceptedPath === update.acceptedPath
|
|
5422
|
+
)) {
|
|
5423
|
+
updates.push(update);
|
|
5424
|
+
}
|
|
4249
5425
|
}
|
|
4250
5426
|
}
|
|
4251
5427
|
}
|
|
4252
|
-
|
|
5428
|
+
const transformed = await Promise.all(
|
|
5429
|
+
[...affectedSet].map(async (module2) => ({
|
|
5430
|
+
module: module2,
|
|
5431
|
+
result: await environment.transformRequest(module2.url)
|
|
5432
|
+
}))
|
|
5433
|
+
);
|
|
5434
|
+
const logPrefix = environmentName === "client" ? "" : `[${environmentName}] `;
|
|
5435
|
+
if (fullReload) {
|
|
5436
|
+
logger.info(import_picocolors7.default.green(`${logPrefix}reload `) + import_picocolors7.default.dim(shortFile), { timestamp: true });
|
|
5437
|
+
environment.hot.send({ type: "full-reload", path: relativePath });
|
|
5438
|
+
} else if (updates.length > 0) {
|
|
4253
5439
|
logger.info(
|
|
4254
|
-
updates.map((u) => import_picocolors7.default.green(
|
|
5440
|
+
updates.map((u) => import_picocolors7.default.green(`${logPrefix}hmr update `) + import_picocolors7.default.dim(u.path)).join("\n"),
|
|
4255
5441
|
{ timestamp: true }
|
|
4256
5442
|
);
|
|
4257
|
-
|
|
5443
|
+
environment.hot.send({ type: "update", updates });
|
|
4258
5444
|
}
|
|
5445
|
+
return {
|
|
5446
|
+
environment,
|
|
5447
|
+
modules: [...affectedSet],
|
|
5448
|
+
updates,
|
|
5449
|
+
transformed,
|
|
5450
|
+
fullReload
|
|
5451
|
+
};
|
|
4259
5452
|
}
|
|
4260
|
-
var
|
|
5453
|
+
var import_node_path13, import_node_fs10, import_picocolors7;
|
|
4261
5454
|
var init_hmr = __esm({
|
|
4262
5455
|
"src/server/hmr.ts"() {
|
|
4263
5456
|
"use strict";
|
|
4264
|
-
|
|
4265
|
-
|
|
5457
|
+
import_node_path13 = __toESM(require("path"), 1);
|
|
5458
|
+
import_node_fs10 = __toESM(require("fs"), 1);
|
|
4266
5459
|
import_picocolors7 = __toESM(require("picocolors"), 1);
|
|
4267
5460
|
}
|
|
4268
5461
|
});
|
|
@@ -4281,18 +5474,18 @@ function createModuleRunner(environment) {
|
|
|
4281
5474
|
}
|
|
4282
5475
|
return new NastiModuleRunner(environment);
|
|
4283
5476
|
}
|
|
4284
|
-
var
|
|
5477
|
+
var import_node_path14, import_node_fs11, import_node_module6, import_node_url4, debug6, NODE_BUILTINS3, NastiModuleRunner, AsyncFunction;
|
|
4285
5478
|
var init_runnable_environment = __esm({
|
|
4286
5479
|
"src/server/runnable-environment.ts"() {
|
|
4287
5480
|
"use strict";
|
|
4288
|
-
|
|
4289
|
-
|
|
5481
|
+
import_node_path14 = __toESM(require("path"), 1);
|
|
5482
|
+
import_node_fs11 = __toESM(require("fs"), 1);
|
|
4290
5483
|
import_node_module6 = require("module");
|
|
4291
5484
|
import_node_url4 = require("url");
|
|
4292
5485
|
init_transformer();
|
|
4293
5486
|
init_env();
|
|
4294
5487
|
init_debug();
|
|
4295
|
-
|
|
5488
|
+
debug6 = createDebugger("nasti:ssr");
|
|
4296
5489
|
NODE_BUILTINS3 = /* @__PURE__ */ new Set([...import_node_module6.builtinModules, ...import_node_module6.builtinModules.map((m) => `node:${m}`)]);
|
|
4297
5490
|
NastiModuleRunner = class {
|
|
4298
5491
|
environment;
|
|
@@ -4308,7 +5501,7 @@ var init_runnable_environment = __esm({
|
|
|
4308
5501
|
this.config.mode,
|
|
4309
5502
|
ssrDefineOverrides(environment.consumer)
|
|
4310
5503
|
);
|
|
4311
|
-
this.require = (0, import_node_module6.createRequire)(
|
|
5504
|
+
this.require = (0, import_node_module6.createRequire)(import_node_path14.default.join(this.config.root, "package.json"));
|
|
4312
5505
|
const handlers = {
|
|
4313
5506
|
fetchModule: async (id, importer) => this.fetchModule(id, importer),
|
|
4314
5507
|
getBuiltins: () => [/^node:/, ...import_node_module6.builtinModules]
|
|
@@ -4332,9 +5525,9 @@ var init_runnable_environment = __esm({
|
|
|
4332
5525
|
this.cache.clear();
|
|
4333
5526
|
}
|
|
4334
5527
|
resolveToId(rawUrl) {
|
|
4335
|
-
if (
|
|
5528
|
+
if (import_node_path14.default.isAbsolute(rawUrl) && import_node_fs11.default.existsSync(rawUrl.split("?")[0])) return rawUrl;
|
|
4336
5529
|
const clean = rawUrl.replace(/^\//, "");
|
|
4337
|
-
return
|
|
5530
|
+
return import_node_path14.default.resolve(this.config.root, clean);
|
|
4338
5531
|
}
|
|
4339
5532
|
/**
|
|
4340
5533
|
* fetchModule(invoke 契约方法):环境管线产出 runner 可执行代码。
|
|
@@ -4343,14 +5536,14 @@ var init_runnable_environment = __esm({
|
|
|
4343
5536
|
*/
|
|
4344
5537
|
async fetchModule(id, importer) {
|
|
4345
5538
|
if (NODE_BUILTINS3.has(id)) return { externalize: id };
|
|
4346
|
-
if (!id.startsWith(".") && !
|
|
5539
|
+
if (!id.startsWith(".") && !import_node_path14.default.isAbsolute(id) && !id.startsWith("\0")) {
|
|
4347
5540
|
return { externalize: id };
|
|
4348
5541
|
}
|
|
4349
5542
|
const container = this.environment.pluginContainer;
|
|
4350
5543
|
let resolvedId = id;
|
|
4351
5544
|
if (id.startsWith(".") && importer) {
|
|
4352
5545
|
const resolved = await container.resolveId(id, importer);
|
|
4353
|
-
resolvedId = resolved ? typeof resolved === "string" ? resolved : resolved.id :
|
|
5546
|
+
resolvedId = resolved ? typeof resolved === "string" ? resolved : resolved.id : import_node_path14.default.resolve(import_node_path14.default.dirname(importer.split("?")[0]), id);
|
|
4354
5547
|
}
|
|
4355
5548
|
resolvedId = this.completeExtension(resolvedId);
|
|
4356
5549
|
const cleanId = resolvedId.split("?")[0];
|
|
@@ -4358,8 +5551,8 @@ var init_runnable_environment = __esm({
|
|
|
4358
5551
|
const loaded = await container.load(resolvedId);
|
|
4359
5552
|
if (loaded != null) {
|
|
4360
5553
|
code = typeof loaded === "string" ? loaded : loaded.code;
|
|
4361
|
-
} else if (
|
|
4362
|
-
code =
|
|
5554
|
+
} else if (import_node_fs11.default.existsSync(cleanId)) {
|
|
5555
|
+
code = import_node_fs11.default.readFileSync(cleanId, "utf-8");
|
|
4363
5556
|
} else {
|
|
4364
5557
|
throw new Error(`[nasti:ssr] cannot load module: ${resolvedId}`);
|
|
4365
5558
|
}
|
|
@@ -4370,6 +5563,7 @@ var init_runnable_environment = __esm({
|
|
|
4370
5563
|
if (shouldTransform(cleanId)) {
|
|
4371
5564
|
const result = transformCode(cleanId, code, {
|
|
4372
5565
|
sourcemap: false,
|
|
5566
|
+
target: this.environment.options.build.target,
|
|
4373
5567
|
jsxRuntime: "automatic",
|
|
4374
5568
|
jsxImportSource: this.config.framework === "vue" ? "vue" : "react"
|
|
4375
5569
|
});
|
|
@@ -4386,25 +5580,25 @@ var init_runnable_environment = __esm({
|
|
|
4386
5580
|
);
|
|
4387
5581
|
}
|
|
4388
5582
|
const runnerResult = await moduleRunnerTransform(resolvedId, code);
|
|
4389
|
-
|
|
5583
|
+
debug6?.(`fetchModule ${resolvedId} (${runnerResult.deps?.length ?? 0} deps)`);
|
|
4390
5584
|
return { id: resolvedId, code: runnerResult.code };
|
|
4391
5585
|
}
|
|
4392
5586
|
completeExtension(id) {
|
|
4393
5587
|
const clean = id.split("?")[0];
|
|
4394
5588
|
const query = id.includes("?") ? id.slice(id.indexOf("?")) : "";
|
|
4395
|
-
if (
|
|
5589
|
+
if (import_node_fs11.default.existsSync(clean) && import_node_fs11.default.statSync(clean).isFile()) return id;
|
|
4396
5590
|
const jsMatch = clean.match(/^(.*)\.([mc]?)jsx?$/);
|
|
4397
5591
|
if (jsMatch) {
|
|
4398
5592
|
for (const tsExt of [`.${jsMatch[2]}ts`, `.${jsMatch[2]}tsx`]) {
|
|
4399
|
-
if (
|
|
5593
|
+
if (import_node_fs11.default.existsSync(jsMatch[1] + tsExt)) return jsMatch[1] + tsExt + query;
|
|
4400
5594
|
}
|
|
4401
5595
|
}
|
|
4402
5596
|
for (const ext of this.config.resolve.extensions) {
|
|
4403
|
-
if (
|
|
5597
|
+
if (import_node_fs11.default.existsSync(clean + ext)) return clean + ext + query;
|
|
4404
5598
|
}
|
|
4405
5599
|
for (const ext of this.config.resolve.extensions) {
|
|
4406
|
-
const indexPath =
|
|
4407
|
-
if (
|
|
5600
|
+
const indexPath = import_node_path14.default.join(clean, `index${ext}`);
|
|
5601
|
+
if (import_node_fs11.default.existsSync(indexPath)) return indexPath;
|
|
4408
5602
|
}
|
|
4409
5603
|
return id;
|
|
4410
5604
|
}
|
|
@@ -4431,10 +5625,10 @@ var init_runnable_environment = __esm({
|
|
|
4431
5625
|
return;
|
|
4432
5626
|
}
|
|
4433
5627
|
const ssrImport = async (dep) => {
|
|
4434
|
-
if (NODE_BUILTINS3.has(dep) || !dep.startsWith(".") && !
|
|
5628
|
+
if (NODE_BUILTINS3.has(dep) || !dep.startsWith(".") && !import_node_path14.default.isAbsolute(dep) && !dep.startsWith("\0")) {
|
|
4435
5629
|
return this.importExternal(dep);
|
|
4436
5630
|
}
|
|
4437
|
-
const depId = dep.startsWith(".") ? this.completeExtension(
|
|
5631
|
+
const depId = dep.startsWith(".") ? this.completeExtension(import_node_path14.default.resolve(import_node_path14.default.dirname(fetched.id.split("?")[0]), dep)) : this.completeExtension(dep);
|
|
4438
5632
|
return this.instantiate(depId);
|
|
4439
5633
|
};
|
|
4440
5634
|
const ssrExportAll = (sourceModule) => {
|
|
@@ -4466,7 +5660,7 @@ var init_runnable_environment = __esm({
|
|
|
4466
5660
|
}
|
|
4467
5661
|
async importExternal(spec) {
|
|
4468
5662
|
try {
|
|
4469
|
-
return await (spec.startsWith("node:") || !
|
|
5663
|
+
return await (spec.startsWith("node:") || !import_node_path14.default.isAbsolute(spec) ? import(this.resolveExternalSpecifier(spec)) : import((0, import_node_url4.pathToFileURL)(spec).href));
|
|
4470
5664
|
} catch (err) {
|
|
4471
5665
|
throw new Error(`[nasti:ssr] failed to import external "${spec}": ${err.message}`);
|
|
4472
5666
|
}
|
|
@@ -4506,7 +5700,7 @@ async function createBundledDevServer(opts) {
|
|
|
4506
5700
|
}
|
|
4507
5701
|
} catch (err) {
|
|
4508
5702
|
throw new Error(
|
|
4509
|
-
`[nasti] experimental.bundledDev requires rolldown's experimental dev() API (locked
|
|
5703
|
+
`[nasti] experimental.bundledDev requires rolldown's experimental dev() API (locked version is incompatible; got: ${err.message}). Remove --bundle / experimental.bundledDev to use the default unbundled dev server.`
|
|
4510
5704
|
);
|
|
4511
5705
|
}
|
|
4512
5706
|
const html = await readHtmlFile(config.root, config.environments.client?.html);
|
|
@@ -4524,7 +5718,7 @@ async function createBundledDevServer(opts) {
|
|
|
4524
5718
|
createReactRefreshRuntimePlugin(entryPoints),
|
|
4525
5719
|
createBundledOxcRefreshPlugin()
|
|
4526
5720
|
] : [],
|
|
4527
|
-
...stripCatchAllLoad(toRolldownPlugins(clientEnv.plugins)),
|
|
5721
|
+
...stripCatchAllLoad(toRolldownPlugins(clientEnv.plugins, clientEnv)),
|
|
4528
5722
|
...useReactRefresh ? [
|
|
4529
5723
|
refreshWrapperFn({
|
|
4530
5724
|
cwd: config.root,
|
|
@@ -4559,7 +5753,7 @@ async function createBundledDevServer(opts) {
|
|
|
4559
5753
|
for (const { clientId, update } of updates) {
|
|
4560
5754
|
if (update.type === "Noop") continue;
|
|
4561
5755
|
if (update.type === "FullReload") {
|
|
4562
|
-
|
|
5756
|
+
debug7?.(`full reload for ${clientId}: ${update.reason ?? ""}`);
|
|
4563
5757
|
needsLatestOutput = true;
|
|
4564
5758
|
continue;
|
|
4565
5759
|
}
|
|
@@ -4573,7 +5767,7 @@ async function createBundledDevServer(opts) {
|
|
|
4573
5767
|
}
|
|
4574
5768
|
const url = `/${patchPath}`;
|
|
4575
5769
|
logger.info(
|
|
4576
|
-
import_picocolors8.default.green("hmr update ") + import_picocolors8.default.dim(changedFiles.map((f) =>
|
|
5770
|
+
import_picocolors8.default.green("hmr update ") + import_picocolors8.default.dim(changedFiles.map((f) => import_node_path15.default.relative(config.root, f)).join(", ")),
|
|
4577
5771
|
{ timestamp: true }
|
|
4578
5772
|
);
|
|
4579
5773
|
sendTo(clientId, { type: "hmr:update", path: url, url });
|
|
@@ -4609,7 +5803,7 @@ async function createBundledDevServer(opts) {
|
|
|
4609
5803
|
},
|
|
4610
5804
|
{
|
|
4611
5805
|
watch: { skipWrite: true },
|
|
4612
|
-
rebuildStrategy: "
|
|
5806
|
+
rebuildStrategy: "never",
|
|
4613
5807
|
onOutput(result) {
|
|
4614
5808
|
if (result instanceof Error) {
|
|
4615
5809
|
logger.error(import_picocolors8.default.red(`[bundled] build error: ${result.message}`), { error: result });
|
|
@@ -4625,7 +5819,13 @@ async function createBundledDevServer(opts) {
|
|
|
4625
5819
|
memoryFiles.set(`${file.fileName}.map`, JSON.stringify(file.map));
|
|
4626
5820
|
}
|
|
4627
5821
|
}
|
|
4628
|
-
|
|
5822
|
+
debug7?.(`bundle output refreshed (${result.output.length} files)`);
|
|
5823
|
+
},
|
|
5824
|
+
onAdditionalAssets(result) {
|
|
5825
|
+
for (const file of result.output) {
|
|
5826
|
+
const content = file.type === "chunk" ? file.code : file.source;
|
|
5827
|
+
if (content != null) memoryFiles.set(file.fileName, content);
|
|
5828
|
+
}
|
|
4629
5829
|
},
|
|
4630
5830
|
async onHmrUpdates(result) {
|
|
4631
5831
|
if (result instanceof Error) {
|
|
@@ -4634,7 +5834,7 @@ async function createBundledDevServer(opts) {
|
|
|
4634
5834
|
return;
|
|
4635
5835
|
}
|
|
4636
5836
|
const { updates, changedFiles } = result;
|
|
4637
|
-
|
|
5837
|
+
debug7?.(
|
|
4638
5838
|
`onHmrUpdates(engine watcher): ${changedFiles.length} changed, ${updates.length} updates`
|
|
4639
5839
|
);
|
|
4640
5840
|
if (changedFiles.length === 0) return;
|
|
@@ -4653,24 +5853,29 @@ async function createBundledDevServer(opts) {
|
|
|
4653
5853
|
if (!clientId) return;
|
|
4654
5854
|
wss.handleUpgrade(req, socket, head, (ws) => {
|
|
4655
5855
|
bundledClients.set(clientId, ws);
|
|
4656
|
-
|
|
4657
|
-
|
|
5856
|
+
debug7?.(`bundled client connected: ${clientId}`);
|
|
5857
|
+
void engine.registerClient(clientId).then(async () => {
|
|
5858
|
+
for (const fileName of entryFileNames.values()) {
|
|
5859
|
+
await engine.notifyPayloadDelivered(fileName);
|
|
5860
|
+
}
|
|
5861
|
+
ws.send(JSON.stringify({ type: "connected" }));
|
|
5862
|
+
}).catch((err) => {
|
|
5863
|
+
debug7?.(`registerClient failed for ${clientId}: ${err?.message ?? err}`);
|
|
5864
|
+
ws.close();
|
|
5865
|
+
});
|
|
4658
5866
|
ws.on("message", async (raw) => {
|
|
4659
5867
|
try {
|
|
4660
5868
|
const msg = JSON.parse(String(raw));
|
|
4661
|
-
if (msg.type === "hmr:
|
|
4662
|
-
await engine.registerModules(clientId, msg.modules);
|
|
4663
|
-
debug6?.(`registered ${msg.modules.length} modules for ${clientId}`);
|
|
4664
|
-
} else if (msg.type === "hmr:invalidate") {
|
|
5869
|
+
if (msg.type === "hmr:invalidate") {
|
|
4665
5870
|
scheduleFullReload();
|
|
4666
5871
|
}
|
|
4667
5872
|
} catch (err) {
|
|
4668
|
-
|
|
5873
|
+
debug7?.(`bundled ws message error: ${err.message}`);
|
|
4669
5874
|
}
|
|
4670
5875
|
});
|
|
4671
5876
|
ws.on("close", () => {
|
|
4672
5877
|
bundledClients.delete(clientId);
|
|
4673
|
-
engine.removeClient(clientId).catch((err) =>
|
|
5878
|
+
engine.removeClient(clientId).catch((err) => debug7?.(`removeClient failed for ${clientId}: ${err?.message ?? err}`));
|
|
4674
5879
|
});
|
|
4675
5880
|
});
|
|
4676
5881
|
});
|
|
@@ -4687,10 +5892,18 @@ async function createBundledDevServer(opts) {
|
|
|
4687
5892
|
res.end("// [nasti] lazy endpoint requires id & clientId");
|
|
4688
5893
|
return;
|
|
4689
5894
|
}
|
|
4690
|
-
const
|
|
5895
|
+
const output = await engine.compileEntry(id, clientId);
|
|
5896
|
+
if (output.sourcemap && output.sourcemapFilename) {
|
|
5897
|
+
memoryFiles.set(output.sourcemapFilename, output.sourcemap);
|
|
5898
|
+
}
|
|
5899
|
+
res.once("finish", () => {
|
|
5900
|
+
void engine.notifyPayloadDelivered(output.filename).catch(
|
|
5901
|
+
(err) => debug7?.(`notifyPayloadDelivered failed: ${err?.message ?? err}`)
|
|
5902
|
+
);
|
|
5903
|
+
});
|
|
4691
5904
|
res.setHeader("Content-Type", "application/javascript");
|
|
4692
5905
|
res.setHeader("Cache-Control", "no-store");
|
|
4693
|
-
res.end(code + "\n;export {}");
|
|
5906
|
+
res.end(output.code + "\n;export {}");
|
|
4694
5907
|
return;
|
|
4695
5908
|
}
|
|
4696
5909
|
const patchHit = patches.get(pathname.replace(/^\//, ""));
|
|
@@ -4709,8 +5922,13 @@ async function createBundledDevServer(opts) {
|
|
|
4709
5922
|
return;
|
|
4710
5923
|
}
|
|
4711
5924
|
res.setHeader("ETag", hit.etag);
|
|
4712
|
-
res.setHeader("Content-Type", MIME_TYPES[
|
|
5925
|
+
res.setHeader("Content-Type", MIME_TYPES[import_node_path15.default.extname(fileName)] ?? "application/octet-stream");
|
|
4713
5926
|
res.setHeader("Cache-Control", "no-cache");
|
|
5927
|
+
res.once("finish", () => {
|
|
5928
|
+
void engine.notifyPayloadDelivered(fileName).catch(
|
|
5929
|
+
(err) => debug7?.(`notifyPayloadDelivered failed: ${err?.message ?? err}`)
|
|
5930
|
+
);
|
|
5931
|
+
});
|
|
4714
5932
|
res.end(hit.content);
|
|
4715
5933
|
return;
|
|
4716
5934
|
}
|
|
@@ -4745,7 +5963,7 @@ function stripCatchAllLoad(plugins) {
|
|
|
4745
5963
|
);
|
|
4746
5964
|
}
|
|
4747
5965
|
function createReactRefreshRuntimePlugin(entryPoints) {
|
|
4748
|
-
const entryIds = new Set(entryPoints.map((p) =>
|
|
5966
|
+
const entryIds = new Set(entryPoints.map((p) => import_node_path15.default.resolve(p)));
|
|
4749
5967
|
return {
|
|
4750
5968
|
name: "nasti:bundled-react-refresh",
|
|
4751
5969
|
resolveId(source) {
|
|
@@ -4763,7 +5981,7 @@ function createReactRefreshRuntimePlugin(entryPoints) {
|
|
|
4763
5981
|
return null;
|
|
4764
5982
|
},
|
|
4765
5983
|
transform(code, id) {
|
|
4766
|
-
if (!entryIds.has(
|
|
5984
|
+
if (!entryIds.has(import_node_path15.default.resolve(id.split("?")[0]))) return null;
|
|
4767
5985
|
return { code: `import ${JSON.stringify(PREAMBLE_SPEC)};
|
|
4768
5986
|
${code}`, map: null };
|
|
4769
5987
|
}
|
|
@@ -4810,11 +6028,11 @@ async function renderBundledIndexHtml(html, config, entryFileNames) {
|
|
|
4810
6028
|
}
|
|
4811
6029
|
return processed;
|
|
4812
6030
|
}
|
|
4813
|
-
var
|
|
6031
|
+
var import_node_path15, import_node_crypto3, import_ws2, import_picocolors8, debug7, MIME_TYPES, MemoryFiles, PREAMBLE_SPEC, RESOLVED_PREAMBLE_ID, REFRESH_RUNTIME_URL, BUNDLED_PREAMBLE_CODE, WRAPPER_RUNTIME_HELPERS;
|
|
4814
6032
|
var init_dev_engine = __esm({
|
|
4815
6033
|
"src/server/bundled/dev-engine.ts"() {
|
|
4816
6034
|
"use strict";
|
|
4817
|
-
|
|
6035
|
+
import_node_path15 = __toESM(require("path"), 1);
|
|
4818
6036
|
import_node_crypto3 = __toESM(require("crypto"), 1);
|
|
4819
6037
|
import_ws2 = require("ws");
|
|
4820
6038
|
import_picocolors8 = __toESM(require("picocolors"), 1);
|
|
@@ -4823,7 +6041,7 @@ var init_dev_engine = __esm({
|
|
|
4823
6041
|
init_transformer();
|
|
4824
6042
|
init_middleware();
|
|
4825
6043
|
init_debug();
|
|
4826
|
-
|
|
6044
|
+
debug7 = createDebugger("nasti:bundled");
|
|
4827
6045
|
MIME_TYPES = {
|
|
4828
6046
|
".js": "application/javascript",
|
|
4829
6047
|
".mjs": "application/javascript",
|
|
@@ -4941,14 +6159,16 @@ async function createServer(inlineConfig = {}) {
|
|
|
4941
6159
|
const startTime = performance.now();
|
|
4942
6160
|
const config = await resolveConfig(inlineConfig, "serve");
|
|
4943
6161
|
const logger = config.logger;
|
|
4944
|
-
const allPlugins = resolvePluginList(config, config.plugins
|
|
6162
|
+
const allPlugins = resolvePluginList(config, config.plugins, {
|
|
6163
|
+
environmentName: "client"
|
|
6164
|
+
});
|
|
4945
6165
|
const configWithPlugins = { ...config, plugins: allPlugins };
|
|
4946
6166
|
const app = (0, import_connect.default)();
|
|
4947
6167
|
const httpServer = import_node_http.default.createServer(app);
|
|
4948
6168
|
const ws = createWebSocketServer(httpServer);
|
|
4949
6169
|
const pluginApi = getPluginApi(config);
|
|
4950
6170
|
const clientEnv = new NastiEnvironment("client", config, {
|
|
4951
|
-
hot: createWsHotChannel(ws),
|
|
6171
|
+
hot: createWsHotChannel(ws, "client"),
|
|
4952
6172
|
mode: "dev",
|
|
4953
6173
|
plugins: allPlugins,
|
|
4954
6174
|
pluginApi
|
|
@@ -4958,15 +6178,45 @@ async function createServer(inlineConfig = {}) {
|
|
|
4958
6178
|
for (const name of Object.keys(config.environments)) {
|
|
4959
6179
|
if (name === "client") continue;
|
|
4960
6180
|
const consumer = config.environments[name].consumer;
|
|
4961
|
-
const envPlugins = resolvePluginList(config, config.plugins, {
|
|
6181
|
+
const envPlugins = resolvePluginList(config, config.plugins, {
|
|
6182
|
+
consumer,
|
|
6183
|
+
environmentName: name
|
|
6184
|
+
});
|
|
4962
6185
|
environments[name] = new NastiEnvironment(name, config, {
|
|
6186
|
+
hot: consumer === "client" ? createWsHotChannel(ws, name) : void 0,
|
|
4963
6187
|
mode: "dev",
|
|
4964
6188
|
plugins: envPlugins,
|
|
4965
6189
|
pluginApi
|
|
4966
6190
|
});
|
|
4967
6191
|
}
|
|
4968
6192
|
for (const [name, environment] of Object.entries(environments)) {
|
|
4969
|
-
if (name
|
|
6193
|
+
if (name === "client" || environment.consumer === "client" || environment.options.driver) {
|
|
6194
|
+
await environment.init();
|
|
6195
|
+
}
|
|
6196
|
+
}
|
|
6197
|
+
const transformContexts = /* @__PURE__ */ new Map();
|
|
6198
|
+
for (const environment of Object.values(environments)) {
|
|
6199
|
+
if (environment.consumer !== "client" || environment.driver) continue;
|
|
6200
|
+
const environmentConfig = {
|
|
6201
|
+
...configWithPlugins,
|
|
6202
|
+
resolve: environment.options.resolve,
|
|
6203
|
+
build: environment.options.build,
|
|
6204
|
+
plugins: environment.plugins
|
|
6205
|
+
};
|
|
6206
|
+
const context = {
|
|
6207
|
+
config: environmentConfig,
|
|
6208
|
+
pluginContainer: environment.pluginContainer,
|
|
6209
|
+
moduleGraph: environment.moduleGraph,
|
|
6210
|
+
environment,
|
|
6211
|
+
envDefine: buildEnvDefine(
|
|
6212
|
+
loadEnv(environmentConfig.mode, environmentConfig.root, environmentConfig.envPrefix),
|
|
6213
|
+
environmentConfig.mode,
|
|
6214
|
+
ssrDefineOverrides(environment.consumer)
|
|
6215
|
+
),
|
|
6216
|
+
onPrune: (paths) => environment.hot.send({ type: "prune", paths })
|
|
6217
|
+
};
|
|
6218
|
+
transformContexts.set(environment.name, context);
|
|
6219
|
+
environment.configureDevPipeline((url) => transformRequest(url, context));
|
|
4970
6220
|
}
|
|
4971
6221
|
let ssrRunner = null;
|
|
4972
6222
|
async function getSsrRunner() {
|
|
@@ -4981,7 +6231,6 @@ async function createServer(inlineConfig = {}) {
|
|
|
4981
6231
|
return ssrRunner;
|
|
4982
6232
|
}
|
|
4983
6233
|
const moduleGraph = clientEnv.moduleGraph;
|
|
4984
|
-
const pluginContainer = clientEnv.pluginContainer;
|
|
4985
6234
|
let bundledServer = null;
|
|
4986
6235
|
if (config.experimental.bundledDev) {
|
|
4987
6236
|
const { createBundledDevServer: createBundledDevServer2 } = await Promise.resolve().then(() => (init_dev_engine(), dev_engine_exports));
|
|
@@ -4993,14 +6242,14 @@ async function createServer(inlineConfig = {}) {
|
|
|
4993
6242
|
app.use(bundledServer.middleware);
|
|
4994
6243
|
}
|
|
4995
6244
|
const ignoredSegments = /* @__PURE__ */ new Set(["node_modules", ".git", ".nasti"]);
|
|
4996
|
-
const outDirAbs =
|
|
6245
|
+
const outDirAbs = import_node_path16.default.resolve(config.root, config.build.outDir);
|
|
4997
6246
|
const watcher = (0, import_chokidar.watch)(config.root, {
|
|
4998
6247
|
ignored: (filePath) => {
|
|
4999
6248
|
if (filePath === config.root) return false;
|
|
5000
|
-
if (filePath === outDirAbs || filePath.startsWith(outDirAbs +
|
|
5001
|
-
const rel =
|
|
5002
|
-
if (!rel || rel.startsWith("..") ||
|
|
5003
|
-
for (const seg of rel.split(
|
|
6249
|
+
if (filePath === outDirAbs || filePath.startsWith(outDirAbs + import_node_path16.default.sep)) return true;
|
|
6250
|
+
const rel = import_node_path16.default.relative(config.root, filePath);
|
|
6251
|
+
if (!rel || rel.startsWith("..") || import_node_path16.default.isAbsolute(rel)) return false;
|
|
6252
|
+
for (const seg of rel.split(import_node_path16.default.sep)) {
|
|
5004
6253
|
if (ignoredSegments.has(seg)) return true;
|
|
5005
6254
|
}
|
|
5006
6255
|
return false;
|
|
@@ -5010,6 +6259,15 @@ async function createServer(inlineConfig = {}) {
|
|
|
5010
6259
|
let server;
|
|
5011
6260
|
const environmentServices = {};
|
|
5012
6261
|
let environmentDriversStarted = false;
|
|
6262
|
+
let devPipelinesStarted = false;
|
|
6263
|
+
const startDevPipelines = async () => {
|
|
6264
|
+
if (devPipelinesStarted) return;
|
|
6265
|
+
devPipelinesStarted = true;
|
|
6266
|
+
for (const environment of Object.values(environments)) {
|
|
6267
|
+
if (!transformContexts.has(environment.name)) continue;
|
|
6268
|
+
await environment.pluginContainer.buildStart();
|
|
6269
|
+
}
|
|
6270
|
+
};
|
|
5013
6271
|
const logCloseError = (target, error) => {
|
|
5014
6272
|
const normalized = error instanceof Error ? error : new Error(String(error));
|
|
5015
6273
|
logger.error(`[nasti] failed to close ${target}`, { error: normalized });
|
|
@@ -5061,14 +6319,61 @@ async function createServer(inlineConfig = {}) {
|
|
|
5061
6319
|
});
|
|
5062
6320
|
}
|
|
5063
6321
|
};
|
|
6322
|
+
const updateClientEnvironments = async (file) => {
|
|
6323
|
+
const timestamp = Date.now();
|
|
6324
|
+
const results = {};
|
|
6325
|
+
for (const environment of Object.values(environments)) {
|
|
6326
|
+
if (environment.consumer !== "client" || environment.driver) continue;
|
|
6327
|
+
try {
|
|
6328
|
+
const result = await handleFileChange(file, server, environment.name, timestamp);
|
|
6329
|
+
if (result) results[environment.name] = result;
|
|
6330
|
+
} catch (error) {
|
|
6331
|
+
const normalized = error instanceof Error ? error : new Error(String(error));
|
|
6332
|
+
logger.error(
|
|
6333
|
+
`[nasti] HMR failed for environment "${environment.name}": ${normalized.message}`,
|
|
6334
|
+
{ error: normalized }
|
|
6335
|
+
);
|
|
6336
|
+
try {
|
|
6337
|
+
environment.hot.send({
|
|
6338
|
+
type: "error",
|
|
6339
|
+
err: { message: normalized.message, stack: normalized.stack }
|
|
6340
|
+
});
|
|
6341
|
+
} catch (channelError) {
|
|
6342
|
+
const channelFailure = channelError instanceof Error ? channelError : new Error(String(channelError));
|
|
6343
|
+
logger.error(
|
|
6344
|
+
`[nasti] failed to deliver HMR error to environment "${environment.name}"`,
|
|
6345
|
+
{ error: channelFailure }
|
|
6346
|
+
);
|
|
6347
|
+
}
|
|
6348
|
+
}
|
|
6349
|
+
}
|
|
6350
|
+
if (Object.keys(results).length === 0) return;
|
|
6351
|
+
const context = {
|
|
6352
|
+
file,
|
|
6353
|
+
timestamp,
|
|
6354
|
+
environments: Object.freeze({ ...results }),
|
|
6355
|
+
server
|
|
6356
|
+
};
|
|
6357
|
+
for (const plugin of config.plugins) {
|
|
6358
|
+
await plugin.handleHotUpdateApp?.(context);
|
|
6359
|
+
}
|
|
6360
|
+
};
|
|
6361
|
+
const queueClientEnvironmentUpdate = (file) => {
|
|
6362
|
+
void updateClientEnvironments(file).catch((error) => {
|
|
6363
|
+
const normalized = error instanceof Error ? error : new Error(String(error));
|
|
6364
|
+
logger.error(`[nasti] multi-environment HMR failed: ${normalized.message}`, {
|
|
6365
|
+
error: normalized
|
|
6366
|
+
});
|
|
6367
|
+
});
|
|
6368
|
+
};
|
|
5064
6369
|
watcher.on("change", (file) => {
|
|
5065
6370
|
ssrRunner?.invalidateFile(file);
|
|
5066
|
-
|
|
6371
|
+
queueClientEnvironmentUpdate(file);
|
|
5067
6372
|
notifyEnvironmentDrivers(file, "change");
|
|
5068
6373
|
});
|
|
5069
6374
|
watcher.on("add", (file) => {
|
|
5070
6375
|
ssrRunner?.invalidateFile(file);
|
|
5071
|
-
|
|
6376
|
+
queueClientEnvironmentUpdate(file);
|
|
5072
6377
|
notifyEnvironmentDrivers(file, "add");
|
|
5073
6378
|
});
|
|
5074
6379
|
watcher.on("unlink", (file) => {
|
|
@@ -5086,7 +6391,7 @@ async function createServer(inlineConfig = {}) {
|
|
|
5086
6391
|
async listen(port) {
|
|
5087
6392
|
const finalPort = port ?? config.server.port;
|
|
5088
6393
|
const host = config.server.host === true ? "0.0.0.0" : config.server.host;
|
|
5089
|
-
await
|
|
6394
|
+
await startDevPipelines();
|
|
5090
6395
|
await startEnvironmentDrivers();
|
|
5091
6396
|
return new Promise((resolve, reject) => {
|
|
5092
6397
|
let currentPort = finalPort;
|
|
@@ -5101,7 +6406,7 @@ async function createServer(inlineConfig = {}) {
|
|
|
5101
6406
|
const readyIn = Math.ceil(performance.now() - startTime);
|
|
5102
6407
|
logger.info(
|
|
5103
6408
|
`
|
|
5104
|
-
${import_picocolors9.default.cyan(import_picocolors9.default.bold("NASTI"))} ${import_picocolors9.default.cyan(`v${"2.
|
|
6409
|
+
${import_picocolors9.default.cyan(import_picocolors9.default.bold("NASTI"))} ${import_picocolors9.default.cyan(`v${"2.4.1"}`)} ${import_picocolors9.default.dim("ready in")} ${import_picocolors9.default.bold(readyIn)} ${import_picocolors9.default.dim("ms")}
|
|
5105
6410
|
`
|
|
5106
6411
|
);
|
|
5107
6412
|
printServerUrls(
|
|
@@ -5128,15 +6433,26 @@ async function createServer(inlineConfig = {}) {
|
|
|
5128
6433
|
});
|
|
5129
6434
|
},
|
|
5130
6435
|
async transformRequest(url) {
|
|
5131
|
-
|
|
5132
|
-
|
|
6436
|
+
return clientEnv.transformRequest(url);
|
|
6437
|
+
},
|
|
6438
|
+
async transformEnvironmentRequest(environmentName, url) {
|
|
6439
|
+
const environment = environments[environmentName];
|
|
6440
|
+
if (!environment) {
|
|
6441
|
+
throw new Error(`[nasti] unknown dev environment "${environmentName}"`);
|
|
6442
|
+
}
|
|
6443
|
+
return environment.transformRequest(url);
|
|
5133
6444
|
},
|
|
5134
6445
|
async ssrLoadModule(url) {
|
|
5135
6446
|
const runner = await getSsrRunner();
|
|
5136
6447
|
return runner.import(url);
|
|
5137
6448
|
},
|
|
5138
6449
|
async close() {
|
|
5139
|
-
|
|
6450
|
+
if (devPipelinesStarted) {
|
|
6451
|
+
for (const environment of Object.values(environments).reverse()) {
|
|
6452
|
+
if (!transformContexts.has(environment.name)) continue;
|
|
6453
|
+
await environment.pluginContainer.buildEnd();
|
|
6454
|
+
}
|
|
6455
|
+
}
|
|
5140
6456
|
await bundledServer?.close();
|
|
5141
6457
|
let environmentCloseFailed = false;
|
|
5142
6458
|
let firstEnvironmentCloseError;
|
|
@@ -5186,12 +6502,8 @@ async function createServer(inlineConfig = {}) {
|
|
|
5186
6502
|
}
|
|
5187
6503
|
throw error;
|
|
5188
6504
|
}
|
|
5189
|
-
app.use(transformMiddleware(
|
|
5190
|
-
|
|
5191
|
-
pluginContainer,
|
|
5192
|
-
moduleGraph
|
|
5193
|
-
}));
|
|
5194
|
-
const publicDir = import_node_path15.default.resolve(config.root, "public");
|
|
6505
|
+
app.use(transformMiddleware(transformContexts.get("client")));
|
|
6506
|
+
const publicDir = import_node_path16.default.resolve(config.root, "public");
|
|
5195
6507
|
app.use((0, import_sirv.default)(publicDir, { dev: true, etag: true }));
|
|
5196
6508
|
app.use((0, import_sirv.default)(config.root, { dev: true, etag: true }));
|
|
5197
6509
|
const postMiddlewares = [];
|
|
@@ -5217,12 +6529,12 @@ function getNetworkAddress() {
|
|
|
5217
6529
|
}
|
|
5218
6530
|
return "localhost";
|
|
5219
6531
|
}
|
|
5220
|
-
var import_node_http,
|
|
6532
|
+
var import_node_http, import_node_path16, import_node_os, import_connect, import_sirv, import_chokidar, import_picocolors9;
|
|
5221
6533
|
var init_server = __esm({
|
|
5222
6534
|
"src/server/index.ts"() {
|
|
5223
6535
|
"use strict";
|
|
5224
6536
|
import_node_http = __toESM(require("http"), 1);
|
|
5225
|
-
|
|
6537
|
+
import_node_path16 = __toESM(require("path"), 1);
|
|
5226
6538
|
import_node_os = __toESM(require("os"), 1);
|
|
5227
6539
|
import_connect = __toESM(require("connect"), 1);
|
|
5228
6540
|
import_sirv = __toESM(require("sirv"), 1);
|
|
@@ -5237,6 +6549,7 @@ var init_server = __esm({
|
|
|
5237
6549
|
init_hmr();
|
|
5238
6550
|
init_builtins();
|
|
5239
6551
|
init_plugin_api();
|
|
6552
|
+
init_env();
|
|
5240
6553
|
}
|
|
5241
6554
|
});
|
|
5242
6555
|
|
|
@@ -5271,8 +6584,8 @@ init_config();
|
|
|
5271
6584
|
init_build();
|
|
5272
6585
|
|
|
5273
6586
|
// src/build/electron.ts
|
|
5274
|
-
var
|
|
5275
|
-
var
|
|
6587
|
+
var import_node_path11 = __toESM(require("path"), 1);
|
|
6588
|
+
var import_node_fs8 = __toESM(require("fs"), 1);
|
|
5276
6589
|
var import_rolldown2 = require("rolldown");
|
|
5277
6590
|
var import_picocolors5 = __toESM(require("picocolors"), 1);
|
|
5278
6591
|
init_config();
|
|
@@ -5318,16 +6631,16 @@ async function buildElectron(inlineConfig = {}) {
|
|
|
5318
6631
|
const config = await resolveConfig({ ...inlineConfig, target: "electron" }, "build");
|
|
5319
6632
|
const startTime = performance.now();
|
|
5320
6633
|
assertElectronVersion(config);
|
|
5321
|
-
console.log(import_picocolors5.default.cyan("\n\u26A1 nasti build (electron)") + import_picocolors5.default.dim(` v${"2.
|
|
6634
|
+
console.log(import_picocolors5.default.cyan("\n\u26A1 nasti build (electron)") + import_picocolors5.default.dim(` v${"2.4.1"}`));
|
|
5322
6635
|
console.log(import_picocolors5.default.dim(` root: ${config.root}`));
|
|
5323
6636
|
console.log(import_picocolors5.default.dim(` mode: ${config.mode}`));
|
|
5324
6637
|
console.log(import_picocolors5.default.dim(` target: electron (\u2265 ${config.electron.minVersion})`));
|
|
5325
|
-
const outDir =
|
|
5326
|
-
if (config.build.emptyOutDir &&
|
|
5327
|
-
|
|
6638
|
+
const outDir = import_node_path11.default.resolve(config.root, config.build.outDir);
|
|
6639
|
+
if (config.build.emptyOutDir && import_node_fs8.default.existsSync(outDir)) {
|
|
6640
|
+
import_node_fs8.default.rmSync(outDir, { recursive: true, force: true });
|
|
5328
6641
|
}
|
|
5329
|
-
|
|
5330
|
-
const rendererOutDir =
|
|
6642
|
+
import_node_fs8.default.mkdirSync(outDir, { recursive: true });
|
|
6643
|
+
const rendererOutDir = import_node_path11.default.join(outDir, "renderer");
|
|
5331
6644
|
const { build: build2 } = await Promise.resolve().then(() => (init_build(), build_exports));
|
|
5332
6645
|
await build2(createElectronRendererConfig(config, inlineConfig, {
|
|
5333
6646
|
build: {
|
|
@@ -5336,8 +6649,8 @@ async function buildElectron(inlineConfig = {}) {
|
|
|
5336
6649
|
emptyOutDir: false
|
|
5337
6650
|
}
|
|
5338
6651
|
}));
|
|
5339
|
-
const mainEntry =
|
|
5340
|
-
if (!
|
|
6652
|
+
const mainEntry = import_node_path11.default.resolve(config.root, config.electron.main);
|
|
6653
|
+
if (!import_node_fs8.default.existsSync(mainEntry)) {
|
|
5341
6654
|
throw new Error(
|
|
5342
6655
|
`Electron main entry not found: ${config.electron.main}
|
|
5343
6656
|
\u5728 nasti.config.ts \u7684 electron.main \u6307\u5B9A\u4E3B\u8FDB\u7A0B\u5165\u53E3\u6587\u4EF6\u3002`
|
|
@@ -5351,11 +6664,11 @@ async function buildElectron(inlineConfig = {}) {
|
|
|
5351
6664
|
const preloadEntries = normalizePreload(config.electron.preload, config.root);
|
|
5352
6665
|
const preloadFiles = [];
|
|
5353
6666
|
for (const entry of preloadEntries) {
|
|
5354
|
-
if (!
|
|
6667
|
+
if (!import_node_fs8.default.existsSync(entry)) {
|
|
5355
6668
|
console.warn(import_picocolors5.default.yellow(` \u26A0 preload entry not found, skipped: ${entry}`));
|
|
5356
6669
|
continue;
|
|
5357
6670
|
}
|
|
5358
|
-
const base =
|
|
6671
|
+
const base = import_node_path11.default.basename(entry).replace(/\.[^.]+$/, "");
|
|
5359
6672
|
const out = outFileName(outDir, base, config.electron.preloadFormat);
|
|
5360
6673
|
await bundleNode(config, entry, {
|
|
5361
6674
|
outFile: out,
|
|
@@ -5367,10 +6680,10 @@ async function buildElectron(inlineConfig = {}) {
|
|
|
5367
6680
|
const elapsed = ((performance.now() - startTime) / 1e3).toFixed(2);
|
|
5368
6681
|
console.log(import_picocolors5.default.green(`
|
|
5369
6682
|
\u2713 Electron build complete in ${elapsed}s`));
|
|
5370
|
-
console.log(import_picocolors5.default.dim(` renderer: ${
|
|
5371
|
-
console.log(import_picocolors5.default.dim(` main: ${
|
|
6683
|
+
console.log(import_picocolors5.default.dim(` renderer: ${import_node_path11.default.relative(config.root, rendererOutDir)}/`));
|
|
6684
|
+
console.log(import_picocolors5.default.dim(` main: ${import_node_path11.default.relative(config.root, mainFile)}`));
|
|
5372
6685
|
for (const pf of preloadFiles) {
|
|
5373
|
-
console.log(import_picocolors5.default.dim(` preload: ${
|
|
6686
|
+
console.log(import_picocolors5.default.dim(` preload: ${import_node_path11.default.relative(config.root, pf)}`));
|
|
5374
6687
|
}
|
|
5375
6688
|
console.log();
|
|
5376
6689
|
return { rendererOutDir, mainFile, preloadFiles };
|
|
@@ -5408,7 +6721,7 @@ async function bundleNode(config, entry, opts) {
|
|
|
5408
6721
|
},
|
|
5409
6722
|
plugins: [oxcTransformPlugin, electronPlugin(config), resolvePlugin(config)]
|
|
5410
6723
|
});
|
|
5411
|
-
|
|
6724
|
+
import_node_fs8.default.mkdirSync(import_node_path11.default.dirname(opts.outFile), { recursive: true });
|
|
5412
6725
|
await bundle2.write({
|
|
5413
6726
|
sourcemap: !!config.build.sourcemap,
|
|
5414
6727
|
minify: !!config.build.minify,
|
|
@@ -5419,7 +6732,7 @@ async function bundleNode(config, entry, opts) {
|
|
|
5419
6732
|
codeSplitting: false
|
|
5420
6733
|
});
|
|
5421
6734
|
await bundle2.close();
|
|
5422
|
-
console.log(import_picocolors5.default.dim(` \u2713 ${opts.label} \u2192 ${
|
|
6735
|
+
console.log(import_picocolors5.default.dim(` \u2713 ${opts.label} \u2192 ${import_node_path11.default.relative(config.root, opts.outFile)}`));
|
|
5423
6736
|
return opts.outFile;
|
|
5424
6737
|
}
|
|
5425
6738
|
function createElectronRendererConfig(config, inlineConfig = {}, overrides = {}) {
|
|
@@ -5443,11 +6756,11 @@ function createElectronRendererConfig(config, inlineConfig = {}, overrides = {})
|
|
|
5443
6756
|
}
|
|
5444
6757
|
function outFileName(outDir, base, format) {
|
|
5445
6758
|
const ext = format === "cjs" ? ".cjs" : ".mjs";
|
|
5446
|
-
return
|
|
6759
|
+
return import_node_path11.default.join(outDir, base + ext);
|
|
5447
6760
|
}
|
|
5448
6761
|
function normalizePreload(preload, root) {
|
|
5449
6762
|
const list = Array.isArray(preload) ? preload : preload ? [preload] : [];
|
|
5450
|
-
return list.map((p) =>
|
|
6763
|
+
return list.map((p) => import_node_path11.default.resolve(root, p));
|
|
5451
6764
|
}
|
|
5452
6765
|
function assertElectronVersion(config) {
|
|
5453
6766
|
const min = config.electron.minVersion;
|
|
@@ -5462,9 +6775,9 @@ function assertElectronVersion(config) {
|
|
|
5462
6775
|
}
|
|
5463
6776
|
function detectInstalledElectron(root) {
|
|
5464
6777
|
try {
|
|
5465
|
-
const pkgPath =
|
|
5466
|
-
if (!
|
|
5467
|
-
const pkg = JSON.parse(
|
|
6778
|
+
const pkgPath = import_node_path11.default.resolve(root, "node_modules/electron/package.json");
|
|
6779
|
+
if (!import_node_fs8.default.existsSync(pkgPath)) return null;
|
|
6780
|
+
const pkg = JSON.parse(import_node_fs8.default.readFileSync(pkgPath, "utf-8"));
|
|
5468
6781
|
const major = parseInt(String(pkg.version).split(".")[0], 10);
|
|
5469
6782
|
return Number.isFinite(major) ? major : null;
|
|
5470
6783
|
} catch {
|
|
@@ -5476,8 +6789,8 @@ function detectInstalledElectron(root) {
|
|
|
5476
6789
|
init_server();
|
|
5477
6790
|
|
|
5478
6791
|
// src/server/electron-dev.ts
|
|
5479
|
-
var
|
|
5480
|
-
var
|
|
6792
|
+
var import_node_path17 = __toESM(require("path"), 1);
|
|
6793
|
+
var import_node_fs12 = __toESM(require("fs"), 1);
|
|
5481
6794
|
var import_node_module7 = require("module");
|
|
5482
6795
|
var import_node_child_process = require("child_process");
|
|
5483
6796
|
var import_chokidar2 = __toESM(require("chokidar"), 1);
|
|
@@ -5491,7 +6804,7 @@ async function startElectronDev(inlineConfig = {}) {
|
|
|
5491
6804
|
const { noSpawn, ...rest } = inlineConfig;
|
|
5492
6805
|
const config = await resolveConfig({ ...rest, target: "electron" }, "serve");
|
|
5493
6806
|
warnElectronVersion(config);
|
|
5494
|
-
console.log(import_picocolors10.default.cyan("\n\u26A1 nasti electron dev") + import_picocolors10.default.dim(` v${"2.
|
|
6807
|
+
console.log(import_picocolors10.default.cyan("\n\u26A1 nasti electron dev") + import_picocolors10.default.dim(` v${"2.4.1"}`));
|
|
5495
6808
|
const { createServer: createServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
|
|
5496
6809
|
const server = await createServer2({
|
|
5497
6810
|
...rest,
|
|
@@ -5501,11 +6814,11 @@ async function startElectronDev(inlineConfig = {}) {
|
|
|
5501
6814
|
await server.listen();
|
|
5502
6815
|
const devUrl = `http://localhost:${server.config.server.port}` + electronRendererDevPath(config.electron.renderer);
|
|
5503
6816
|
console.log(import_picocolors10.default.dim(` renderer: ${devUrl}`));
|
|
5504
|
-
const stageDir =
|
|
5505
|
-
|
|
5506
|
-
const mainEntry =
|
|
6817
|
+
const stageDir = import_node_path17.default.resolve(config.root, ".nasti");
|
|
6818
|
+
import_node_fs12.default.mkdirSync(stageDir, { recursive: true });
|
|
6819
|
+
const mainEntry = import_node_path17.default.resolve(config.root, config.electron.main);
|
|
5507
6820
|
const preloadEntries = normalizePreload(config.electron.preload, config.root);
|
|
5508
|
-
const builtMainFile =
|
|
6821
|
+
const builtMainFile = import_node_path17.default.join(stageDir, "main" + extFor(config.electron.mainFormat));
|
|
5509
6822
|
const builtPreloadFiles = [];
|
|
5510
6823
|
const compileAll = async () => {
|
|
5511
6824
|
await compileNode(config, mainEntry, {
|
|
@@ -5515,9 +6828,9 @@ async function startElectronDev(inlineConfig = {}) {
|
|
|
5515
6828
|
});
|
|
5516
6829
|
builtPreloadFiles.length = 0;
|
|
5517
6830
|
for (const entry of preloadEntries) {
|
|
5518
|
-
if (!
|
|
5519
|
-
const base =
|
|
5520
|
-
const out =
|
|
6831
|
+
if (!import_node_fs12.default.existsSync(entry)) continue;
|
|
6832
|
+
const base = import_node_path17.default.basename(entry).replace(/\.[^.]+$/, "");
|
|
6833
|
+
const out = import_node_path17.default.join(stageDir, base + extFor(config.electron.preloadFormat));
|
|
5521
6834
|
await compileNode(config, entry, {
|
|
5522
6835
|
outFile: out,
|
|
5523
6836
|
format: config.electron.preloadFormat,
|
|
@@ -5556,7 +6869,7 @@ async function startElectronDev(inlineConfig = {}) {
|
|
|
5556
6869
|
};
|
|
5557
6870
|
spawnElectron();
|
|
5558
6871
|
if (config.electron.autoRestart) {
|
|
5559
|
-
const watchTargets = [mainEntry, ...preloadEntries].filter(
|
|
6872
|
+
const watchTargets = [mainEntry, ...preloadEntries].filter(import_node_fs12.default.existsSync);
|
|
5560
6873
|
const watcher = import_chokidar2.default.watch(watchTargets, { ignoreInitial: true });
|
|
5561
6874
|
let restarting = null;
|
|
5562
6875
|
let pending = false;
|
|
@@ -5636,7 +6949,7 @@ async function compileNode(config, entry, opts) {
|
|
|
5636
6949
|
platform: "node",
|
|
5637
6950
|
plugins: [oxcTransformPlugin, electronPlugin(config), resolvePlugin(config)]
|
|
5638
6951
|
});
|
|
5639
|
-
|
|
6952
|
+
import_node_fs12.default.mkdirSync(import_node_path17.default.dirname(opts.outFile), { recursive: true });
|
|
5640
6953
|
await bundle2.write({
|
|
5641
6954
|
file: opts.outFile,
|
|
5642
6955
|
format: opts.format === "cjs" ? "cjs" : "esm",
|
|
@@ -5649,18 +6962,18 @@ async function compileNode(config, entry, opts) {
|
|
|
5649
6962
|
await bundle2.close();
|
|
5650
6963
|
}
|
|
5651
6964
|
function electronRendererDevPath(renderer) {
|
|
5652
|
-
const normalized = renderer.split(
|
|
6965
|
+
const normalized = renderer.split(import_node_path17.default.sep).join("/").replace(/^\.?\//, "");
|
|
5653
6966
|
return normalized === "index.html" ? "/" : `/${normalized}`;
|
|
5654
6967
|
}
|
|
5655
6968
|
function resolveElectronBinary(config) {
|
|
5656
|
-
if (config.electron.electronPath &&
|
|
6969
|
+
if (config.electron.electronPath && import_node_fs12.default.existsSync(config.electron.electronPath)) {
|
|
5657
6970
|
return config.electron.electronPath;
|
|
5658
6971
|
}
|
|
5659
6972
|
try {
|
|
5660
|
-
const require2 = (0, import_node_module7.createRequire)(
|
|
6973
|
+
const require2 = (0, import_node_module7.createRequire)(import_node_path17.default.resolve(config.root, "package.json"));
|
|
5661
6974
|
const pathFile = require2.resolve("electron");
|
|
5662
6975
|
const electronModule = require2(pathFile);
|
|
5663
|
-
if (typeof electronModule === "string" &&
|
|
6976
|
+
if (typeof electronModule === "string" && import_node_fs12.default.existsSync(electronModule)) {
|
|
5664
6977
|
return electronModule;
|
|
5665
6978
|
}
|
|
5666
6979
|
} catch {
|
|
@@ -5687,8 +7000,8 @@ function warnElectronVersion(config) {
|
|
|
5687
7000
|
}
|
|
5688
7001
|
|
|
5689
7002
|
// src/plugins/monaco-editor.ts
|
|
5690
|
-
var
|
|
5691
|
-
var
|
|
7003
|
+
var import_node_path18 = __toESM(require("path"), 1);
|
|
7004
|
+
var import_node_fs13 = __toESM(require("fs"), 1);
|
|
5692
7005
|
var import_node_crypto4 = __toESM(require("crypto"), 1);
|
|
5693
7006
|
var import_node_module8 = require("module");
|
|
5694
7007
|
var DEFAULT_WORKERS = {
|
|
@@ -5709,9 +7022,9 @@ function normalizePublicPath(p) {
|
|
|
5709
7022
|
}
|
|
5710
7023
|
function readMonacoVersion(root) {
|
|
5711
7024
|
try {
|
|
5712
|
-
const require2 = (0, import_node_module8.createRequire)(
|
|
7025
|
+
const require2 = (0, import_node_module8.createRequire)(import_node_path18.default.resolve(root, "package.json"));
|
|
5713
7026
|
const pkgJsonPath = require2.resolve("monaco-editor/package.json", { paths: [root] });
|
|
5714
|
-
const pkg = JSON.parse(
|
|
7027
|
+
const pkg = JSON.parse(import_node_fs13.default.readFileSync(pkgJsonPath, "utf-8"));
|
|
5715
7028
|
return typeof pkg.version === "string" ? pkg.version : "unknown";
|
|
5716
7029
|
} catch {
|
|
5717
7030
|
return "unknown";
|
|
@@ -5731,20 +7044,20 @@ function monacoEditorPlugin(options = {}) {
|
|
|
5731
7044
|
let cacheDir = "";
|
|
5732
7045
|
const building = /* @__PURE__ */ new Map();
|
|
5733
7046
|
async function buildWorker(worker) {
|
|
5734
|
-
const cacheFile =
|
|
5735
|
-
if (
|
|
7047
|
+
const cacheFile = import_node_path18.default.join(cacheDir, `${worker.label}.worker.js`);
|
|
7048
|
+
if (import_node_fs13.default.existsSync(cacheFile)) return cacheFile;
|
|
5736
7049
|
const existing = building.get(worker.label);
|
|
5737
7050
|
if (existing) return existing;
|
|
5738
7051
|
const task = (async () => {
|
|
5739
7052
|
const { rolldown: rolldown4 } = await import("rolldown");
|
|
5740
|
-
const require2 = (0, import_node_module8.createRequire)(
|
|
7053
|
+
const require2 = (0, import_node_module8.createRequire)(import_node_path18.default.resolve(resolvedConfig.root, "package.json"));
|
|
5741
7054
|
let entry;
|
|
5742
7055
|
try {
|
|
5743
7056
|
entry = require2.resolve(worker.entry, { paths: [resolvedConfig.root] });
|
|
5744
7057
|
} catch {
|
|
5745
7058
|
entry = require2.resolve(worker.entry + ".js", { paths: [resolvedConfig.root] });
|
|
5746
7059
|
}
|
|
5747
|
-
|
|
7060
|
+
import_node_fs13.default.mkdirSync(cacheDir, { recursive: true });
|
|
5748
7061
|
const bundle2 = await rolldown4({
|
|
5749
7062
|
input: entry,
|
|
5750
7063
|
platform: "browser"
|
|
@@ -5804,12 +7117,12 @@ function monacoEditorPlugin(options = {}) {
|
|
|
5804
7117
|
resolvedConfig = config;
|
|
5805
7118
|
const version = readMonacoVersion(config.root);
|
|
5806
7119
|
const key = import_node_crypto4.default.createHash("sha1").update(version + "|" + publicPath).digest("hex").slice(0, 8);
|
|
5807
|
-
cacheDir =
|
|
7120
|
+
cacheDir = import_node_path18.default.resolve(config.root, "node_modules/.nasti/monaco", key);
|
|
5808
7121
|
},
|
|
5809
7122
|
async configureServer(server) {
|
|
5810
7123
|
const shouldBuild = !isCDN(publicPath) || forceBuildCDN;
|
|
5811
7124
|
const watcher = server.watcher;
|
|
5812
|
-
const monacoDir =
|
|
7125
|
+
const monacoDir = import_node_path18.default.resolve(resolvedConfig.root, "node_modules/monaco-editor");
|
|
5813
7126
|
try {
|
|
5814
7127
|
watcher?.unwatch?.(monacoDir);
|
|
5815
7128
|
} catch {
|
|
@@ -5839,7 +7152,7 @@ function monacoEditorPlugin(options = {}) {
|
|
|
5839
7152
|
const file = await buildWorker(worker);
|
|
5840
7153
|
res.setHeader("Content-Type", "application/javascript; charset=utf-8");
|
|
5841
7154
|
res.setHeader("Cache-Control", "public, max-age=604800, immutable");
|
|
5842
|
-
|
|
7155
|
+
import_node_fs13.default.createReadStream(file).pipe(res);
|
|
5843
7156
|
} catch (e) {
|
|
5844
7157
|
res.statusCode = 500;
|
|
5845
7158
|
res.end(`Monaco worker build failed: ${e.message}`);
|
|
@@ -5874,16 +7187,16 @@ self.monaco = monaco;`,
|
|
|
5874
7187
|
resolvedConfig.root,
|
|
5875
7188
|
resolvedConfig.build.outDir,
|
|
5876
7189
|
resolvedConfig.base
|
|
5877
|
-
) : isCDN(publicPath) ?
|
|
7190
|
+
) : isCDN(publicPath) ? import_node_path18.default.resolve(resolvedConfig.root, resolvedConfig.build.outDir, "monaco") : import_node_path18.default.resolve(
|
|
5878
7191
|
resolvedConfig.root,
|
|
5879
7192
|
resolvedConfig.build.outDir,
|
|
5880
7193
|
publicPath.replace(/^\//, "")
|
|
5881
7194
|
);
|
|
5882
|
-
|
|
7195
|
+
import_node_fs13.default.mkdirSync(outDir, { recursive: true });
|
|
5883
7196
|
for (const worker of workers) {
|
|
5884
7197
|
try {
|
|
5885
7198
|
const cacheFile = await buildWorker(worker);
|
|
5886
|
-
|
|
7199
|
+
import_node_fs13.default.copyFileSync(cacheFile, import_node_path18.default.join(outDir, `${worker.label}.worker.js`));
|
|
5887
7200
|
} catch (e) {
|
|
5888
7201
|
throw new Error(
|
|
5889
7202
|
`[nasti:monaco-editor] worker build failed for "${worker.label}": ${e.message}
|