@nasti-toolchain/nasti 2.4.0 → 2.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -7
- package/dist/cli.cjs +948 -323
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +946 -317
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +775 -150
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +170 -11
- package/dist/index.d.ts +170 -11
- package/dist/index.js +778 -149
- package/dist/index.js.map +1 -1
- package/package.json +8 -4
package/dist/index.cjs
CHANGED
|
@@ -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,7 +485,11 @@ 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,
|
|
477
495
|
buildEnabled: envOptions.buildEnabled ?? true,
|
|
@@ -483,7 +501,8 @@ async function resolveConfig(inlineConfig = {}, command) {
|
|
|
483
501
|
driver: envOptions.driver,
|
|
484
502
|
// 同引用 —— 精确镜像(assertClientEnvironmentMirror 校验)
|
|
485
503
|
resolve: resolved.resolve,
|
|
486
|
-
build: resolved.build
|
|
504
|
+
build: resolved.build,
|
|
505
|
+
vue: vueOptions
|
|
487
506
|
};
|
|
488
507
|
continue;
|
|
489
508
|
}
|
|
@@ -493,6 +512,7 @@ async function resolveConfig(inlineConfig = {}, command) {
|
|
|
493
512
|
entry: normalizeEnvironmentEntries(envOptions.entry, root),
|
|
494
513
|
html: envOptions.consumer === "client" && envOptions.html ? import_node_path.default.resolve(root, envOptions.html) : void 0,
|
|
495
514
|
driver: envOptions.driver,
|
|
515
|
+
vue: vueOptions,
|
|
496
516
|
resolve: {
|
|
497
517
|
alias: { ...resolved.resolve.alias, ...envOptions.resolve?.alias },
|
|
498
518
|
extensions: envOptions.resolve?.extensions ?? [...resolved.resolve.extensions],
|
|
@@ -503,6 +523,7 @@ async function resolveConfig(inlineConfig = {}, command) {
|
|
|
503
523
|
build: {
|
|
504
524
|
...resolved.build,
|
|
505
525
|
...envOptions.build,
|
|
526
|
+
css: { ...resolved.build.css, ...envOptions.build?.css },
|
|
506
527
|
// 非 client 环境默认产出到 <outDir>/<envName>(如 dist/ssr),可显式覆盖
|
|
507
528
|
outDir: envOptions.build?.outDir ?? import_node_path.default.join(resolved.build.outDir, name),
|
|
508
529
|
// server 产物默认不压缩(可调试性优先,与 Vite SSR 默认一致),可显式覆盖
|
|
@@ -735,7 +756,7 @@ function resolvePlugin(config) {
|
|
|
735
756
|
const content = import_node_fs2.default.readFileSync(id, "utf-8");
|
|
736
757
|
return `export default ${content}`;
|
|
737
758
|
}
|
|
738
|
-
return
|
|
759
|
+
return null;
|
|
739
760
|
}
|
|
740
761
|
};
|
|
741
762
|
}
|
|
@@ -1696,12 +1717,31 @@ var init_node = __esm({
|
|
|
1696
1717
|
function createCssEngine() {
|
|
1697
1718
|
return {
|
|
1698
1719
|
styles: /* @__PURE__ */ new Map(),
|
|
1720
|
+
modules: /* @__PURE__ */ new Map(),
|
|
1721
|
+
chunks: /* @__PURE__ */ new Map(),
|
|
1699
1722
|
entryCss: /* @__PURE__ */ new Map(),
|
|
1700
1723
|
allCss: [],
|
|
1701
1724
|
pendingSingle: [],
|
|
1702
1725
|
singleFileName: null
|
|
1703
1726
|
};
|
|
1704
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
|
+
}
|
|
1705
1745
|
function normalizeCssModuleId(id) {
|
|
1706
1746
|
return id.startsWith("\0") ? id.slice(1) : id;
|
|
1707
1747
|
}
|
|
@@ -1821,15 +1861,29 @@ function cssPlugin(config, engine, consumer = "client") {
|
|
|
1821
1861
|
}
|
|
1822
1862
|
const rewritten = rewriteCssUrls(cssSource, file, config.root);
|
|
1823
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);
|
|
1824
1869
|
if (query === "inline") {
|
|
1825
1870
|
return { code: `export default ${escaped};
|
|
1826
|
-
`, moduleType: "js" };
|
|
1871
|
+
`, map, moduleType: "js" };
|
|
1827
1872
|
}
|
|
1828
1873
|
if (consumer === "server") {
|
|
1829
1874
|
return { code: `export default ${escaped};
|
|
1830
|
-
`, moduleType: "js" };
|
|
1875
|
+
`, map, moduleType: "js" };
|
|
1831
1876
|
}
|
|
1832
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
|
+
}
|
|
1833
1887
|
return {
|
|
1834
1888
|
code: `
|
|
1835
1889
|
const css = ${escaped};
|
|
@@ -1853,16 +1907,18 @@ if (import.meta.hot) {
|
|
|
1853
1907
|
|
|
1854
1908
|
export default css;
|
|
1855
1909
|
`,
|
|
1910
|
+
map,
|
|
1856
1911
|
// bundled dev(DevEngine)下该模块会进 Rolldown:不标 js 会按 .css
|
|
1857
1912
|
// 扩展名走 CSS 管线触发 #4271 报错;unbundled 中间件忽略此字段
|
|
1858
1913
|
moduleType: "js"
|
|
1859
1914
|
};
|
|
1860
1915
|
}
|
|
1861
1916
|
if (engine) {
|
|
1862
|
-
engine.styles.set(
|
|
1917
|
+
engine.styles.set(normalizedId, rewritten);
|
|
1863
1918
|
return {
|
|
1864
1919
|
code: `export default '';
|
|
1865
1920
|
`,
|
|
1921
|
+
map,
|
|
1866
1922
|
moduleType: "js",
|
|
1867
1923
|
// 防止空 stub 被 tree-shake 出 chunk.moduleIds(css-post 靠它定位)
|
|
1868
1924
|
moduleSideEffects: "no-treeshake"
|
|
@@ -1882,11 +1938,27 @@ document.head.appendChild(style);
|
|
|
1882
1938
|
|
|
1883
1939
|
export default css;
|
|
1884
1940
|
`,
|
|
1941
|
+
map,
|
|
1885
1942
|
moduleType: "js"
|
|
1886
1943
|
};
|
|
1887
1944
|
}
|
|
1888
1945
|
};
|
|
1889
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
|
+
}
|
|
1890
1962
|
function rewriteCssUrls(css, from, root) {
|
|
1891
1963
|
return css.replace(/url\(\s*['"]?([^'")\s]+)['"]?\s*\)/g, (match, url) => {
|
|
1892
1964
|
if (url.startsWith("/") || url.startsWith("data:") || url.startsWith("http")) {
|
|
@@ -1897,11 +1969,12 @@ function rewriteCssUrls(css, from, root) {
|
|
|
1897
1969
|
return `url(${relative})`;
|
|
1898
1970
|
});
|
|
1899
1971
|
}
|
|
1900
|
-
var import_node_path4;
|
|
1972
|
+
var import_node_path4, import_source_map_js;
|
|
1901
1973
|
var init_css = __esm({
|
|
1902
1974
|
"src/plugins/css.ts"() {
|
|
1903
1975
|
"use strict";
|
|
1904
1976
|
import_node_path4 = __toESM(require("path"), 1);
|
|
1977
|
+
import_source_map_js = require("source-map-js");
|
|
1905
1978
|
init_css_engine();
|
|
1906
1979
|
init_tailwind();
|
|
1907
1980
|
}
|
|
@@ -1911,19 +1984,27 @@ var init_css = __esm({
|
|
|
1911
1984
|
function collectChunkCss(chunk, engine) {
|
|
1912
1985
|
const ids = chunk.moduleIds ?? Object.keys(chunk.modules);
|
|
1913
1986
|
let css = "";
|
|
1987
|
+
const moduleIds = [];
|
|
1914
1988
|
for (const id of ids) {
|
|
1915
|
-
const
|
|
1916
|
-
|
|
1989
|
+
const normalizedId = normalizeCssModuleId(id);
|
|
1990
|
+
const styles = engine.styles.get(normalizedId);
|
|
1991
|
+
if (styles) {
|
|
1992
|
+
css += styles + "\n";
|
|
1993
|
+
moduleIds.push(normalizedId);
|
|
1994
|
+
}
|
|
1917
1995
|
}
|
|
1918
|
-
return css;
|
|
1996
|
+
return { css, moduleIds };
|
|
1919
1997
|
}
|
|
1920
1998
|
function cssPostPlugin(config, engine) {
|
|
1921
1999
|
return {
|
|
1922
2000
|
name: "nasti:css-post",
|
|
1923
2001
|
enforce: "post",
|
|
1924
2002
|
async renderChunk(code, chunk) {
|
|
1925
|
-
const css = collectChunkCss(chunk, engine);
|
|
2003
|
+
const { css, moduleIds } = collectChunkCss(chunk, engine);
|
|
1926
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;
|
|
1927
2008
|
if (!config.build.cssCodeSplit) {
|
|
1928
2009
|
engine.pendingSingle.push(css);
|
|
1929
2010
|
return null;
|
|
@@ -1936,6 +2017,7 @@ function cssPostPlugin(config, engine) {
|
|
|
1936
2017
|
});
|
|
1937
2018
|
const fileName = this.getFileName(ref);
|
|
1938
2019
|
engine.allCss.push(fileName);
|
|
2020
|
+
ownership.cssFileNames.push(fileName);
|
|
1939
2021
|
if (chunk.isEntry) {
|
|
1940
2022
|
const key = chunk.facadeModuleId ?? chunk.name;
|
|
1941
2023
|
const existing = engine.entryCss.get(key) ?? [];
|
|
@@ -1943,13 +2025,14 @@ function cssPostPlugin(config, engine) {
|
|
|
1943
2025
|
engine.entryCss.set(key, existing);
|
|
1944
2026
|
return null;
|
|
1945
2027
|
}
|
|
2028
|
+
if (config.build.css.inject === false) return null;
|
|
1946
2029
|
const href = JSON.stringify(config.base + fileName);
|
|
1947
2030
|
const snippet = `
|
|
1948
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){}})();`;
|
|
1949
2032
|
return { code: code + snippet, map: null };
|
|
1950
2033
|
},
|
|
1951
2034
|
augmentChunkHash(chunk) {
|
|
1952
|
-
const css = collectChunkCss(chunk, engine);
|
|
2035
|
+
const { css } = collectChunkCss(chunk, engine);
|
|
1953
2036
|
return css || void 0;
|
|
1954
2037
|
},
|
|
1955
2038
|
async generateBundle() {
|
|
@@ -1960,6 +2043,9 @@ function cssPostPlugin(config, engine) {
|
|
|
1960
2043
|
const fileName = this.getFileName(ref);
|
|
1961
2044
|
engine.singleFileName = fileName;
|
|
1962
2045
|
engine.allCss.push(fileName);
|
|
2046
|
+
for (const ownership of engine.chunks.values()) {
|
|
2047
|
+
if (ownership.moduleIds.length > 0) ownership.cssFileNames.push(fileName);
|
|
2048
|
+
}
|
|
1963
2049
|
}
|
|
1964
2050
|
};
|
|
1965
2051
|
}
|
|
@@ -1972,6 +2058,7 @@ var init_css_post = __esm({
|
|
|
1972
2058
|
|
|
1973
2059
|
// src/plugins/assets.ts
|
|
1974
2060
|
function assetsPlugin(config) {
|
|
2061
|
+
const emittedAssets = /* @__PURE__ */ new Set();
|
|
1975
2062
|
return {
|
|
1976
2063
|
name: "nasti:assets",
|
|
1977
2064
|
resolveId(source) {
|
|
@@ -2000,12 +2087,29 @@ function assetsPlugin(config) {
|
|
|
2000
2087
|
const hash = import_node_crypto.default.createHash("sha256").update(content).digest("hex").slice(0, 8);
|
|
2001
2088
|
const basename = import_node_path5.default.basename(file, ext);
|
|
2002
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);
|
|
2003
2103
|
return `export default ${JSON.stringify(config.base + hashedName)}`;
|
|
2004
2104
|
}
|
|
2005
2105
|
return null;
|
|
2006
2106
|
}
|
|
2007
2107
|
};
|
|
2008
2108
|
}
|
|
2109
|
+
function isAssetFile(id) {
|
|
2110
|
+
const ext = import_node_path5.default.extname(id.replace(/\?.*$/, ""));
|
|
2111
|
+
return ASSET_EXTENSIONS.has(ext);
|
|
2112
|
+
}
|
|
2009
2113
|
var import_node_path5, import_node_fs3, import_node_crypto, ASSET_EXTENSIONS;
|
|
2010
2114
|
var init_assets = __esm({
|
|
2011
2115
|
"src/plugins/assets.ts"() {
|
|
@@ -2088,9 +2192,10 @@ async function loadVueCompiler() {
|
|
|
2088
2192
|
return null;
|
|
2089
2193
|
}
|
|
2090
2194
|
}
|
|
2091
|
-
function vuePlugin(config) {
|
|
2195
|
+
function vuePlugin(config, environmentName = "client") {
|
|
2092
2196
|
const isDev = config.command === "serve";
|
|
2093
2197
|
const descriptorCache = /* @__PURE__ */ new Map();
|
|
2198
|
+
const vueOptions = config.environments[environmentName]?.vue ?? {};
|
|
2094
2199
|
return {
|
|
2095
2200
|
name: "nasti:vue",
|
|
2096
2201
|
enforce: "pre",
|
|
@@ -2110,32 +2215,63 @@ function vuePlugin(config) {
|
|
|
2110
2215
|
const sfc = await loadVueCompiler();
|
|
2111
2216
|
if (!sfc) return null;
|
|
2112
2217
|
const [, filePath, indexStr] = match;
|
|
2113
|
-
let
|
|
2114
|
-
if (!
|
|
2218
|
+
let cached2 = descriptorCache.get(filePath);
|
|
2219
|
+
if (!cached2) {
|
|
2115
2220
|
try {
|
|
2116
2221
|
const fs14 = await import("fs");
|
|
2117
|
-
const
|
|
2118
|
-
const
|
|
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
|
+
});
|
|
2119
2233
|
if (parsed.errors.length) return null;
|
|
2120
|
-
|
|
2121
|
-
|
|
2234
|
+
cached2 = {
|
|
2235
|
+
descriptor: parsed.descriptor,
|
|
2236
|
+
sourceMap: transformedSfc.map
|
|
2237
|
+
};
|
|
2238
|
+
descriptorCache.set(filePath, cached2);
|
|
2122
2239
|
} catch {
|
|
2123
2240
|
return null;
|
|
2124
2241
|
}
|
|
2125
2242
|
}
|
|
2243
|
+
const { descriptor, sourceMap: sfcSourceMap } = cached2;
|
|
2126
2244
|
const index2 = parseInt(indexStr ?? "0", 10);
|
|
2127
2245
|
const style = descriptor.styles[index2];
|
|
2128
2246
|
if (!style) return null;
|
|
2129
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;
|
|
2130
2258
|
const result = await sfc.compileStyleAsync({
|
|
2131
|
-
|
|
2259
|
+
...vueOptions.style,
|
|
2260
|
+
source: transformedStyle.code,
|
|
2132
2261
|
filename: filePath,
|
|
2133
2262
|
id: `data-v-${scopeId}`,
|
|
2134
2263
|
scoped: style.scoped ?? false,
|
|
2264
|
+
inMap: styleInputMap,
|
|
2135
2265
|
// <style lang="scss|less|stylus"> 需经对应预处理器(缺省 undefined = 纯 CSS)
|
|
2136
2266
|
preprocessLang: style.lang
|
|
2137
2267
|
});
|
|
2138
|
-
|
|
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;
|
|
2139
2275
|
},
|
|
2140
2276
|
async transform(code, id) {
|
|
2141
2277
|
if (!VUE_FILE_RE.test(id) && !VUE_QUERY_RE.test(id)) return null;
|
|
@@ -2147,57 +2283,144 @@ function vuePlugin(config) {
|
|
|
2147
2283
|
if (VUE_QUERY_RE.test(id)) {
|
|
2148
2284
|
return null;
|
|
2149
2285
|
}
|
|
2150
|
-
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
|
+
});
|
|
2151
2297
|
if (errors.length) {
|
|
2152
|
-
|
|
2298
|
+
const firstError = errors[0];
|
|
2299
|
+
console.error(
|
|
2300
|
+
`[nasti:vue] Parse error in ${id}:`,
|
|
2301
|
+
typeof firstError === "string" ? firstError : firstError.message
|
|
2302
|
+
);
|
|
2153
2303
|
return null;
|
|
2154
2304
|
}
|
|
2155
|
-
descriptorCache.set(id,
|
|
2305
|
+
descriptorCache.set(id, {
|
|
2306
|
+
descriptor,
|
|
2307
|
+
sourceMap: transformedSfc.map
|
|
2308
|
+
});
|
|
2156
2309
|
const scopeId = hashId(id);
|
|
2310
|
+
const wantsSourceMap = !!config.build.sourcemap || transformedSfc.map != null;
|
|
2157
2311
|
let scriptCode = "";
|
|
2312
|
+
let scriptMap;
|
|
2158
2313
|
if (descriptor.script || descriptor.scriptSetup) {
|
|
2314
|
+
const inlineTemplate = vueOptions.script?.inlineTemplate !== false;
|
|
2159
2315
|
const compiled = sfc.compileScript(descriptor, {
|
|
2316
|
+
...vueOptions.script,
|
|
2160
2317
|
id: scopeId,
|
|
2161
2318
|
isProd: !isDev,
|
|
2162
|
-
inlineTemplate
|
|
2319
|
+
inlineTemplate,
|
|
2320
|
+
sourceMap: wantsSourceMap,
|
|
2163
2321
|
// 让 compileScript 产出 `const __sfc__ = ...`(而非默认的 `export default {...}`)。
|
|
2164
2322
|
// 否则下方追加的 `__sfc__.render` / `__sfc__.__scopeId` / HMR 记录会引用一个
|
|
2165
2323
|
// 不存在的 `__sfc__`,并与 compileScript 自带的 `export default` 形成双重默认导出。
|
|
2166
2324
|
genDefaultAs: "__sfc__"
|
|
2167
2325
|
});
|
|
2168
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
|
+
}
|
|
2169
2337
|
}
|
|
2170
2338
|
let templateCode = "";
|
|
2171
|
-
|
|
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 ?? {};
|
|
2172
2356
|
const compiled = sfc.compileTemplate({
|
|
2173
|
-
|
|
2357
|
+
...vueOptions.template,
|
|
2358
|
+
source: transformedTemplate.code,
|
|
2174
2359
|
filename: id,
|
|
2175
2360
|
id: scopeId,
|
|
2176
|
-
|
|
2361
|
+
inMap: templateInputMap,
|
|
2362
|
+
compilerOptions: {
|
|
2363
|
+
...customCompilerOptions,
|
|
2364
|
+
scopeId: `data-v-${scopeId}`
|
|
2365
|
+
}
|
|
2177
2366
|
});
|
|
2178
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
|
+
}
|
|
2179
2377
|
}
|
|
2180
|
-
|
|
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);
|
|
2181
2406
|
if (templateCode) {
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
__sfc__.render = render
|
|
2187
|
-
`;
|
|
2407
|
+
append("\n");
|
|
2408
|
+
append(templateCode, templateMap);
|
|
2409
|
+
append("\n");
|
|
2410
|
+
append("\n__sfc__.render = render\n");
|
|
2188
2411
|
}
|
|
2189
2412
|
if (descriptor.styles.length > 0) {
|
|
2190
2413
|
for (let i = 0; i < descriptor.styles.length; i++) {
|
|
2191
|
-
|
|
2414
|
+
append(`
|
|
2192
2415
|
import "${id}?vue&type=style&index=${i}&lang.css"
|
|
2193
|
-
|
|
2416
|
+
`);
|
|
2194
2417
|
}
|
|
2195
2418
|
}
|
|
2196
|
-
|
|
2419
|
+
append(`
|
|
2197
2420
|
__sfc__.__scopeId = "data-v-${scopeId}"
|
|
2198
|
-
|
|
2421
|
+
`);
|
|
2199
2422
|
if (isDev) {
|
|
2200
|
-
|
|
2423
|
+
append(`
|
|
2201
2424
|
__sfc__.__hmrId = ${JSON.stringify(scopeId)}
|
|
2202
2425
|
if (typeof __VUE_HMR_RUNTIME__ !== 'undefined') {
|
|
2203
2426
|
__VUE_HMR_RUNTIME__.createRecord(__sfc__.__hmrId, __sfc__)
|
|
@@ -2211,17 +2434,34 @@ if (import.meta.hot) {
|
|
|
2211
2434
|
}
|
|
2212
2435
|
})
|
|
2213
2436
|
}
|
|
2214
|
-
|
|
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
|
+
);
|
|
2215
2448
|
}
|
|
2216
|
-
output += `
|
|
2217
|
-
export default __sfc__
|
|
2218
|
-
`;
|
|
2219
2449
|
const lang = descriptor.scriptSetup?.lang ?? descriptor.script?.lang;
|
|
2220
2450
|
if (lang === "ts") {
|
|
2221
|
-
const transpiled = transformCode(`${id}.ts`, output, {
|
|
2222
|
-
|
|
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
|
+
};
|
|
2223
2463
|
}
|
|
2224
|
-
return { code: output };
|
|
2464
|
+
return { code: output, map: outputMap };
|
|
2225
2465
|
},
|
|
2226
2466
|
handleHotUpdate(ctx) {
|
|
2227
2467
|
const { file, modules } = ctx;
|
|
@@ -2235,17 +2475,77 @@ export default __sfc__
|
|
|
2235
2475
|
}
|
|
2236
2476
|
};
|
|
2237
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
|
+
}
|
|
2238
2535
|
function hashId(filename) {
|
|
2239
2536
|
return import_node_crypto2.default.createHash("sha256").update(filename).digest("hex").slice(0, 8);
|
|
2240
2537
|
}
|
|
2241
|
-
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;
|
|
2242
2539
|
var init_vue = __esm({
|
|
2243
2540
|
"src/plugins/vue.ts"() {
|
|
2244
2541
|
"use strict";
|
|
2245
2542
|
import_node_crypto2 = __toESM(require("crypto"), 1);
|
|
2543
|
+
import_source_map_js2 = require("source-map-js");
|
|
2246
2544
|
init_transformer();
|
|
2545
|
+
init_debug();
|
|
2247
2546
|
VUE_FILE_RE = /\.vue$/;
|
|
2248
2547
|
VUE_QUERY_RE = /\.vue\?vue&type=(script|template|style)(&index=\d+)?(&lang[.=]\w+)?/;
|
|
2548
|
+
debug2 = createDebugger("nasti:vue");
|
|
2249
2549
|
compiler = null;
|
|
2250
2550
|
}
|
|
2251
2551
|
});
|
|
@@ -2349,7 +2649,7 @@ function resolvePluginList(config, userPlugins, opts = {}) {
|
|
|
2349
2649
|
const consumer = opts.consumer ?? environmentOptions?.consumer;
|
|
2350
2650
|
return [
|
|
2351
2651
|
// vuePlugin 排最前(enforce: 'pre' 语义):.vue 先编译成 JS 再走后续管道
|
|
2352
|
-
...config.framework === "vue" ? [vuePlugin(pluginConfig)] : [],
|
|
2652
|
+
...config.framework === "vue" ? [vuePlugin(pluginConfig, opts.environmentName ?? "client")] : [],
|
|
2353
2653
|
resolvePlugin(pluginConfig),
|
|
2354
2654
|
cssPlugin(pluginConfig, opts.cssEngine, consumer),
|
|
2355
2655
|
assetsPlugin(pluginConfig),
|
|
@@ -2453,17 +2753,23 @@ var init_plugin_container = __esm({
|
|
|
2453
2753
|
}
|
|
2454
2754
|
async transform(code, id) {
|
|
2455
2755
|
let currentCode = code;
|
|
2756
|
+
let lastResult;
|
|
2456
2757
|
for (const plugin of this.plugins) {
|
|
2457
2758
|
if (!plugin.transform) continue;
|
|
2458
2759
|
const result = await plugin.transform.call(this.ctx, currentCode, id);
|
|
2459
2760
|
if (result == null) continue;
|
|
2460
2761
|
if (typeof result === "string") {
|
|
2461
2762
|
currentCode = result;
|
|
2763
|
+
lastResult = void 0;
|
|
2462
2764
|
} else {
|
|
2463
2765
|
currentCode = result.code;
|
|
2766
|
+
lastResult = result;
|
|
2464
2767
|
}
|
|
2465
2768
|
}
|
|
2466
|
-
return currentCode === code ? null : {
|
|
2769
|
+
return currentCode === code ? null : {
|
|
2770
|
+
...lastResult,
|
|
2771
|
+
code: currentCode
|
|
2772
|
+
};
|
|
2467
2773
|
}
|
|
2468
2774
|
/** 完整的模块处理管道: resolveId → load → transform */
|
|
2469
2775
|
async processModule(source, importer) {
|
|
@@ -2510,9 +2816,13 @@ var init_module_graph = __esm({
|
|
|
2510
2816
|
"use strict";
|
|
2511
2817
|
init_url();
|
|
2512
2818
|
ModuleGraph = class {
|
|
2819
|
+
environmentName;
|
|
2513
2820
|
urlToModuleMap = /* @__PURE__ */ new Map();
|
|
2514
2821
|
idToModuleMap = /* @__PURE__ */ new Map();
|
|
2515
2822
|
fileToModulesMap = /* @__PURE__ */ new Map();
|
|
2823
|
+
constructor(environmentName = "client") {
|
|
2824
|
+
this.environmentName = environmentName;
|
|
2825
|
+
}
|
|
2516
2826
|
getModuleByUrl(url) {
|
|
2517
2827
|
return this.urlToModuleMap.get(removeTimestampQuery(url));
|
|
2518
2828
|
}
|
|
@@ -2542,7 +2852,8 @@ var init_module_graph = __esm({
|
|
|
2542
2852
|
transformResult: null,
|
|
2543
2853
|
lastHMRTimestamp: 0,
|
|
2544
2854
|
invalidationVersion: 0,
|
|
2545
|
-
isSelfAccepting: false
|
|
2855
|
+
isSelfAccepting: false,
|
|
2856
|
+
environment: this.environmentName
|
|
2546
2857
|
};
|
|
2547
2858
|
this.idToModuleMap.set(mod.id, mod);
|
|
2548
2859
|
return mod;
|
|
@@ -2700,12 +3011,12 @@ function createNoopHotChannel() {
|
|
|
2700
3011
|
}
|
|
2701
3012
|
};
|
|
2702
3013
|
}
|
|
2703
|
-
function createWsHotChannel(ws) {
|
|
3014
|
+
function createWsHotChannel(ws, environmentName = "client") {
|
|
2704
3015
|
const listeners = /* @__PURE__ */ new Map();
|
|
2705
3016
|
let invokeHandlers;
|
|
2706
3017
|
return {
|
|
2707
3018
|
send(payload) {
|
|
2708
|
-
ws.send(payload);
|
|
3019
|
+
ws.send({ ...payload, environment: payload.environment ?? environmentName });
|
|
2709
3020
|
},
|
|
2710
3021
|
on(event, listener) {
|
|
2711
3022
|
let set = listeners.get(event);
|
|
@@ -2717,8 +3028,8 @@ function createWsHotChannel(ws) {
|
|
|
2717
3028
|
},
|
|
2718
3029
|
listen() {
|
|
2719
3030
|
},
|
|
3031
|
+
// 多个 environment 共享底层 WebSocket server;它由 DevServer.close() 统一关闭。
|
|
2720
3032
|
close() {
|
|
2721
|
-
ws.close();
|
|
2722
3033
|
},
|
|
2723
3034
|
setInvokeHandler(handlers) {
|
|
2724
3035
|
invokeHandlers = handlers;
|
|
@@ -2747,7 +3058,7 @@ function resolveEnvironmentPlugins(environment, plugins) {
|
|
|
2747
3058
|
}
|
|
2748
3059
|
});
|
|
2749
3060
|
}
|
|
2750
|
-
var
|
|
3061
|
+
var debug3, NastiEnvironment;
|
|
2751
3062
|
var init_environment = __esm({
|
|
2752
3063
|
"src/core/environment.ts"() {
|
|
2753
3064
|
"use strict";
|
|
@@ -2756,7 +3067,7 @@ var init_environment = __esm({
|
|
|
2756
3067
|
init_hot_channel();
|
|
2757
3068
|
init_debug();
|
|
2758
3069
|
init_plugin_api();
|
|
2759
|
-
|
|
3070
|
+
debug3 = createDebugger("nasti:environment");
|
|
2760
3071
|
NastiEnvironment = class {
|
|
2761
3072
|
name;
|
|
2762
3073
|
consumer;
|
|
@@ -2774,6 +3085,9 @@ var init_environment = __esm({
|
|
|
2774
3085
|
candidatePlugins;
|
|
2775
3086
|
pluginApi;
|
|
2776
3087
|
buildMetadata = {};
|
|
3088
|
+
cssModules = /* @__PURE__ */ new Map();
|
|
3089
|
+
assetModules = /* @__PURE__ */ new Map();
|
|
3090
|
+
transformRequestHandler;
|
|
2777
3091
|
initialized = false;
|
|
2778
3092
|
constructor(name, config, init = {}) {
|
|
2779
3093
|
const options = config.environments[name];
|
|
@@ -2788,7 +3102,7 @@ var init_environment = __esm({
|
|
|
2788
3102
|
this.config = config;
|
|
2789
3103
|
this.options = options;
|
|
2790
3104
|
this.hot = init.hot ?? createNoopHotChannel();
|
|
2791
|
-
this.moduleGraph = new ModuleGraph();
|
|
3105
|
+
this.moduleGraph = new ModuleGraph(name);
|
|
2792
3106
|
this.candidatePlugins = init.plugins ?? config.plugins;
|
|
2793
3107
|
this.pluginApi = init.pluginApi ?? getPluginApi(config);
|
|
2794
3108
|
}
|
|
@@ -2818,9 +3132,9 @@ var init_environment = __esm({
|
|
|
2818
3132
|
);
|
|
2819
3133
|
}
|
|
2820
3134
|
this.driver = claimed[0].driver;
|
|
2821
|
-
|
|
3135
|
+
debug3?.(`env "${this.name}" uses driver "${this.driver.name}"`);
|
|
2822
3136
|
}
|
|
2823
|
-
|
|
3137
|
+
debug3?.(`env "${this.name}" initialized (${this.plugins.length} plugins)`);
|
|
2824
3138
|
}
|
|
2825
3139
|
getDriverContext() {
|
|
2826
3140
|
return {
|
|
@@ -2830,6 +3144,37 @@ var init_environment = __esm({
|
|
|
2830
3144
|
logger: this.config.logger
|
|
2831
3145
|
};
|
|
2832
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
|
+
}
|
|
2833
3178
|
setBuildMetadata(metadata) {
|
|
2834
3179
|
const { entries: currentEntries, ...currentMetadata } = this.buildMetadata;
|
|
2835
3180
|
const { entries, ...nextMetadata } = metadata;
|
|
@@ -2940,7 +3285,7 @@ async function tryNativeReporterPlugin(config, logger) {
|
|
|
2940
3285
|
logInfo: (msg) => logger.info(msg)
|
|
2941
3286
|
});
|
|
2942
3287
|
} catch (err) {
|
|
2943
|
-
|
|
3288
|
+
debug4?.(`native viteReporterPlugin unavailable, falling back to JS table: ${err}`);
|
|
2944
3289
|
return null;
|
|
2945
3290
|
}
|
|
2946
3291
|
}
|
|
@@ -2995,7 +3340,7 @@ function warnLargeChunks(output, config, logger) {
|
|
|
2995
3340
|
)
|
|
2996
3341
|
);
|
|
2997
3342
|
}
|
|
2998
|
-
var import_node_path8, import_node_zlib, import_picocolors3,
|
|
3343
|
+
var import_node_path8, import_node_zlib, import_picocolors3, debug4, numberFormatter;
|
|
2999
3344
|
var init_reporter = __esm({
|
|
3000
3345
|
"src/build/reporter.ts"() {
|
|
3001
3346
|
"use strict";
|
|
@@ -3003,7 +3348,7 @@ var init_reporter = __esm({
|
|
|
3003
3348
|
import_node_zlib = require("zlib");
|
|
3004
3349
|
import_picocolors3 = __toESM(require("picocolors"), 1);
|
|
3005
3350
|
init_debug();
|
|
3006
|
-
|
|
3351
|
+
debug4 = createDebugger("nasti:reporter");
|
|
3007
3352
|
numberFormatter = new Intl.NumberFormat("en", {
|
|
3008
3353
|
maximumFractionDigits: 2,
|
|
3009
3354
|
minimumFractionDigits: 2
|
|
@@ -3043,6 +3388,24 @@ function createBuildAppContext(config, results) {
|
|
|
3043
3388
|
getManifest(environmentName) {
|
|
3044
3389
|
return results[environmentName]?.manifest;
|
|
3045
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
|
+
},
|
|
3046
3409
|
emitFile(file) {
|
|
3047
3410
|
const fileName = normalizeAppFileName(file.fileName);
|
|
3048
3411
|
const collisionKey = artifactCollisionKey(fileName);
|
|
@@ -3072,6 +3435,9 @@ function createBuildAppContext(config, results) {
|
|
|
3072
3435
|
}
|
|
3073
3436
|
};
|
|
3074
3437
|
}
|
|
3438
|
+
function joinPublicPath(base, fileName) {
|
|
3439
|
+
return `${base.endsWith("/") ? base : `${base}/`}${fileName.replace(/^\//, "")}`;
|
|
3440
|
+
}
|
|
3075
3441
|
function normalizeEnvironmentFileName(fileName) {
|
|
3076
3442
|
return import_node_path9.default.posix.normalize(fileName.replace(/\\/g, "/").replace(/^\.\//, ""));
|
|
3077
3443
|
}
|
|
@@ -3172,7 +3538,11 @@ function getRolldownOptions(environment, entryPoints, rolldownPlugins) {
|
|
|
3172
3538
|
const inputOptions = {
|
|
3173
3539
|
...restInputOptions,
|
|
3174
3540
|
input: entryPoints,
|
|
3175
|
-
transform: {
|
|
3541
|
+
transform: {
|
|
3542
|
+
...userTransform,
|
|
3543
|
+
target: userTransform?.target ?? envOptions.build.target,
|
|
3544
|
+
define: mergedDefine
|
|
3545
|
+
},
|
|
3176
3546
|
plugins: rolldownPlugins,
|
|
3177
3547
|
// client/server consumer 都必须使用当前环境的 conditions/mainFields;Lynx
|
|
3178
3548
|
// BG/MT 通常同为 client consumer,但仍可能声明不同的运行时条件。
|
|
@@ -3195,7 +3565,7 @@ function getRolldownOptions(environment, entryPoints, rolldownPlugins) {
|
|
|
3195
3565
|
};
|
|
3196
3566
|
const outputOptions = isServer ? {
|
|
3197
3567
|
format: "esm",
|
|
3198
|
-
sourcemap:
|
|
3568
|
+
sourcemap: envOptions.build.sourcemap,
|
|
3199
3569
|
minify: !!envOptions.build.minify,
|
|
3200
3570
|
entryFileNames: "[name].js",
|
|
3201
3571
|
chunkFileNames: "chunks/[name]-[hash].js",
|
|
@@ -3204,7 +3574,7 @@ function getRolldownOptions(environment, entryPoints, rolldownPlugins) {
|
|
|
3204
3574
|
dir: outDir
|
|
3205
3575
|
} : {
|
|
3206
3576
|
format: "esm",
|
|
3207
|
-
sourcemap:
|
|
3577
|
+
sourcemap: envOptions.build.sourcemap,
|
|
3208
3578
|
minify: !!envOptions.build.minify,
|
|
3209
3579
|
entryFileNames: `${assetsDir}/[name].[hash].js`,
|
|
3210
3580
|
chunkFileNames: `${assetsDir}/[name].[hash].js`,
|
|
@@ -3279,13 +3649,68 @@ function finalizeEnvironmentResult(environment, result) {
|
|
|
3279
3649
|
return [name, normalized];
|
|
3280
3650
|
})
|
|
3281
3651
|
);
|
|
3652
|
+
const inferredMetadata = inferOutputMetadata(environment, result.output);
|
|
3282
3653
|
return {
|
|
3654
|
+
publicPath: environment.config.base,
|
|
3655
|
+
...inferredMetadata,
|
|
3283
3656
|
...metadata,
|
|
3284
3657
|
...result,
|
|
3285
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
|
+
},
|
|
3286
3674
|
...Object.keys(normalizedEntries).length > 0 ? { entries: normalizedEntries } : {}
|
|
3287
3675
|
};
|
|
3288
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
|
+
}
|
|
3289
3714
|
function prepareBuildOutputDirectories(config, buildableNames) {
|
|
3290
3715
|
const directories = /* @__PURE__ */ new Set();
|
|
3291
3716
|
const protectedPaths = /* @__PURE__ */ new Set();
|
|
@@ -3363,6 +3788,7 @@ function createOxcTransformPlugin(config, environment) {
|
|
|
3363
3788
|
if (!shouldTransform(id)) return null;
|
|
3364
3789
|
const result = transformCode(id, code, {
|
|
3365
3790
|
sourcemap: !!environment.options.build.sourcemap,
|
|
3791
|
+
target: environment.options.build.target,
|
|
3366
3792
|
jsxRuntime: "automatic",
|
|
3367
3793
|
jsxImportSource: config.framework === "vue" ? "vue" : "react"
|
|
3368
3794
|
});
|
|
@@ -3376,9 +3802,9 @@ async function build(inlineConfig = {}) {
|
|
|
3376
3802
|
const startTime = performance.now();
|
|
3377
3803
|
logger.info(
|
|
3378
3804
|
import_picocolors4.default.cyan(`
|
|
3379
|
-
nasti v${"2.4.
|
|
3805
|
+
nasti v${"2.4.2"} `) + import_picocolors4.default.green(`building for ${config.mode}...`)
|
|
3380
3806
|
);
|
|
3381
|
-
|
|
3807
|
+
debug5?.(`root: ${config.root}`);
|
|
3382
3808
|
const buildableNames = Object.keys(config.environments).filter((name) => {
|
|
3383
3809
|
const environment = config.environments[name];
|
|
3384
3810
|
if (!environment.buildEnabled) return false;
|
|
@@ -3400,7 +3826,7 @@ nasti v${"2.4.0"} `) + import_picocolors4.default.green(`building for ${config.m
|
|
|
3400
3826
|
environmentResults[name] = built.result;
|
|
3401
3827
|
if (name === "client") clientOutput = built.result.output;
|
|
3402
3828
|
if (buildableNames.length > 1) {
|
|
3403
|
-
|
|
3829
|
+
debug5?.(`environment "${name}" built (${built.result.output.length} files)`);
|
|
3404
3830
|
}
|
|
3405
3831
|
}
|
|
3406
3832
|
const pluginApi = getPluginApi(config);
|
|
@@ -3496,6 +3922,7 @@ async function buildClientEnvironment(config) {
|
|
|
3496
3922
|
const bundle2 = await (0, import_rolldown.rolldown)(inputOptions);
|
|
3497
3923
|
const { output } = await bundle2.write(outputOptions);
|
|
3498
3924
|
await bundle2.close();
|
|
3925
|
+
clientEnv.setBuildMetadata({ css: getCssMetadata(cssEngine) });
|
|
3499
3926
|
if (html) {
|
|
3500
3927
|
let processedHtml = html;
|
|
3501
3928
|
const htmlPlugins = [...allPlugins.filter((p) => p.transformIndexHtml), htmlPlugin(config)];
|
|
@@ -3509,7 +3936,9 @@ async function buildClientEnvironment(config) {
|
|
|
3509
3936
|
processedHtml = processHtml(processedHtml, result);
|
|
3510
3937
|
}
|
|
3511
3938
|
}
|
|
3512
|
-
|
|
3939
|
+
if (clientEnv.options.build.css.inject !== false) {
|
|
3940
|
+
processedHtml = injectCssLinks(processedHtml, cssEngine, config);
|
|
3941
|
+
}
|
|
3513
3942
|
for (const chunk of output) {
|
|
3514
3943
|
if (chunk.type === "chunk" && chunk.isEntry && chunk.facadeModuleId) {
|
|
3515
3944
|
processedHtml = replaceEntryScript(
|
|
@@ -3547,9 +3976,11 @@ async function buildClientEnvironment(config) {
|
|
|
3547
3976
|
async function buildServerEnvironment(config, name) {
|
|
3548
3977
|
const envOptions = config.environments[name];
|
|
3549
3978
|
const logger = config.logger;
|
|
3979
|
+
const cssEngine = envOptions.consumer === "client" ? createCssEngine() : void 0;
|
|
3550
3980
|
const pluginList = resolvePluginList(config, config.plugins, {
|
|
3551
3981
|
consumer: envOptions.consumer,
|
|
3552
|
-
environmentName: name
|
|
3982
|
+
environmentName: name,
|
|
3983
|
+
cssEngine
|
|
3553
3984
|
});
|
|
3554
3985
|
const environment = new NastiEnvironment(name, config, {
|
|
3555
3986
|
mode: "build",
|
|
@@ -3592,6 +4023,7 @@ async function buildServerEnvironment(config, name) {
|
|
|
3592
4023
|
const bundle2 = await (0, import_rolldown.rolldown)(inputOptions);
|
|
3593
4024
|
const { output } = await bundle2.write(outputOptions);
|
|
3594
4025
|
await bundle2.close();
|
|
4026
|
+
if (cssEngine) environment.setBuildMetadata({ css: getCssMetadata(cssEngine) });
|
|
3595
4027
|
logger.info(
|
|
3596
4028
|
import_picocolors4.default.dim(` [${name}] `) + output.map((o) => import_node_path10.default.join(envOptions.build.outDir, o.fileName)).join(import_picocolors4.default.dim(", "))
|
|
3597
4029
|
);
|
|
@@ -3643,7 +4075,7 @@ function replaceEntryScript(html, facadeModuleId, fileName, config, htmlFile, ur
|
|
|
3643
4075
|
}
|
|
3644
4076
|
return processed;
|
|
3645
4077
|
}
|
|
3646
|
-
var import_node_path10, import_node_fs7, import_node_module3, import_rolldown, import_picocolors4,
|
|
4078
|
+
var import_node_path10, import_node_fs7, import_node_module3, import_rolldown, import_picocolors4, debug5, NODE_BUILTINS;
|
|
3647
4079
|
var init_build = __esm({
|
|
3648
4080
|
"src/build/index.ts"() {
|
|
3649
4081
|
"use strict";
|
|
@@ -3663,7 +4095,7 @@ var init_build = __esm({
|
|
|
3663
4095
|
init_plugin_api();
|
|
3664
4096
|
init_build_app_context();
|
|
3665
4097
|
import_picocolors4 = __toESM(require("picocolors"), 1);
|
|
3666
|
-
|
|
4098
|
+
debug5 = createDebugger("nasti:build");
|
|
3667
4099
|
NODE_BUILTINS = /* @__PURE__ */ new Set([...import_node_module3.builtinModules, ...import_node_module3.builtinModules.map((m) => `node:${m}`)]);
|
|
3668
4100
|
}
|
|
3669
4101
|
});
|
|
@@ -3714,13 +4146,6 @@ var init_ws = __esm({
|
|
|
3714
4146
|
});
|
|
3715
4147
|
|
|
3716
4148
|
// src/server/middleware.ts
|
|
3717
|
-
var middleware_exports = {};
|
|
3718
|
-
__export(middleware_exports, {
|
|
3719
|
-
REACT_REFRESH_GLOBAL_PREAMBLE: () => REACT_REFRESH_GLOBAL_PREAMBLE,
|
|
3720
|
-
getReactRefreshRuntimeEsm: () => getReactRefreshRuntimeEsm,
|
|
3721
|
-
transformMiddleware: () => transformMiddleware,
|
|
3722
|
-
transformRequest: () => transformRequest
|
|
3723
|
-
});
|
|
3724
4149
|
function getReactRefreshRuntimeEsm(includeBoundaryHelpers = false) {
|
|
3725
4150
|
if (__refreshRuntimeCache) {
|
|
3726
4151
|
return includeBoundaryHelpers ? __refreshRuntimeCache + REACT_REFRESH_BOUNDARY_HELPERS : __refreshRuntimeCache;
|
|
@@ -3823,7 +4248,8 @@ const __nasti_hot__ = __nasti_createHotContext__(${urlLit});
|
|
|
3823
4248
|
function transformMiddleware(ctx) {
|
|
3824
4249
|
ctx.envDefine = buildEnvDefine(
|
|
3825
4250
|
loadEnv(ctx.config.mode, ctx.config.root, ctx.config.envPrefix),
|
|
3826
|
-
ctx.config.mode
|
|
4251
|
+
ctx.config.mode,
|
|
4252
|
+
ssrDefineOverrides(ctx.environment?.consumer ?? "client")
|
|
3827
4253
|
);
|
|
3828
4254
|
return async (req, res, next) => {
|
|
3829
4255
|
const url = req.url ?? "/";
|
|
@@ -3868,7 +4294,7 @@ function transformMiddleware(ctx) {
|
|
|
3868
4294
|
return;
|
|
3869
4295
|
}
|
|
3870
4296
|
}
|
|
3871
|
-
if (isModuleRequest(url)) {
|
|
4297
|
+
if (isModuleRequest(url, req.headers["sec-fetch-dest"])) {
|
|
3872
4298
|
try {
|
|
3873
4299
|
const result = await transformRequest(url, ctx);
|
|
3874
4300
|
if (result) {
|
|
@@ -3939,12 +4365,16 @@ async function transformRequest(url, ctx) {
|
|
|
3939
4365
|
if (rawQuery && !/^t=\d+$/.test(rawQuery)) {
|
|
3940
4366
|
const mod2 = await moduleGraph.ensureEntryFromUrl(url);
|
|
3941
4367
|
const transformVersion2 = mod2.invalidationVersion;
|
|
3942
|
-
const
|
|
3943
|
-
if (
|
|
3944
|
-
let code2 = typeof
|
|
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;
|
|
3945
4372
|
const transformed = await pluginContainer.transform(code2, url);
|
|
3946
4373
|
if (transformed != null) {
|
|
3947
4374
|
code2 = typeof transformed === "string" ? transformed : transformed.code;
|
|
4375
|
+
if (typeof transformed !== "string" && transformed.map != null) {
|
|
4376
|
+
map2 = transformed.map;
|
|
4377
|
+
}
|
|
3948
4378
|
}
|
|
3949
4379
|
const parentFile = resolveUrlToFile(cleanReqUrl, config.root) ?? cleanReqUrl;
|
|
3950
4380
|
moduleGraph.registerModule(mod2, parentFile);
|
|
@@ -3952,7 +4382,8 @@ async function transformRequest(url, ctx) {
|
|
|
3952
4382
|
code2 = injectImportMetaHot(hotInfo2.code, url);
|
|
3953
4383
|
code2 = replaceEnvInCode(code2, ctx.envDefine ?? buildEnvDefine(
|
|
3954
4384
|
loadEnv(config.mode, config.root, config.envPrefix),
|
|
3955
|
-
config.mode
|
|
4385
|
+
config.mode,
|
|
4386
|
+
ssrDefineOverrides(ctx.environment?.consumer ?? "client")
|
|
3956
4387
|
));
|
|
3957
4388
|
const importedUrls2 = /* @__PURE__ */ new Set();
|
|
3958
4389
|
code2 = rewriteImports(code2, config, parentFile, importedUrls2, moduleGraph);
|
|
@@ -3963,7 +4394,7 @@ async function transformRequest(url, ctx) {
|
|
|
3963
4394
|
hotInfo2.isSelfAccepting,
|
|
3964
4395
|
transformVersion2
|
|
3965
4396
|
);
|
|
3966
|
-
const transformResult2 = { code: code2 };
|
|
4397
|
+
const transformResult2 = { code: code2, map: map2 };
|
|
3967
4398
|
if (pruned2) {
|
|
3968
4399
|
if (pruned2.size > 0) ctx.onPrune?.([...pruned2].map((item) => item.url));
|
|
3969
4400
|
mod2.transformResult = transformResult2;
|
|
@@ -3982,10 +4413,13 @@ async function transformRequest(url, ctx) {
|
|
|
3982
4413
|
mod.transformResult = transformResult2;
|
|
3983
4414
|
return transformResult2;
|
|
3984
4415
|
}
|
|
3985
|
-
|
|
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;
|
|
3986
4419
|
const pluginResult = await pluginContainer.transform(code, filePath);
|
|
3987
4420
|
if (pluginResult) {
|
|
3988
4421
|
code = typeof pluginResult === "string" ? pluginResult : pluginResult.code;
|
|
4422
|
+
if (typeof pluginResult !== "string") map = pluginResult.map;
|
|
3989
4423
|
}
|
|
3990
4424
|
const stableUrl = cleanReqUrl;
|
|
3991
4425
|
let wrappedWithRefresh = false;
|
|
@@ -3996,9 +4430,11 @@ async function transformRequest(url, ctx) {
|
|
|
3996
4430
|
sourcemap: true,
|
|
3997
4431
|
jsxRuntime: "automatic",
|
|
3998
4432
|
jsxImportSource: config.framework === "vue" ? "vue" : "react",
|
|
3999
|
-
reactRefresh: useRefresh
|
|
4433
|
+
reactRefresh: useRefresh,
|
|
4434
|
+
target: ctx.environment?.options.build.target ?? config.build.target
|
|
4000
4435
|
});
|
|
4001
4436
|
code = result.code;
|
|
4437
|
+
if (result.map) map = JSON.parse(result.map);
|
|
4002
4438
|
if (useRefresh) {
|
|
4003
4439
|
code = buildReactRefreshWrapper(stableUrl, code);
|
|
4004
4440
|
wrappedWithRefresh = true;
|
|
@@ -4011,7 +4447,8 @@ async function transformRequest(url, ctx) {
|
|
|
4011
4447
|
}
|
|
4012
4448
|
const envDefine = ctx.envDefine ?? buildEnvDefine(
|
|
4013
4449
|
loadEnv(config.mode, config.root, config.envPrefix),
|
|
4014
|
-
config.mode
|
|
4450
|
+
config.mode,
|
|
4451
|
+
ssrDefineOverrides(ctx.environment?.consumer ?? "client")
|
|
4015
4452
|
);
|
|
4016
4453
|
code = replaceEnvInCode(code, envDefine);
|
|
4017
4454
|
const importedUrls = /* @__PURE__ */ new Set();
|
|
@@ -4023,7 +4460,7 @@ async function transformRequest(url, ctx) {
|
|
|
4023
4460
|
wrappedWithRefresh || hotInfo.isSelfAccepting,
|
|
4024
4461
|
transformVersion
|
|
4025
4462
|
);
|
|
4026
|
-
const transformResult = { code };
|
|
4463
|
+
const transformResult = { code, map };
|
|
4027
4464
|
if (pruned) {
|
|
4028
4465
|
if (pruned.size > 0) ctx.onPrune?.([...pruned].map((item) => item.url));
|
|
4029
4466
|
mod.transformResult = transformResult;
|
|
@@ -4046,7 +4483,8 @@ async function loadVirtualModule(spec, ctx) {
|
|
|
4046
4483
|
}
|
|
4047
4484
|
code = replaceEnvInCode(code, ctx.envDefine ?? buildEnvDefine(
|
|
4048
4485
|
loadEnv(config.mode, config.root, config.envPrefix),
|
|
4049
|
-
config.mode
|
|
4486
|
+
config.mode,
|
|
4487
|
+
ssrDefineOverrides(ctx.environment?.consumer ?? "client")
|
|
4050
4488
|
));
|
|
4051
4489
|
const anchor = import_node_path12.default.join(config.root, "__nasti_virtual__.ts");
|
|
4052
4490
|
code = rewriteImports(code, config, anchor);
|
|
@@ -4591,10 +5029,15 @@ function resolveUrlToFile(url, root) {
|
|
|
4591
5029
|
}
|
|
4592
5030
|
return null;
|
|
4593
5031
|
}
|
|
4594
|
-
function isModuleRequest(url) {
|
|
5032
|
+
function isModuleRequest(url, destination) {
|
|
4595
5033
|
const cleanUrl = url.split("?")[0];
|
|
4596
5034
|
if (/\.(ts|tsx|jsx|js|mjs|vue|css|json)$/.test(cleanUrl)) return true;
|
|
4597
5035
|
if (cleanUrl.startsWith("/@modules/")) return true;
|
|
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
|
+
}
|
|
4598
5041
|
if (!import_node_path12.default.extname(cleanUrl)) return true;
|
|
4599
5042
|
return false;
|
|
4600
5043
|
}
|
|
@@ -4607,11 +5050,15 @@ const hotModulesMap = new Map();
|
|
|
4607
5050
|
const disposeMap = new Map();
|
|
4608
5051
|
const pruneMap = new Map();
|
|
4609
5052
|
const dataMap = new Map();
|
|
5053
|
+
const customListenersMap = new Map();
|
|
4610
5054
|
let updateQueue = [];
|
|
4611
5055
|
let pendingUpdateQueue = false;
|
|
4612
5056
|
|
|
4613
5057
|
socket.addEventListener('message', async ({ data }) => {
|
|
4614
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;
|
|
4615
5062
|
switch (payload.type) {
|
|
4616
5063
|
case 'connected':
|
|
4617
5064
|
console.debug('[nasti] connected.');
|
|
@@ -4644,8 +5091,24 @@ socket.addEventListener('message', async ({ data }) => {
|
|
|
4644
5091
|
disposeMap.delete(path);
|
|
4645
5092
|
pruneMap.delete(path);
|
|
4646
5093
|
dataMap.delete(path);
|
|
5094
|
+
clearCustomListeners(path);
|
|
4647
5095
|
}));
|
|
4648
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
|
+
}
|
|
4649
5112
|
case 'error':
|
|
4650
5113
|
console.error('[nasti] error:', payload.err.message);
|
|
4651
5114
|
showErrorOverlay(payload.err);
|
|
@@ -4744,6 +5207,7 @@ export function createHotContext(ownerPath) {
|
|
|
4744
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
|
|
4745
5208
|
const existing = hotModulesMap.get(ownerPath);
|
|
4746
5209
|
if (existing) existing.callbacks = [];
|
|
5210
|
+
clearCustomListeners(ownerPath);
|
|
4747
5211
|
|
|
4748
5212
|
const acceptDeps = (deps, callback = () => {}) => {
|
|
4749
5213
|
const mod = hotModulesMap.get(ownerPath) || { id: ownerPath, callbacks: [] };
|
|
@@ -4769,12 +5233,39 @@ export function createHotContext(ownerPath) {
|
|
|
4769
5233
|
dispose(callback) {
|
|
4770
5234
|
disposeMap.set(ownerPath, callback);
|
|
4771
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
|
+
},
|
|
4772
5256
|
invalidate() {
|
|
4773
5257
|
location.reload();
|
|
4774
5258
|
},
|
|
4775
5259
|
data: dataMap.get(ownerPath),
|
|
4776
5260
|
};
|
|
4777
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
|
+
}
|
|
4778
5269
|
`;
|
|
4779
5270
|
}
|
|
4780
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;
|
|
@@ -4790,6 +5281,7 @@ var init_middleware = __esm({
|
|
|
4790
5281
|
init_html();
|
|
4791
5282
|
init_env();
|
|
4792
5283
|
init_url();
|
|
5284
|
+
init_assets();
|
|
4793
5285
|
import_meta = {};
|
|
4794
5286
|
__dirname_esm = import_node_path12.default.dirname((0, import_node_url3.fileURLToPath)(import_meta.url));
|
|
4795
5287
|
__require = (0, import_node_module5.createRequire)(import_meta.url);
|
|
@@ -4872,19 +5364,25 @@ window.__vite_plugin_react_preamble_installed__ = true;
|
|
|
4872
5364
|
});
|
|
4873
5365
|
|
|
4874
5366
|
// src/server/hmr.ts
|
|
4875
|
-
async function handleFileChange(file, server) {
|
|
4876
|
-
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;
|
|
4877
5374
|
const logger = config.logger;
|
|
4878
5375
|
const relativePath = "/" + import_node_path13.default.relative(config.root, file);
|
|
4879
5376
|
const shortFile = import_node_path13.default.relative(config.root, file);
|
|
4880
5377
|
const mods = moduleGraph.getModulesByFile(file);
|
|
4881
5378
|
if (!mods || mods.size === 0) {
|
|
4882
|
-
return;
|
|
5379
|
+
return null;
|
|
4883
5380
|
}
|
|
4884
5381
|
const updates = [];
|
|
4885
|
-
const timestamp = Date.now();
|
|
4886
5382
|
const graph = moduleGraph;
|
|
4887
5383
|
const invalidatedModules = /* @__PURE__ */ new Set();
|
|
5384
|
+
const affectedSet = /* @__PURE__ */ new Set();
|
|
5385
|
+
let fullReload = false;
|
|
4888
5386
|
for (const mod of mods) {
|
|
4889
5387
|
graph.invalidateModuleAndImporters(mod, timestamp, invalidatedModules);
|
|
4890
5388
|
const ctx = {
|
|
@@ -4892,10 +5390,11 @@ async function handleFileChange(file, server) {
|
|
|
4892
5390
|
timestamp,
|
|
4893
5391
|
modules: [mod],
|
|
4894
5392
|
read: () => import_node_fs10.default.readFileSync(file, "utf-8"),
|
|
4895
|
-
server
|
|
5393
|
+
server,
|
|
5394
|
+
environment
|
|
4896
5395
|
};
|
|
4897
5396
|
let affectedModules = [mod];
|
|
4898
|
-
for (const plugin of
|
|
5397
|
+
for (const plugin of environment.plugins) {
|
|
4899
5398
|
if (plugin.handleHotUpdate) {
|
|
4900
5399
|
const result = await plugin.handleHotUpdate(ctx);
|
|
4901
5400
|
if (result) {
|
|
@@ -4904,12 +5403,12 @@ async function handleFileChange(file, server) {
|
|
|
4904
5403
|
}
|
|
4905
5404
|
}
|
|
4906
5405
|
for (const affected of affectedModules) {
|
|
5406
|
+
affectedSet.add(affected);
|
|
4907
5407
|
graph.invalidateModuleAndImporters(affected, timestamp, invalidatedModules);
|
|
4908
5408
|
const boundaries = graph.getHmrBoundaries(affected);
|
|
4909
5409
|
if (boundaries.length === 0) {
|
|
4910
|
-
|
|
4911
|
-
|
|
4912
|
-
return;
|
|
5410
|
+
fullReload = true;
|
|
5411
|
+
continue;
|
|
4913
5412
|
}
|
|
4914
5413
|
for (const { boundary, acceptedVia } of boundaries) {
|
|
4915
5414
|
const update = {
|
|
@@ -4926,13 +5425,30 @@ async function handleFileChange(file, server) {
|
|
|
4926
5425
|
}
|
|
4927
5426
|
}
|
|
4928
5427
|
}
|
|
4929
|
-
|
|
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) {
|
|
4930
5439
|
logger.info(
|
|
4931
|
-
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"),
|
|
4932
5441
|
{ timestamp: true }
|
|
4933
5442
|
);
|
|
4934
|
-
|
|
5443
|
+
environment.hot.send({ type: "update", updates });
|
|
4935
5444
|
}
|
|
5445
|
+
return {
|
|
5446
|
+
environment,
|
|
5447
|
+
modules: [...affectedSet],
|
|
5448
|
+
updates,
|
|
5449
|
+
transformed,
|
|
5450
|
+
fullReload
|
|
5451
|
+
};
|
|
4936
5452
|
}
|
|
4937
5453
|
var import_node_path13, import_node_fs10, import_picocolors7;
|
|
4938
5454
|
var init_hmr = __esm({
|
|
@@ -4958,7 +5474,7 @@ function createModuleRunner(environment) {
|
|
|
4958
5474
|
}
|
|
4959
5475
|
return new NastiModuleRunner(environment);
|
|
4960
5476
|
}
|
|
4961
|
-
var import_node_path14, import_node_fs11, import_node_module6, import_node_url4,
|
|
5477
|
+
var import_node_path14, import_node_fs11, import_node_module6, import_node_url4, debug6, NODE_BUILTINS3, NastiModuleRunner, AsyncFunction;
|
|
4962
5478
|
var init_runnable_environment = __esm({
|
|
4963
5479
|
"src/server/runnable-environment.ts"() {
|
|
4964
5480
|
"use strict";
|
|
@@ -4969,7 +5485,7 @@ var init_runnable_environment = __esm({
|
|
|
4969
5485
|
init_transformer();
|
|
4970
5486
|
init_env();
|
|
4971
5487
|
init_debug();
|
|
4972
|
-
|
|
5488
|
+
debug6 = createDebugger("nasti:ssr");
|
|
4973
5489
|
NODE_BUILTINS3 = /* @__PURE__ */ new Set([...import_node_module6.builtinModules, ...import_node_module6.builtinModules.map((m) => `node:${m}`)]);
|
|
4974
5490
|
NastiModuleRunner = class {
|
|
4975
5491
|
environment;
|
|
@@ -5047,6 +5563,7 @@ var init_runnable_environment = __esm({
|
|
|
5047
5563
|
if (shouldTransform(cleanId)) {
|
|
5048
5564
|
const result = transformCode(cleanId, code, {
|
|
5049
5565
|
sourcemap: false,
|
|
5566
|
+
target: this.environment.options.build.target,
|
|
5050
5567
|
jsxRuntime: "automatic",
|
|
5051
5568
|
jsxImportSource: this.config.framework === "vue" ? "vue" : "react"
|
|
5052
5569
|
});
|
|
@@ -5063,7 +5580,7 @@ var init_runnable_environment = __esm({
|
|
|
5063
5580
|
);
|
|
5064
5581
|
}
|
|
5065
5582
|
const runnerResult = await moduleRunnerTransform(resolvedId, code);
|
|
5066
|
-
|
|
5583
|
+
debug6?.(`fetchModule ${resolvedId} (${runnerResult.deps?.length ?? 0} deps)`);
|
|
5067
5584
|
return { id: resolvedId, code: runnerResult.code };
|
|
5068
5585
|
}
|
|
5069
5586
|
completeExtension(id) {
|
|
@@ -5183,7 +5700,7 @@ async function createBundledDevServer(opts) {
|
|
|
5183
5700
|
}
|
|
5184
5701
|
} catch (err) {
|
|
5185
5702
|
throw new Error(
|
|
5186
|
-
`[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.`
|
|
5187
5704
|
);
|
|
5188
5705
|
}
|
|
5189
5706
|
const html = await readHtmlFile(config.root, config.environments.client?.html);
|
|
@@ -5236,7 +5753,7 @@ async function createBundledDevServer(opts) {
|
|
|
5236
5753
|
for (const { clientId, update } of updates) {
|
|
5237
5754
|
if (update.type === "Noop") continue;
|
|
5238
5755
|
if (update.type === "FullReload") {
|
|
5239
|
-
|
|
5756
|
+
debug7?.(`full reload for ${clientId}: ${update.reason ?? ""}`);
|
|
5240
5757
|
needsLatestOutput = true;
|
|
5241
5758
|
continue;
|
|
5242
5759
|
}
|
|
@@ -5286,7 +5803,7 @@ async function createBundledDevServer(opts) {
|
|
|
5286
5803
|
},
|
|
5287
5804
|
{
|
|
5288
5805
|
watch: { skipWrite: true },
|
|
5289
|
-
rebuildStrategy: "
|
|
5806
|
+
rebuildStrategy: "never",
|
|
5290
5807
|
onOutput(result) {
|
|
5291
5808
|
if (result instanceof Error) {
|
|
5292
5809
|
logger.error(import_picocolors8.default.red(`[bundled] build error: ${result.message}`), { error: result });
|
|
@@ -5302,7 +5819,13 @@ async function createBundledDevServer(opts) {
|
|
|
5302
5819
|
memoryFiles.set(`${file.fileName}.map`, JSON.stringify(file.map));
|
|
5303
5820
|
}
|
|
5304
5821
|
}
|
|
5305
|
-
|
|
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
|
+
}
|
|
5306
5829
|
},
|
|
5307
5830
|
async onHmrUpdates(result) {
|
|
5308
5831
|
if (result instanceof Error) {
|
|
@@ -5311,7 +5834,7 @@ async function createBundledDevServer(opts) {
|
|
|
5311
5834
|
return;
|
|
5312
5835
|
}
|
|
5313
5836
|
const { updates, changedFiles } = result;
|
|
5314
|
-
|
|
5837
|
+
debug7?.(
|
|
5315
5838
|
`onHmrUpdates(engine watcher): ${changedFiles.length} changed, ${updates.length} updates`
|
|
5316
5839
|
);
|
|
5317
5840
|
if (changedFiles.length === 0) return;
|
|
@@ -5330,24 +5853,29 @@ async function createBundledDevServer(opts) {
|
|
|
5330
5853
|
if (!clientId) return;
|
|
5331
5854
|
wss.handleUpgrade(req, socket, head, (ws) => {
|
|
5332
5855
|
bundledClients.set(clientId, ws);
|
|
5333
|
-
|
|
5334
|
-
|
|
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
|
+
});
|
|
5335
5866
|
ws.on("message", async (raw) => {
|
|
5336
5867
|
try {
|
|
5337
5868
|
const msg = JSON.parse(String(raw));
|
|
5338
|
-
if (msg.type === "hmr:
|
|
5339
|
-
await engine.registerModules(clientId, msg.modules);
|
|
5340
|
-
debug6?.(`registered ${msg.modules.length} modules for ${clientId}`);
|
|
5341
|
-
} else if (msg.type === "hmr:invalidate") {
|
|
5869
|
+
if (msg.type === "hmr:invalidate") {
|
|
5342
5870
|
scheduleFullReload();
|
|
5343
5871
|
}
|
|
5344
5872
|
} catch (err) {
|
|
5345
|
-
|
|
5873
|
+
debug7?.(`bundled ws message error: ${err.message}`);
|
|
5346
5874
|
}
|
|
5347
5875
|
});
|
|
5348
5876
|
ws.on("close", () => {
|
|
5349
5877
|
bundledClients.delete(clientId);
|
|
5350
|
-
engine.removeClient(clientId).catch((err) =>
|
|
5878
|
+
engine.removeClient(clientId).catch((err) => debug7?.(`removeClient failed for ${clientId}: ${err?.message ?? err}`));
|
|
5351
5879
|
});
|
|
5352
5880
|
});
|
|
5353
5881
|
});
|
|
@@ -5364,10 +5892,18 @@ async function createBundledDevServer(opts) {
|
|
|
5364
5892
|
res.end("// [nasti] lazy endpoint requires id & clientId");
|
|
5365
5893
|
return;
|
|
5366
5894
|
}
|
|
5367
|
-
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
|
+
});
|
|
5368
5904
|
res.setHeader("Content-Type", "application/javascript");
|
|
5369
5905
|
res.setHeader("Cache-Control", "no-store");
|
|
5370
|
-
res.end(code + "\n;export {}");
|
|
5906
|
+
res.end(output.code + "\n;export {}");
|
|
5371
5907
|
return;
|
|
5372
5908
|
}
|
|
5373
5909
|
const patchHit = patches.get(pathname.replace(/^\//, ""));
|
|
@@ -5388,6 +5924,11 @@ async function createBundledDevServer(opts) {
|
|
|
5388
5924
|
res.setHeader("ETag", hit.etag);
|
|
5389
5925
|
res.setHeader("Content-Type", MIME_TYPES[import_node_path15.default.extname(fileName)] ?? "application/octet-stream");
|
|
5390
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
|
+
});
|
|
5391
5932
|
res.end(hit.content);
|
|
5392
5933
|
return;
|
|
5393
5934
|
}
|
|
@@ -5487,7 +6028,7 @@ async function renderBundledIndexHtml(html, config, entryFileNames) {
|
|
|
5487
6028
|
}
|
|
5488
6029
|
return processed;
|
|
5489
6030
|
}
|
|
5490
|
-
var import_node_path15, import_node_crypto3, import_ws2, import_picocolors8,
|
|
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;
|
|
5491
6032
|
var init_dev_engine = __esm({
|
|
5492
6033
|
"src/server/bundled/dev-engine.ts"() {
|
|
5493
6034
|
"use strict";
|
|
@@ -5500,7 +6041,7 @@ var init_dev_engine = __esm({
|
|
|
5500
6041
|
init_transformer();
|
|
5501
6042
|
init_middleware();
|
|
5502
6043
|
init_debug();
|
|
5503
|
-
|
|
6044
|
+
debug7 = createDebugger("nasti:bundled");
|
|
5504
6045
|
MIME_TYPES = {
|
|
5505
6046
|
".js": "application/javascript",
|
|
5506
6047
|
".mjs": "application/javascript",
|
|
@@ -5627,7 +6168,7 @@ async function createServer(inlineConfig = {}) {
|
|
|
5627
6168
|
const ws = createWebSocketServer(httpServer);
|
|
5628
6169
|
const pluginApi = getPluginApi(config);
|
|
5629
6170
|
const clientEnv = new NastiEnvironment("client", config, {
|
|
5630
|
-
hot: createWsHotChannel(ws),
|
|
6171
|
+
hot: createWsHotChannel(ws, "client"),
|
|
5631
6172
|
mode: "dev",
|
|
5632
6173
|
plugins: allPlugins,
|
|
5633
6174
|
pluginApi
|
|
@@ -5642,13 +6183,40 @@ async function createServer(inlineConfig = {}) {
|
|
|
5642
6183
|
environmentName: name
|
|
5643
6184
|
});
|
|
5644
6185
|
environments[name] = new NastiEnvironment(name, config, {
|
|
6186
|
+
hot: consumer === "client" ? createWsHotChannel(ws, name) : void 0,
|
|
5645
6187
|
mode: "dev",
|
|
5646
6188
|
plugins: envPlugins,
|
|
5647
6189
|
pluginApi
|
|
5648
6190
|
});
|
|
5649
6191
|
}
|
|
5650
6192
|
for (const [name, environment] of Object.entries(environments)) {
|
|
5651
|
-
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));
|
|
5652
6220
|
}
|
|
5653
6221
|
let ssrRunner = null;
|
|
5654
6222
|
async function getSsrRunner() {
|
|
@@ -5663,7 +6231,6 @@ async function createServer(inlineConfig = {}) {
|
|
|
5663
6231
|
return ssrRunner;
|
|
5664
6232
|
}
|
|
5665
6233
|
const moduleGraph = clientEnv.moduleGraph;
|
|
5666
|
-
const pluginContainer = clientEnv.pluginContainer;
|
|
5667
6234
|
let bundledServer = null;
|
|
5668
6235
|
if (config.experimental.bundledDev) {
|
|
5669
6236
|
const { createBundledDevServer: createBundledDevServer2 } = await Promise.resolve().then(() => (init_dev_engine(), dev_engine_exports));
|
|
@@ -5692,6 +6259,15 @@ async function createServer(inlineConfig = {}) {
|
|
|
5692
6259
|
let server;
|
|
5693
6260
|
const environmentServices = {};
|
|
5694
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
|
+
};
|
|
5695
6271
|
const logCloseError = (target, error) => {
|
|
5696
6272
|
const normalized = error instanceof Error ? error : new Error(String(error));
|
|
5697
6273
|
logger.error(`[nasti] failed to close ${target}`, { error: normalized });
|
|
@@ -5743,14 +6319,61 @@ async function createServer(inlineConfig = {}) {
|
|
|
5743
6319
|
});
|
|
5744
6320
|
}
|
|
5745
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
|
+
};
|
|
5746
6369
|
watcher.on("change", (file) => {
|
|
5747
6370
|
ssrRunner?.invalidateFile(file);
|
|
5748
|
-
|
|
6371
|
+
queueClientEnvironmentUpdate(file);
|
|
5749
6372
|
notifyEnvironmentDrivers(file, "change");
|
|
5750
6373
|
});
|
|
5751
6374
|
watcher.on("add", (file) => {
|
|
5752
6375
|
ssrRunner?.invalidateFile(file);
|
|
5753
|
-
|
|
6376
|
+
queueClientEnvironmentUpdate(file);
|
|
5754
6377
|
notifyEnvironmentDrivers(file, "add");
|
|
5755
6378
|
});
|
|
5756
6379
|
watcher.on("unlink", (file) => {
|
|
@@ -5768,7 +6391,7 @@ async function createServer(inlineConfig = {}) {
|
|
|
5768
6391
|
async listen(port) {
|
|
5769
6392
|
const finalPort = port ?? config.server.port;
|
|
5770
6393
|
const host = config.server.host === true ? "0.0.0.0" : config.server.host;
|
|
5771
|
-
await
|
|
6394
|
+
await startDevPipelines();
|
|
5772
6395
|
await startEnvironmentDrivers();
|
|
5773
6396
|
return new Promise((resolve, reject) => {
|
|
5774
6397
|
let currentPort = finalPort;
|
|
@@ -5783,7 +6406,7 @@ async function createServer(inlineConfig = {}) {
|
|
|
5783
6406
|
const readyIn = Math.ceil(performance.now() - startTime);
|
|
5784
6407
|
logger.info(
|
|
5785
6408
|
`
|
|
5786
|
-
${import_picocolors9.default.cyan(import_picocolors9.default.bold("NASTI"))} ${import_picocolors9.default.cyan(`v${"2.4.
|
|
6409
|
+
${import_picocolors9.default.cyan(import_picocolors9.default.bold("NASTI"))} ${import_picocolors9.default.cyan(`v${"2.4.2"}`)} ${import_picocolors9.default.dim("ready in")} ${import_picocolors9.default.bold(readyIn)} ${import_picocolors9.default.dim("ms")}
|
|
5787
6410
|
`
|
|
5788
6411
|
);
|
|
5789
6412
|
printServerUrls(
|
|
@@ -5810,20 +6433,26 @@ async function createServer(inlineConfig = {}) {
|
|
|
5810
6433
|
});
|
|
5811
6434
|
},
|
|
5812
6435
|
async transformRequest(url) {
|
|
5813
|
-
|
|
5814
|
-
|
|
5815
|
-
|
|
5816
|
-
|
|
5817
|
-
|
|
5818
|
-
|
|
5819
|
-
}
|
|
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);
|
|
5820
6444
|
},
|
|
5821
6445
|
async ssrLoadModule(url) {
|
|
5822
6446
|
const runner = await getSsrRunner();
|
|
5823
6447
|
return runner.import(url);
|
|
5824
6448
|
},
|
|
5825
6449
|
async close() {
|
|
5826
|
-
|
|
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
|
+
}
|
|
5827
6456
|
await bundledServer?.close();
|
|
5828
6457
|
let environmentCloseFailed = false;
|
|
5829
6458
|
let firstEnvironmentCloseError;
|
|
@@ -5873,12 +6502,7 @@ async function createServer(inlineConfig = {}) {
|
|
|
5873
6502
|
}
|
|
5874
6503
|
throw error;
|
|
5875
6504
|
}
|
|
5876
|
-
app.use(transformMiddleware(
|
|
5877
|
-
config: configWithPlugins,
|
|
5878
|
-
pluginContainer,
|
|
5879
|
-
moduleGraph,
|
|
5880
|
-
onPrune: (paths) => ws.send({ type: "prune", paths })
|
|
5881
|
-
}));
|
|
6505
|
+
app.use(transformMiddleware(transformContexts.get("client")));
|
|
5882
6506
|
const publicDir = import_node_path16.default.resolve(config.root, "public");
|
|
5883
6507
|
app.use((0, import_sirv.default)(publicDir, { dev: true, etag: true }));
|
|
5884
6508
|
app.use((0, import_sirv.default)(config.root, { dev: true, etag: true }));
|
|
@@ -5925,6 +6549,7 @@ var init_server = __esm({
|
|
|
5925
6549
|
init_hmr();
|
|
5926
6550
|
init_builtins();
|
|
5927
6551
|
init_plugin_api();
|
|
6552
|
+
init_env();
|
|
5928
6553
|
}
|
|
5929
6554
|
});
|
|
5930
6555
|
|
|
@@ -6006,7 +6631,7 @@ async function buildElectron(inlineConfig = {}) {
|
|
|
6006
6631
|
const config = await resolveConfig({ ...inlineConfig, target: "electron" }, "build");
|
|
6007
6632
|
const startTime = performance.now();
|
|
6008
6633
|
assertElectronVersion(config);
|
|
6009
|
-
console.log(import_picocolors5.default.cyan("\n\u26A1 nasti build (electron)") + import_picocolors5.default.dim(` v${"2.4.
|
|
6634
|
+
console.log(import_picocolors5.default.cyan("\n\u26A1 nasti build (electron)") + import_picocolors5.default.dim(` v${"2.4.2"}`));
|
|
6010
6635
|
console.log(import_picocolors5.default.dim(` root: ${config.root}`));
|
|
6011
6636
|
console.log(import_picocolors5.default.dim(` mode: ${config.mode}`));
|
|
6012
6637
|
console.log(import_picocolors5.default.dim(` target: electron (\u2265 ${config.electron.minVersion})`));
|
|
@@ -6179,7 +6804,7 @@ async function startElectronDev(inlineConfig = {}) {
|
|
|
6179
6804
|
const { noSpawn, ...rest } = inlineConfig;
|
|
6180
6805
|
const config = await resolveConfig({ ...rest, target: "electron" }, "serve");
|
|
6181
6806
|
warnElectronVersion(config);
|
|
6182
|
-
console.log(import_picocolors10.default.cyan("\n\u26A1 nasti electron dev") + import_picocolors10.default.dim(` v${"2.4.
|
|
6807
|
+
console.log(import_picocolors10.default.cyan("\n\u26A1 nasti electron dev") + import_picocolors10.default.dim(` v${"2.4.2"}`));
|
|
6183
6808
|
const { createServer: createServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
|
|
6184
6809
|
const server = await createServer2({
|
|
6185
6810
|
...rest,
|