@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.js
CHANGED
|
@@ -70,7 +70,10 @@ var init_defaults = __esm({
|
|
|
70
70
|
target: "es2022",
|
|
71
71
|
rolldownOptions: {},
|
|
72
72
|
emptyOutDir: true,
|
|
73
|
-
css: {
|
|
73
|
+
css: {
|
|
74
|
+
inject: true,
|
|
75
|
+
emit: true
|
|
76
|
+
},
|
|
74
77
|
reportCompressedSize: true,
|
|
75
78
|
chunkSizeWarningLimit: 500,
|
|
76
79
|
cssCodeSplit: true,
|
|
@@ -425,7 +428,11 @@ async function resolveConfig(inlineConfig = {}, command) {
|
|
|
425
428
|
allowClearScreen: clearScreen2,
|
|
426
429
|
customLogger: merged.customLogger
|
|
427
430
|
});
|
|
428
|
-
const mergedBuild = {
|
|
431
|
+
const mergedBuild = {
|
|
432
|
+
...defaults.build,
|
|
433
|
+
...merged.build,
|
|
434
|
+
css: { ...defaults.build.css, ...merged.build?.css }
|
|
435
|
+
};
|
|
429
436
|
if (merged.build?.cssMinify === void 0) {
|
|
430
437
|
mergedBuild.cssMinify = !!mergedBuild.minify;
|
|
431
438
|
}
|
|
@@ -456,11 +463,17 @@ async function resolveConfig(inlineConfig = {}, command) {
|
|
|
456
463
|
bundledDev: merged.experimental?.bundledDev ?? defaults.experimental.bundledDev
|
|
457
464
|
}
|
|
458
465
|
};
|
|
459
|
-
const
|
|
466
|
+
const rawUserEnvironments = {
|
|
460
467
|
client: {},
|
|
461
468
|
ssr: {},
|
|
462
469
|
...merged.environments ?? {}
|
|
463
470
|
};
|
|
471
|
+
const userEnvironments = Object.fromEntries(
|
|
472
|
+
Object.entries(rawUserEnvironments).map(([name, options]) => [
|
|
473
|
+
name,
|
|
474
|
+
deepMerge({}, options)
|
|
475
|
+
])
|
|
476
|
+
);
|
|
464
477
|
for (const [name, envOptions] of Object.entries(userEnvironments)) {
|
|
465
478
|
for (const plugin of rawPlugins) {
|
|
466
479
|
if (plugin.configEnvironment) {
|
|
@@ -471,6 +484,7 @@ async function resolveConfig(inlineConfig = {}, command) {
|
|
|
471
484
|
}
|
|
472
485
|
for (const [name, envOptions] of Object.entries(userEnvironments)) {
|
|
473
486
|
const consumer = envOptions.consumer ?? (name === "client" ? "client" : "server");
|
|
487
|
+
const vueOptions = deepMerge({}, envOptions.vue ?? {});
|
|
474
488
|
if (name === "client") {
|
|
475
489
|
if (envOptions.resolve) {
|
|
476
490
|
Object.assign(resolved.resolve, {
|
|
@@ -478,7 +492,11 @@ async function resolveConfig(inlineConfig = {}, command) {
|
|
|
478
492
|
alias: { ...resolved.resolve.alias, ...envOptions.resolve.alias }
|
|
479
493
|
});
|
|
480
494
|
}
|
|
481
|
-
if (envOptions.build)
|
|
495
|
+
if (envOptions.build) {
|
|
496
|
+
const { css, ...environmentBuild } = envOptions.build;
|
|
497
|
+
Object.assign(resolved.build, environmentBuild);
|
|
498
|
+
if (css) resolved.build.css = { ...resolved.build.css, ...css };
|
|
499
|
+
}
|
|
482
500
|
resolved.environments.client = {
|
|
483
501
|
consumer,
|
|
484
502
|
buildEnabled: envOptions.buildEnabled ?? true,
|
|
@@ -490,7 +508,8 @@ async function resolveConfig(inlineConfig = {}, command) {
|
|
|
490
508
|
driver: envOptions.driver,
|
|
491
509
|
// 同引用 —— 精确镜像(assertClientEnvironmentMirror 校验)
|
|
492
510
|
resolve: resolved.resolve,
|
|
493
|
-
build: resolved.build
|
|
511
|
+
build: resolved.build,
|
|
512
|
+
vue: vueOptions
|
|
494
513
|
};
|
|
495
514
|
continue;
|
|
496
515
|
}
|
|
@@ -500,6 +519,7 @@ async function resolveConfig(inlineConfig = {}, command) {
|
|
|
500
519
|
entry: normalizeEnvironmentEntries(envOptions.entry, root),
|
|
501
520
|
html: envOptions.consumer === "client" && envOptions.html ? path.resolve(root, envOptions.html) : void 0,
|
|
502
521
|
driver: envOptions.driver,
|
|
522
|
+
vue: vueOptions,
|
|
503
523
|
resolve: {
|
|
504
524
|
alias: { ...resolved.resolve.alias, ...envOptions.resolve?.alias },
|
|
505
525
|
extensions: envOptions.resolve?.extensions ?? [...resolved.resolve.extensions],
|
|
@@ -510,6 +530,7 @@ async function resolveConfig(inlineConfig = {}, command) {
|
|
|
510
530
|
build: {
|
|
511
531
|
...resolved.build,
|
|
512
532
|
...envOptions.build,
|
|
533
|
+
css: { ...resolved.build.css, ...envOptions.build?.css },
|
|
513
534
|
// 非 client 环境默认产出到 <outDir>/<envName>(如 dist/ssr),可显式覆盖
|
|
514
535
|
outDir: envOptions.build?.outDir ?? path.join(resolved.build.outDir, name),
|
|
515
536
|
// server 产物默认不压缩(可调试性优先,与 Vite SSR 默认一致),可显式覆盖
|
|
@@ -742,7 +763,7 @@ function resolvePlugin(config) {
|
|
|
742
763
|
const content = fs2.readFileSync(id, "utf-8");
|
|
743
764
|
return `export default ${content}`;
|
|
744
765
|
}
|
|
745
|
-
return
|
|
766
|
+
return null;
|
|
746
767
|
}
|
|
747
768
|
};
|
|
748
769
|
}
|
|
@@ -1699,12 +1720,31 @@ var init_node = __esm({
|
|
|
1699
1720
|
function createCssEngine() {
|
|
1700
1721
|
return {
|
|
1701
1722
|
styles: /* @__PURE__ */ new Map(),
|
|
1723
|
+
modules: /* @__PURE__ */ new Map(),
|
|
1724
|
+
chunks: /* @__PURE__ */ new Map(),
|
|
1702
1725
|
entryCss: /* @__PURE__ */ new Map(),
|
|
1703
1726
|
allCss: [],
|
|
1704
1727
|
pendingSingle: [],
|
|
1705
1728
|
singleFileName: null
|
|
1706
1729
|
};
|
|
1707
1730
|
}
|
|
1731
|
+
function getCssMetadata(engine) {
|
|
1732
|
+
return {
|
|
1733
|
+
modules: Object.fromEntries(
|
|
1734
|
+
[...engine.modules].map(([id, module]) => [id, { ...module }])
|
|
1735
|
+
),
|
|
1736
|
+
chunks: Object.fromEntries(
|
|
1737
|
+
[...engine.chunks].map(([fileName, chunk]) => [
|
|
1738
|
+
fileName,
|
|
1739
|
+
{
|
|
1740
|
+
fileName,
|
|
1741
|
+
moduleIds: [...chunk.moduleIds],
|
|
1742
|
+
cssFileNames: [...chunk.cssFileNames]
|
|
1743
|
+
}
|
|
1744
|
+
])
|
|
1745
|
+
)
|
|
1746
|
+
};
|
|
1747
|
+
}
|
|
1708
1748
|
function normalizeCssModuleId(id) {
|
|
1709
1749
|
return id.startsWith("\0") ? id.slice(1) : id;
|
|
1710
1750
|
}
|
|
@@ -1806,6 +1846,7 @@ var init_tailwind = __esm({
|
|
|
1806
1846
|
|
|
1807
1847
|
// src/plugins/css.ts
|
|
1808
1848
|
import path4 from "path";
|
|
1849
|
+
import { SourceMapGenerator } from "source-map-js";
|
|
1809
1850
|
function cssPlugin(config, engine, consumer = "client") {
|
|
1810
1851
|
return {
|
|
1811
1852
|
name: "nasti:css",
|
|
@@ -1825,15 +1866,29 @@ function cssPlugin(config, engine, consumer = "client") {
|
|
|
1825
1866
|
}
|
|
1826
1867
|
const rewritten = rewriteCssUrls(cssSource, file, config.root);
|
|
1827
1868
|
const escaped = JSON.stringify(rewritten);
|
|
1869
|
+
const normalizedId = normalizeCssModuleId(id);
|
|
1870
|
+
const cssModule = { id: normalizedId, source: code, code: rewritten };
|
|
1871
|
+
const map = config.build.sourcemap ? createIdentitySourceMap(code, id) : void 0;
|
|
1872
|
+
engine?.modules.set(normalizedId, cssModule);
|
|
1873
|
+
this.environment?.setCssModule?.(cssModule);
|
|
1828
1874
|
if (query === "inline") {
|
|
1829
1875
|
return { code: `export default ${escaped};
|
|
1830
|
-
`, moduleType: "js" };
|
|
1876
|
+
`, map, moduleType: "js" };
|
|
1831
1877
|
}
|
|
1832
1878
|
if (consumer === "server") {
|
|
1833
1879
|
return { code: `export default ${escaped};
|
|
1834
|
-
`, moduleType: "js" };
|
|
1880
|
+
`, map, moduleType: "js" };
|
|
1835
1881
|
}
|
|
1836
1882
|
if (config.command === "serve") {
|
|
1883
|
+
if (config.build.css.inject === false) {
|
|
1884
|
+
return {
|
|
1885
|
+
code: `export default ${escaped};
|
|
1886
|
+
`,
|
|
1887
|
+
map,
|
|
1888
|
+
moduleType: "js",
|
|
1889
|
+
moduleSideEffects: "no-treeshake"
|
|
1890
|
+
};
|
|
1891
|
+
}
|
|
1837
1892
|
return {
|
|
1838
1893
|
code: `
|
|
1839
1894
|
const css = ${escaped};
|
|
@@ -1857,16 +1912,18 @@ if (import.meta.hot) {
|
|
|
1857
1912
|
|
|
1858
1913
|
export default css;
|
|
1859
1914
|
`,
|
|
1915
|
+
map,
|
|
1860
1916
|
// bundled dev(DevEngine)下该模块会进 Rolldown:不标 js 会按 .css
|
|
1861
1917
|
// 扩展名走 CSS 管线触发 #4271 报错;unbundled 中间件忽略此字段
|
|
1862
1918
|
moduleType: "js"
|
|
1863
1919
|
};
|
|
1864
1920
|
}
|
|
1865
1921
|
if (engine) {
|
|
1866
|
-
engine.styles.set(
|
|
1922
|
+
engine.styles.set(normalizedId, rewritten);
|
|
1867
1923
|
return {
|
|
1868
1924
|
code: `export default '';
|
|
1869
1925
|
`,
|
|
1926
|
+
map,
|
|
1870
1927
|
moduleType: "js",
|
|
1871
1928
|
// 防止空 stub 被 tree-shake 出 chunk.moduleIds(css-post 靠它定位)
|
|
1872
1929
|
moduleSideEffects: "no-treeshake"
|
|
@@ -1886,11 +1943,27 @@ document.head.appendChild(style);
|
|
|
1886
1943
|
|
|
1887
1944
|
export default css;
|
|
1888
1945
|
`,
|
|
1946
|
+
map,
|
|
1889
1947
|
moduleType: "js"
|
|
1890
1948
|
};
|
|
1891
1949
|
}
|
|
1892
1950
|
};
|
|
1893
1951
|
}
|
|
1952
|
+
function createIdentitySourceMap(code, id) {
|
|
1953
|
+
const map = new SourceMapGenerator({ file: id });
|
|
1954
|
+
const lines = code.split("\n");
|
|
1955
|
+
for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
|
|
1956
|
+
for (let column = 0; column <= lines[lineIndex].length; column++) {
|
|
1957
|
+
map.addMapping({
|
|
1958
|
+
generated: { line: lineIndex + 1, column },
|
|
1959
|
+
original: { line: lineIndex + 1, column },
|
|
1960
|
+
source: id
|
|
1961
|
+
});
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1964
|
+
map.setSourceContent(id, code);
|
|
1965
|
+
return map.toJSON();
|
|
1966
|
+
}
|
|
1894
1967
|
function rewriteCssUrls(css, from, root) {
|
|
1895
1968
|
return css.replace(/url\(\s*['"]?([^'")\s]+)['"]?\s*\)/g, (match, url) => {
|
|
1896
1969
|
if (url.startsWith("/") || url.startsWith("data:") || url.startsWith("http")) {
|
|
@@ -1913,19 +1986,27 @@ var init_css = __esm({
|
|
|
1913
1986
|
function collectChunkCss(chunk, engine) {
|
|
1914
1987
|
const ids = chunk.moduleIds ?? Object.keys(chunk.modules);
|
|
1915
1988
|
let css = "";
|
|
1989
|
+
const moduleIds = [];
|
|
1916
1990
|
for (const id of ids) {
|
|
1917
|
-
const
|
|
1918
|
-
|
|
1991
|
+
const normalizedId = normalizeCssModuleId(id);
|
|
1992
|
+
const styles = engine.styles.get(normalizedId);
|
|
1993
|
+
if (styles) {
|
|
1994
|
+
css += styles + "\n";
|
|
1995
|
+
moduleIds.push(normalizedId);
|
|
1996
|
+
}
|
|
1919
1997
|
}
|
|
1920
|
-
return css;
|
|
1998
|
+
return { css, moduleIds };
|
|
1921
1999
|
}
|
|
1922
2000
|
function cssPostPlugin(config, engine) {
|
|
1923
2001
|
return {
|
|
1924
2002
|
name: "nasti:css-post",
|
|
1925
2003
|
enforce: "post",
|
|
1926
2004
|
async renderChunk(code, chunk) {
|
|
1927
|
-
const css = collectChunkCss(chunk, engine);
|
|
2005
|
+
const { css, moduleIds } = collectChunkCss(chunk, engine);
|
|
1928
2006
|
if (!css) return null;
|
|
2007
|
+
const ownership = { moduleIds, cssFileNames: [] };
|
|
2008
|
+
engine.chunks.set(chunk.fileName, ownership);
|
|
2009
|
+
if (config.build.css.emit === false) return null;
|
|
1929
2010
|
if (!config.build.cssCodeSplit) {
|
|
1930
2011
|
engine.pendingSingle.push(css);
|
|
1931
2012
|
return null;
|
|
@@ -1938,6 +2019,7 @@ function cssPostPlugin(config, engine) {
|
|
|
1938
2019
|
});
|
|
1939
2020
|
const fileName = this.getFileName(ref);
|
|
1940
2021
|
engine.allCss.push(fileName);
|
|
2022
|
+
ownership.cssFileNames.push(fileName);
|
|
1941
2023
|
if (chunk.isEntry) {
|
|
1942
2024
|
const key = chunk.facadeModuleId ?? chunk.name;
|
|
1943
2025
|
const existing = engine.entryCss.get(key) ?? [];
|
|
@@ -1945,13 +2027,14 @@ function cssPostPlugin(config, engine) {
|
|
|
1945
2027
|
engine.entryCss.set(key, existing);
|
|
1946
2028
|
return null;
|
|
1947
2029
|
}
|
|
2030
|
+
if (config.build.css.inject === false) return null;
|
|
1948
2031
|
const href = JSON.stringify(config.base + fileName);
|
|
1949
2032
|
const snippet = `
|
|
1950
2033
|
;(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){}})();`;
|
|
1951
2034
|
return { code: code + snippet, map: null };
|
|
1952
2035
|
},
|
|
1953
2036
|
augmentChunkHash(chunk) {
|
|
1954
|
-
const css = collectChunkCss(chunk, engine);
|
|
2037
|
+
const { css } = collectChunkCss(chunk, engine);
|
|
1955
2038
|
return css || void 0;
|
|
1956
2039
|
},
|
|
1957
2040
|
async generateBundle() {
|
|
@@ -1962,6 +2045,9 @@ function cssPostPlugin(config, engine) {
|
|
|
1962
2045
|
const fileName = this.getFileName(ref);
|
|
1963
2046
|
engine.singleFileName = fileName;
|
|
1964
2047
|
engine.allCss.push(fileName);
|
|
2048
|
+
for (const ownership of engine.chunks.values()) {
|
|
2049
|
+
if (ownership.moduleIds.length > 0) ownership.cssFileNames.push(fileName);
|
|
2050
|
+
}
|
|
1965
2051
|
}
|
|
1966
2052
|
};
|
|
1967
2053
|
}
|
|
@@ -1977,6 +2063,7 @@ import path5 from "path";
|
|
|
1977
2063
|
import fs3 from "fs";
|
|
1978
2064
|
import crypto from "crypto";
|
|
1979
2065
|
function assetsPlugin(config) {
|
|
2066
|
+
const emittedAssets = /* @__PURE__ */ new Set();
|
|
1980
2067
|
return {
|
|
1981
2068
|
name: "nasti:assets",
|
|
1982
2069
|
resolveId(source) {
|
|
@@ -2005,12 +2092,29 @@ function assetsPlugin(config) {
|
|
|
2005
2092
|
const hash = crypto.createHash("sha256").update(content).digest("hex").slice(0, 8);
|
|
2006
2093
|
const basename = path5.basename(file, ext);
|
|
2007
2094
|
const hashedName = `${config.build.assetsDir}/${basename}.${hash}${ext}`;
|
|
2095
|
+
const environment = this.environment;
|
|
2096
|
+
if (!environment) {
|
|
2097
|
+
throw new Error("[nasti:assets] build environment is not initialized");
|
|
2098
|
+
}
|
|
2099
|
+
if (!emittedAssets.has(hashedName)) {
|
|
2100
|
+
this.emitFile({
|
|
2101
|
+
type: "asset",
|
|
2102
|
+
fileName: hashedName,
|
|
2103
|
+
source: content
|
|
2104
|
+
});
|
|
2105
|
+
emittedAssets.add(hashedName);
|
|
2106
|
+
}
|
|
2107
|
+
environment.setAssetModule(file, hashedName);
|
|
2008
2108
|
return `export default ${JSON.stringify(config.base + hashedName)}`;
|
|
2009
2109
|
}
|
|
2010
2110
|
return null;
|
|
2011
2111
|
}
|
|
2012
2112
|
};
|
|
2013
2113
|
}
|
|
2114
|
+
function isAssetFile(id) {
|
|
2115
|
+
const ext = path5.extname(id.replace(/\?.*$/, ""));
|
|
2116
|
+
return ASSET_EXTENSIONS.has(ext);
|
|
2117
|
+
}
|
|
2014
2118
|
var ASSET_EXTENSIONS;
|
|
2015
2119
|
var init_assets = __esm({
|
|
2016
2120
|
"src/plugins/assets.ts"() {
|
|
@@ -2082,6 +2186,11 @@ var init_transformer = __esm({
|
|
|
2082
2186
|
|
|
2083
2187
|
// src/plugins/vue.ts
|
|
2084
2188
|
import crypto2 from "crypto";
|
|
2189
|
+
import {
|
|
2190
|
+
SourceMapConsumer,
|
|
2191
|
+
SourceMapGenerator as SourceMapGenerator2,
|
|
2192
|
+
SourceNode
|
|
2193
|
+
} from "source-map-js";
|
|
2085
2194
|
async function loadVueCompiler() {
|
|
2086
2195
|
if (compiler) return compiler;
|
|
2087
2196
|
try {
|
|
@@ -2091,9 +2200,10 @@ async function loadVueCompiler() {
|
|
|
2091
2200
|
return null;
|
|
2092
2201
|
}
|
|
2093
2202
|
}
|
|
2094
|
-
function vuePlugin(config) {
|
|
2203
|
+
function vuePlugin(config, environmentName = "client") {
|
|
2095
2204
|
const isDev = config.command === "serve";
|
|
2096
2205
|
const descriptorCache = /* @__PURE__ */ new Map();
|
|
2206
|
+
const vueOptions = config.environments[environmentName]?.vue ?? {};
|
|
2097
2207
|
return {
|
|
2098
2208
|
name: "nasti:vue",
|
|
2099
2209
|
enforce: "pre",
|
|
@@ -2113,32 +2223,63 @@ function vuePlugin(config) {
|
|
|
2113
2223
|
const sfc = await loadVueCompiler();
|
|
2114
2224
|
if (!sfc) return null;
|
|
2115
2225
|
const [, filePath, indexStr] = match;
|
|
2116
|
-
let
|
|
2117
|
-
if (!
|
|
2226
|
+
let cached2 = descriptorCache.get(filePath);
|
|
2227
|
+
if (!cached2) {
|
|
2118
2228
|
try {
|
|
2119
2229
|
const fs14 = await import("fs");
|
|
2120
|
-
const
|
|
2121
|
-
const
|
|
2230
|
+
const rawSource = fs14.readFileSync(filePath, "utf-8");
|
|
2231
|
+
const transformedSfc = await applySourceTransform(
|
|
2232
|
+
vueOptions.transformSfc,
|
|
2233
|
+
rawSource,
|
|
2234
|
+
{ filename: filePath, environmentName, type: "sfc" }
|
|
2235
|
+
);
|
|
2236
|
+
const parsed = sfc.parse(transformedSfc.code, {
|
|
2237
|
+
...vueOptions.parse,
|
|
2238
|
+
filename: filePath,
|
|
2239
|
+
sourceMap: true
|
|
2240
|
+
});
|
|
2122
2241
|
if (parsed.errors.length) return null;
|
|
2123
|
-
|
|
2124
|
-
|
|
2242
|
+
cached2 = {
|
|
2243
|
+
descriptor: parsed.descriptor,
|
|
2244
|
+
sourceMap: transformedSfc.map
|
|
2245
|
+
};
|
|
2246
|
+
descriptorCache.set(filePath, cached2);
|
|
2125
2247
|
} catch {
|
|
2126
2248
|
return null;
|
|
2127
2249
|
}
|
|
2128
2250
|
}
|
|
2251
|
+
const { descriptor, sourceMap: sfcSourceMap } = cached2;
|
|
2129
2252
|
const index2 = parseInt(indexStr ?? "0", 10);
|
|
2130
2253
|
const style = descriptor.styles[index2];
|
|
2131
2254
|
if (!style) return null;
|
|
2132
2255
|
const scopeId = hashId(filePath);
|
|
2256
|
+
const transformedStyle = await applySourceTransform(
|
|
2257
|
+
vueOptions.transformStyle,
|
|
2258
|
+
style.content,
|
|
2259
|
+
{ filename: filePath, environmentName, type: "style", index: index2 }
|
|
2260
|
+
);
|
|
2261
|
+
const wantsStyleSourceMap = !!config.build.sourcemap || transformedStyle.map != null || sfcSourceMap != null;
|
|
2262
|
+
const styleInputMap = wantsStyleSourceMap ? composeSourceMapChain(
|
|
2263
|
+
[transformedStyle.map, style.map, sfcSourceMap],
|
|
2264
|
+
{ filename: filePath, environmentName, type: "style", index: index2 }
|
|
2265
|
+
) : void 0;
|
|
2133
2266
|
const result = await sfc.compileStyleAsync({
|
|
2134
|
-
|
|
2267
|
+
...vueOptions.style,
|
|
2268
|
+
source: transformedStyle.code,
|
|
2135
2269
|
filename: filePath,
|
|
2136
2270
|
id: `data-v-${scopeId}`,
|
|
2137
2271
|
scoped: style.scoped ?? false,
|
|
2272
|
+
inMap: styleInputMap,
|
|
2138
2273
|
// <style lang="scss|less|stylus"> 需经对应预处理器(缺省 undefined = 纯 CSS)
|
|
2139
2274
|
preprocessLang: style.lang
|
|
2140
2275
|
});
|
|
2141
|
-
|
|
2276
|
+
if (transformedStyle.map != null && result.map == null) {
|
|
2277
|
+
warnUnchainableMap(
|
|
2278
|
+
{ filename: filePath, environmentName, type: "style", index: index2 },
|
|
2279
|
+
"compiler-sfc did not return a style map"
|
|
2280
|
+
);
|
|
2281
|
+
}
|
|
2282
|
+
return wantsStyleSourceMap ? { code: result.code, map: result.map } : result.code;
|
|
2142
2283
|
},
|
|
2143
2284
|
async transform(code, id) {
|
|
2144
2285
|
if (!VUE_FILE_RE.test(id) && !VUE_QUERY_RE.test(id)) return null;
|
|
@@ -2150,57 +2291,144 @@ function vuePlugin(config) {
|
|
|
2150
2291
|
if (VUE_QUERY_RE.test(id)) {
|
|
2151
2292
|
return null;
|
|
2152
2293
|
}
|
|
2153
|
-
const
|
|
2294
|
+
const transformedSfc = await applySourceTransform(
|
|
2295
|
+
vueOptions.transformSfc,
|
|
2296
|
+
code,
|
|
2297
|
+
{ filename: id, environmentName, type: "sfc" }
|
|
2298
|
+
);
|
|
2299
|
+
code = transformedSfc.code;
|
|
2300
|
+
const { descriptor, errors } = sfc.parse(code, {
|
|
2301
|
+
...vueOptions.parse,
|
|
2302
|
+
filename: id,
|
|
2303
|
+
sourceMap: true
|
|
2304
|
+
});
|
|
2154
2305
|
if (errors.length) {
|
|
2155
|
-
|
|
2306
|
+
const firstError = errors[0];
|
|
2307
|
+
console.error(
|
|
2308
|
+
`[nasti:vue] Parse error in ${id}:`,
|
|
2309
|
+
typeof firstError === "string" ? firstError : firstError.message
|
|
2310
|
+
);
|
|
2156
2311
|
return null;
|
|
2157
2312
|
}
|
|
2158
|
-
descriptorCache.set(id,
|
|
2313
|
+
descriptorCache.set(id, {
|
|
2314
|
+
descriptor,
|
|
2315
|
+
sourceMap: transformedSfc.map
|
|
2316
|
+
});
|
|
2159
2317
|
const scopeId = hashId(id);
|
|
2318
|
+
const wantsSourceMap = !!config.build.sourcemap || transformedSfc.map != null;
|
|
2160
2319
|
let scriptCode = "";
|
|
2320
|
+
let scriptMap;
|
|
2161
2321
|
if (descriptor.script || descriptor.scriptSetup) {
|
|
2322
|
+
const inlineTemplate = vueOptions.script?.inlineTemplate !== false;
|
|
2162
2323
|
const compiled = sfc.compileScript(descriptor, {
|
|
2324
|
+
...vueOptions.script,
|
|
2163
2325
|
id: scopeId,
|
|
2164
2326
|
isProd: !isDev,
|
|
2165
|
-
inlineTemplate
|
|
2327
|
+
inlineTemplate,
|
|
2328
|
+
sourceMap: wantsSourceMap,
|
|
2166
2329
|
// 让 compileScript 产出 `const __sfc__ = ...`(而非默认的 `export default {...}`)。
|
|
2167
2330
|
// 否则下方追加的 `__sfc__.render` / `__sfc__.__scopeId` / HMR 记录会引用一个
|
|
2168
2331
|
// 不存在的 `__sfc__`,并与 compileScript 自带的 `export default` 形成双重默认导出。
|
|
2169
2332
|
genDefaultAs: "__sfc__"
|
|
2170
2333
|
});
|
|
2171
2334
|
scriptCode = compiled.content;
|
|
2335
|
+
scriptMap = composeSourceMapChain(
|
|
2336
|
+
[compiled.map, transformedSfc.map],
|
|
2337
|
+
{ filename: id, environmentName, type: "sfc" }
|
|
2338
|
+
);
|
|
2339
|
+
if (transformedSfc.map != null && scriptMap == null) {
|
|
2340
|
+
warnUnchainableMap(
|
|
2341
|
+
{ filename: id, environmentName, type: "sfc" },
|
|
2342
|
+
"compiler-sfc did not return a script map"
|
|
2343
|
+
);
|
|
2344
|
+
}
|
|
2172
2345
|
}
|
|
2173
2346
|
let templateCode = "";
|
|
2174
|
-
|
|
2347
|
+
let templateMap;
|
|
2348
|
+
const scriptSetupIsInline = !!descriptor.scriptSetup && vueOptions.script?.inlineTemplate !== false;
|
|
2349
|
+
if (descriptor.template && !scriptSetupIsInline) {
|
|
2350
|
+
const transformedTemplate = await applySourceTransform(
|
|
2351
|
+
vueOptions.transformTemplate,
|
|
2352
|
+
descriptor.template.content,
|
|
2353
|
+
{ filename: id, environmentName, type: "template" }
|
|
2354
|
+
);
|
|
2355
|
+
const templateInputMap = composeSourceMapChain(
|
|
2356
|
+
[
|
|
2357
|
+
transformedTemplate.map,
|
|
2358
|
+
descriptor.template.map,
|
|
2359
|
+
transformedSfc.map
|
|
2360
|
+
],
|
|
2361
|
+
{ filename: id, environmentName, type: "template" }
|
|
2362
|
+
);
|
|
2363
|
+
const customCompilerOptions = vueOptions.template?.compilerOptions ?? {};
|
|
2175
2364
|
const compiled = sfc.compileTemplate({
|
|
2176
|
-
|
|
2365
|
+
...vueOptions.template,
|
|
2366
|
+
source: transformedTemplate.code,
|
|
2177
2367
|
filename: id,
|
|
2178
2368
|
id: scopeId,
|
|
2179
|
-
|
|
2369
|
+
inMap: templateInputMap,
|
|
2370
|
+
compilerOptions: {
|
|
2371
|
+
...customCompilerOptions,
|
|
2372
|
+
scopeId: `data-v-${scopeId}`
|
|
2373
|
+
}
|
|
2180
2374
|
});
|
|
2181
2375
|
templateCode = compiled.code;
|
|
2376
|
+
if (wantsSourceMap || transformedTemplate.map != null) {
|
|
2377
|
+
templateMap = compiled.map;
|
|
2378
|
+
}
|
|
2379
|
+
if (transformedTemplate.map != null && templateMap == null) {
|
|
2380
|
+
warnUnchainableMap(
|
|
2381
|
+
{ filename: id, environmentName, type: "template" },
|
|
2382
|
+
"compiler-sfc did not return a template map"
|
|
2383
|
+
);
|
|
2384
|
+
}
|
|
2182
2385
|
}
|
|
2183
|
-
|
|
2386
|
+
const outputNode = new SourceNode();
|
|
2387
|
+
let hasMappedOutput = false;
|
|
2388
|
+
const append = (fragment, map) => {
|
|
2389
|
+
const normalizedMap = normalizeSourceMap(
|
|
2390
|
+
map,
|
|
2391
|
+
{ filename: id, environmentName, type: "sfc" }
|
|
2392
|
+
);
|
|
2393
|
+
if (!normalizedMap) {
|
|
2394
|
+
outputNode.add(fragment);
|
|
2395
|
+
return;
|
|
2396
|
+
}
|
|
2397
|
+
try {
|
|
2398
|
+
outputNode.add(
|
|
2399
|
+
SourceNode.fromStringWithSourceMap(
|
|
2400
|
+
fragment,
|
|
2401
|
+
new SourceMapConsumer(normalizedMap)
|
|
2402
|
+
)
|
|
2403
|
+
);
|
|
2404
|
+
hasMappedOutput = true;
|
|
2405
|
+
} catch (error) {
|
|
2406
|
+
warnUnchainableMap(
|
|
2407
|
+
{ filename: id, environmentName, type: "sfc" },
|
|
2408
|
+
`source-map assembly failed: ${error instanceof Error ? error.message : String(error)}`
|
|
2409
|
+
);
|
|
2410
|
+
outputNode.add(fragment);
|
|
2411
|
+
}
|
|
2412
|
+
};
|
|
2413
|
+
append(scriptCode || "const __sfc__ = {}", scriptMap);
|
|
2184
2414
|
if (templateCode) {
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
__sfc__.render = render
|
|
2190
|
-
`;
|
|
2415
|
+
append("\n");
|
|
2416
|
+
append(templateCode, templateMap);
|
|
2417
|
+
append("\n");
|
|
2418
|
+
append("\n__sfc__.render = render\n");
|
|
2191
2419
|
}
|
|
2192
2420
|
if (descriptor.styles.length > 0) {
|
|
2193
2421
|
for (let i = 0; i < descriptor.styles.length; i++) {
|
|
2194
|
-
|
|
2422
|
+
append(`
|
|
2195
2423
|
import "${id}?vue&type=style&index=${i}&lang.css"
|
|
2196
|
-
|
|
2424
|
+
`);
|
|
2197
2425
|
}
|
|
2198
2426
|
}
|
|
2199
|
-
|
|
2427
|
+
append(`
|
|
2200
2428
|
__sfc__.__scopeId = "data-v-${scopeId}"
|
|
2201
|
-
|
|
2429
|
+
`);
|
|
2202
2430
|
if (isDev) {
|
|
2203
|
-
|
|
2431
|
+
append(`
|
|
2204
2432
|
__sfc__.__hmrId = ${JSON.stringify(scopeId)}
|
|
2205
2433
|
if (typeof __VUE_HMR_RUNTIME__ !== 'undefined') {
|
|
2206
2434
|
__VUE_HMR_RUNTIME__.createRecord(__sfc__.__hmrId, __sfc__)
|
|
@@ -2214,17 +2442,34 @@ if (import.meta.hot) {
|
|
|
2214
2442
|
}
|
|
2215
2443
|
})
|
|
2216
2444
|
}
|
|
2217
|
-
|
|
2445
|
+
`);
|
|
2446
|
+
}
|
|
2447
|
+
append("\nexport default __sfc__\n");
|
|
2448
|
+
const renderedOutput = outputNode.toStringWithSourceMap({ file: id });
|
|
2449
|
+
const output = renderedOutput.code;
|
|
2450
|
+
const outputMap = hasMappedOutput ? renderedOutput.map.toJSON() : void 0;
|
|
2451
|
+
if (transformedSfc.map != null && outputMap == null) {
|
|
2452
|
+
warnUnchainableMap(
|
|
2453
|
+
{ filename: id, environmentName, type: "sfc" },
|
|
2454
|
+
"the compiled SFC output contained no chainable mappings"
|
|
2455
|
+
);
|
|
2218
2456
|
}
|
|
2219
|
-
output += `
|
|
2220
|
-
export default __sfc__
|
|
2221
|
-
`;
|
|
2222
2457
|
const lang = descriptor.scriptSetup?.lang ?? descriptor.script?.lang;
|
|
2223
2458
|
if (lang === "ts") {
|
|
2224
|
-
const transpiled = transformCode(`${id}.ts`, output, {
|
|
2225
|
-
|
|
2459
|
+
const transpiled = transformCode(`${id}.ts`, output, {
|
|
2460
|
+
sourcemap: wantsSourceMap,
|
|
2461
|
+
target: config.build.target
|
|
2462
|
+
});
|
|
2463
|
+
const transpiledMap = transpiled.map ? JSON.parse(transpiled.map) : void 0;
|
|
2464
|
+
return {
|
|
2465
|
+
code: transpiled.code,
|
|
2466
|
+
map: composeSourceMapChain(
|
|
2467
|
+
[transpiledMap, outputMap],
|
|
2468
|
+
{ filename: id, environmentName, type: "sfc" }
|
|
2469
|
+
)
|
|
2470
|
+
};
|
|
2226
2471
|
}
|
|
2227
|
-
return { code: output };
|
|
2472
|
+
return { code: output, map: outputMap };
|
|
2228
2473
|
},
|
|
2229
2474
|
handleHotUpdate(ctx) {
|
|
2230
2475
|
const { file, modules } = ctx;
|
|
@@ -2238,16 +2483,75 @@ export default __sfc__
|
|
|
2238
2483
|
}
|
|
2239
2484
|
};
|
|
2240
2485
|
}
|
|
2486
|
+
async function applySourceTransform(transform2, source, context) {
|
|
2487
|
+
if (!transform2) return { code: source };
|
|
2488
|
+
const result = await transform2(source, context);
|
|
2489
|
+
return typeof result === "string" ? { code: result } : result;
|
|
2490
|
+
}
|
|
2491
|
+
function normalizeSourceMap(map, context) {
|
|
2492
|
+
if (map == null) return void 0;
|
|
2493
|
+
try {
|
|
2494
|
+
const value = typeof map === "string" ? JSON.parse(map) : map;
|
|
2495
|
+
if (value && typeof value === "object" && Array.isArray(value.sources) && Array.isArray(value.names) && typeof value.mappings === "string") {
|
|
2496
|
+
return value;
|
|
2497
|
+
}
|
|
2498
|
+
} catch {
|
|
2499
|
+
}
|
|
2500
|
+
warnUnchainableMap(context, "the provided map is not a valid source map");
|
|
2501
|
+
return void 0;
|
|
2502
|
+
}
|
|
2503
|
+
function composeSourceMapChain(maps, context) {
|
|
2504
|
+
const pending = maps.filter((map) => map != null);
|
|
2505
|
+
if (pending.length === 0) return void 0;
|
|
2506
|
+
let composed = normalizeSourceMap(pending.shift(), context);
|
|
2507
|
+
for (const map of pending) {
|
|
2508
|
+
const input = normalizeSourceMap(map, context);
|
|
2509
|
+
if (!input) continue;
|
|
2510
|
+
if (!composed) {
|
|
2511
|
+
composed = input;
|
|
2512
|
+
continue;
|
|
2513
|
+
}
|
|
2514
|
+
try {
|
|
2515
|
+
const consumer = new SourceMapConsumer(composed);
|
|
2516
|
+
if (consumer.sources.length !== 1) {
|
|
2517
|
+
warnUnchainableMap(
|
|
2518
|
+
context,
|
|
2519
|
+
"a generated map has multiple sources and cannot be chained safely"
|
|
2520
|
+
);
|
|
2521
|
+
continue;
|
|
2522
|
+
}
|
|
2523
|
+
const generator = SourceMapGenerator2.fromSourceMap(consumer);
|
|
2524
|
+
generator.applySourceMap(
|
|
2525
|
+
new SourceMapConsumer(input),
|
|
2526
|
+
consumer.sources[0]
|
|
2527
|
+
);
|
|
2528
|
+
composed = generator.toJSON();
|
|
2529
|
+
} catch (error) {
|
|
2530
|
+
warnUnchainableMap(
|
|
2531
|
+
context,
|
|
2532
|
+
`source-map composition failed: ${error instanceof Error ? error.message : String(error)}`
|
|
2533
|
+
);
|
|
2534
|
+
}
|
|
2535
|
+
}
|
|
2536
|
+
return composed;
|
|
2537
|
+
}
|
|
2538
|
+
function warnUnchainableMap(context, reason) {
|
|
2539
|
+
debug2?.(
|
|
2540
|
+
`source map warning for ${context.filename} (${context.type}, ${context.environmentName}): ${reason}`
|
|
2541
|
+
);
|
|
2542
|
+
}
|
|
2241
2543
|
function hashId(filename) {
|
|
2242
2544
|
return crypto2.createHash("sha256").update(filename).digest("hex").slice(0, 8);
|
|
2243
2545
|
}
|
|
2244
|
-
var VUE_FILE_RE, VUE_QUERY_RE, compiler;
|
|
2546
|
+
var VUE_FILE_RE, VUE_QUERY_RE, debug2, compiler;
|
|
2245
2547
|
var init_vue = __esm({
|
|
2246
2548
|
"src/plugins/vue.ts"() {
|
|
2247
2549
|
"use strict";
|
|
2248
2550
|
init_transformer();
|
|
2551
|
+
init_debug();
|
|
2249
2552
|
VUE_FILE_RE = /\.vue$/;
|
|
2250
2553
|
VUE_QUERY_RE = /\.vue\?vue&type=(script|template|style)(&index=\d+)?(&lang[.=]\w+)?/;
|
|
2554
|
+
debug2 = createDebugger("nasti:vue");
|
|
2251
2555
|
compiler = null;
|
|
2252
2556
|
}
|
|
2253
2557
|
});
|
|
@@ -2351,7 +2655,7 @@ function resolvePluginList(config, userPlugins, opts = {}) {
|
|
|
2351
2655
|
const consumer = opts.consumer ?? environmentOptions?.consumer;
|
|
2352
2656
|
return [
|
|
2353
2657
|
// vuePlugin 排最前(enforce: 'pre' 语义):.vue 先编译成 JS 再走后续管道
|
|
2354
|
-
...config.framework === "vue" ? [vuePlugin(pluginConfig)] : [],
|
|
2658
|
+
...config.framework === "vue" ? [vuePlugin(pluginConfig, opts.environmentName ?? "client")] : [],
|
|
2355
2659
|
resolvePlugin(pluginConfig),
|
|
2356
2660
|
cssPlugin(pluginConfig, opts.cssEngine, consumer),
|
|
2357
2661
|
assetsPlugin(pluginConfig),
|
|
@@ -2455,17 +2759,23 @@ var init_plugin_container = __esm({
|
|
|
2455
2759
|
}
|
|
2456
2760
|
async transform(code, id) {
|
|
2457
2761
|
let currentCode = code;
|
|
2762
|
+
let lastResult;
|
|
2458
2763
|
for (const plugin of this.plugins) {
|
|
2459
2764
|
if (!plugin.transform) continue;
|
|
2460
2765
|
const result = await plugin.transform.call(this.ctx, currentCode, id);
|
|
2461
2766
|
if (result == null) continue;
|
|
2462
2767
|
if (typeof result === "string") {
|
|
2463
2768
|
currentCode = result;
|
|
2769
|
+
lastResult = void 0;
|
|
2464
2770
|
} else {
|
|
2465
2771
|
currentCode = result.code;
|
|
2772
|
+
lastResult = result;
|
|
2466
2773
|
}
|
|
2467
2774
|
}
|
|
2468
|
-
return currentCode === code ? null : {
|
|
2775
|
+
return currentCode === code ? null : {
|
|
2776
|
+
...lastResult,
|
|
2777
|
+
code: currentCode
|
|
2778
|
+
};
|
|
2469
2779
|
}
|
|
2470
2780
|
/** 完整的模块处理管道: resolveId → load → transform */
|
|
2471
2781
|
async processModule(source, importer) {
|
|
@@ -2512,9 +2822,13 @@ var init_module_graph = __esm({
|
|
|
2512
2822
|
"use strict";
|
|
2513
2823
|
init_url();
|
|
2514
2824
|
ModuleGraph = class {
|
|
2825
|
+
environmentName;
|
|
2515
2826
|
urlToModuleMap = /* @__PURE__ */ new Map();
|
|
2516
2827
|
idToModuleMap = /* @__PURE__ */ new Map();
|
|
2517
2828
|
fileToModulesMap = /* @__PURE__ */ new Map();
|
|
2829
|
+
constructor(environmentName = "client") {
|
|
2830
|
+
this.environmentName = environmentName;
|
|
2831
|
+
}
|
|
2518
2832
|
getModuleByUrl(url) {
|
|
2519
2833
|
return this.urlToModuleMap.get(removeTimestampQuery(url));
|
|
2520
2834
|
}
|
|
@@ -2544,7 +2858,8 @@ var init_module_graph = __esm({
|
|
|
2544
2858
|
transformResult: null,
|
|
2545
2859
|
lastHMRTimestamp: 0,
|
|
2546
2860
|
invalidationVersion: 0,
|
|
2547
|
-
isSelfAccepting: false
|
|
2861
|
+
isSelfAccepting: false,
|
|
2862
|
+
environment: this.environmentName
|
|
2548
2863
|
};
|
|
2549
2864
|
this.idToModuleMap.set(mod.id, mod);
|
|
2550
2865
|
return mod;
|
|
@@ -2702,12 +3017,12 @@ function createNoopHotChannel() {
|
|
|
2702
3017
|
}
|
|
2703
3018
|
};
|
|
2704
3019
|
}
|
|
2705
|
-
function createWsHotChannel(ws) {
|
|
3020
|
+
function createWsHotChannel(ws, environmentName = "client") {
|
|
2706
3021
|
const listeners = /* @__PURE__ */ new Map();
|
|
2707
3022
|
let invokeHandlers;
|
|
2708
3023
|
return {
|
|
2709
3024
|
send(payload) {
|
|
2710
|
-
ws.send(payload);
|
|
3025
|
+
ws.send({ ...payload, environment: payload.environment ?? environmentName });
|
|
2711
3026
|
},
|
|
2712
3027
|
on(event, listener) {
|
|
2713
3028
|
let set = listeners.get(event);
|
|
@@ -2719,8 +3034,8 @@ function createWsHotChannel(ws) {
|
|
|
2719
3034
|
},
|
|
2720
3035
|
listen() {
|
|
2721
3036
|
},
|
|
3037
|
+
// 多个 environment 共享底层 WebSocket server;它由 DevServer.close() 统一关闭。
|
|
2722
3038
|
close() {
|
|
2723
|
-
ws.close();
|
|
2724
3039
|
},
|
|
2725
3040
|
setInvokeHandler(handlers) {
|
|
2726
3041
|
invokeHandlers = handlers;
|
|
@@ -2749,7 +3064,7 @@ function resolveEnvironmentPlugins(environment, plugins) {
|
|
|
2749
3064
|
}
|
|
2750
3065
|
});
|
|
2751
3066
|
}
|
|
2752
|
-
var
|
|
3067
|
+
var debug3, NastiEnvironment;
|
|
2753
3068
|
var init_environment = __esm({
|
|
2754
3069
|
"src/core/environment.ts"() {
|
|
2755
3070
|
"use strict";
|
|
@@ -2758,7 +3073,7 @@ var init_environment = __esm({
|
|
|
2758
3073
|
init_hot_channel();
|
|
2759
3074
|
init_debug();
|
|
2760
3075
|
init_plugin_api();
|
|
2761
|
-
|
|
3076
|
+
debug3 = createDebugger("nasti:environment");
|
|
2762
3077
|
NastiEnvironment = class {
|
|
2763
3078
|
name;
|
|
2764
3079
|
consumer;
|
|
@@ -2776,6 +3091,9 @@ var init_environment = __esm({
|
|
|
2776
3091
|
candidatePlugins;
|
|
2777
3092
|
pluginApi;
|
|
2778
3093
|
buildMetadata = {};
|
|
3094
|
+
cssModules = /* @__PURE__ */ new Map();
|
|
3095
|
+
assetModules = /* @__PURE__ */ new Map();
|
|
3096
|
+
transformRequestHandler;
|
|
2779
3097
|
initialized = false;
|
|
2780
3098
|
constructor(name, config, init = {}) {
|
|
2781
3099
|
const options = config.environments[name];
|
|
@@ -2790,7 +3108,7 @@ var init_environment = __esm({
|
|
|
2790
3108
|
this.config = config;
|
|
2791
3109
|
this.options = options;
|
|
2792
3110
|
this.hot = init.hot ?? createNoopHotChannel();
|
|
2793
|
-
this.moduleGraph = new ModuleGraph();
|
|
3111
|
+
this.moduleGraph = new ModuleGraph(name);
|
|
2794
3112
|
this.candidatePlugins = init.plugins ?? config.plugins;
|
|
2795
3113
|
this.pluginApi = init.pluginApi ?? getPluginApi(config);
|
|
2796
3114
|
}
|
|
@@ -2820,9 +3138,9 @@ var init_environment = __esm({
|
|
|
2820
3138
|
);
|
|
2821
3139
|
}
|
|
2822
3140
|
this.driver = claimed[0].driver;
|
|
2823
|
-
|
|
3141
|
+
debug3?.(`env "${this.name}" uses driver "${this.driver.name}"`);
|
|
2824
3142
|
}
|
|
2825
|
-
|
|
3143
|
+
debug3?.(`env "${this.name}" initialized (${this.plugins.length} plugins)`);
|
|
2826
3144
|
}
|
|
2827
3145
|
getDriverContext() {
|
|
2828
3146
|
return {
|
|
@@ -2832,6 +3150,37 @@ var init_environment = __esm({
|
|
|
2832
3150
|
logger: this.config.logger
|
|
2833
3151
|
};
|
|
2834
3152
|
}
|
|
3153
|
+
configureDevPipeline(transformRequest2) {
|
|
3154
|
+
this.transformRequestHandler = transformRequest2;
|
|
3155
|
+
}
|
|
3156
|
+
async transformRequest(url) {
|
|
3157
|
+
if (!this.transformRequestHandler) {
|
|
3158
|
+
throw new Error(
|
|
3159
|
+
`[nasti] environment "${this.name}" does not have an initialized dev transform pipeline`
|
|
3160
|
+
);
|
|
3161
|
+
}
|
|
3162
|
+
return this.transformRequestHandler(url);
|
|
3163
|
+
}
|
|
3164
|
+
setCssModule(module) {
|
|
3165
|
+
this.cssModules.set(module.id, { ...module });
|
|
3166
|
+
}
|
|
3167
|
+
getCssModule(id) {
|
|
3168
|
+
const module = this.cssModules.get(id);
|
|
3169
|
+
return module ? { ...module } : void 0;
|
|
3170
|
+
}
|
|
3171
|
+
getCssModules() {
|
|
3172
|
+
return Object.freeze(
|
|
3173
|
+
Object.fromEntries(
|
|
3174
|
+
[...this.cssModules].map(([id, module]) => [id, { ...module }])
|
|
3175
|
+
)
|
|
3176
|
+
);
|
|
3177
|
+
}
|
|
3178
|
+
setAssetModule(id, fileName) {
|
|
3179
|
+
this.assetModules.set(id, fileName);
|
|
3180
|
+
}
|
|
3181
|
+
getAssetModules() {
|
|
3182
|
+
return Object.freeze(Object.fromEntries(this.assetModules));
|
|
3183
|
+
}
|
|
2835
3184
|
setBuildMetadata(metadata) {
|
|
2836
3185
|
const { entries: currentEntries, ...currentMetadata } = this.buildMetadata;
|
|
2837
3186
|
const { entries, ...nextMetadata } = metadata;
|
|
@@ -2944,7 +3293,7 @@ async function tryNativeReporterPlugin(config, logger) {
|
|
|
2944
3293
|
logInfo: (msg) => logger.info(msg)
|
|
2945
3294
|
});
|
|
2946
3295
|
} catch (err) {
|
|
2947
|
-
|
|
3296
|
+
debug4?.(`native viteReporterPlugin unavailable, falling back to JS table: ${err}`);
|
|
2948
3297
|
return null;
|
|
2949
3298
|
}
|
|
2950
3299
|
}
|
|
@@ -2999,12 +3348,12 @@ function warnLargeChunks(output, config, logger) {
|
|
|
2999
3348
|
)
|
|
3000
3349
|
);
|
|
3001
3350
|
}
|
|
3002
|
-
var
|
|
3351
|
+
var debug4, numberFormatter;
|
|
3003
3352
|
var init_reporter = __esm({
|
|
3004
3353
|
"src/build/reporter.ts"() {
|
|
3005
3354
|
"use strict";
|
|
3006
3355
|
init_debug();
|
|
3007
|
-
|
|
3356
|
+
debug4 = createDebugger("nasti:reporter");
|
|
3008
3357
|
numberFormatter = new Intl.NumberFormat("en", {
|
|
3009
3358
|
maximumFractionDigits: 2,
|
|
3010
3359
|
minimumFractionDigits: 2
|
|
@@ -3046,6 +3395,24 @@ function createBuildAppContext(config, results) {
|
|
|
3046
3395
|
getManifest(environmentName) {
|
|
3047
3396
|
return results[environmentName]?.manifest;
|
|
3048
3397
|
},
|
|
3398
|
+
getChunk(environmentName, fileName) {
|
|
3399
|
+
const normalized = normalizeEnvironmentFileName(fileName);
|
|
3400
|
+
return results[environmentName]?.chunks?.[normalized];
|
|
3401
|
+
},
|
|
3402
|
+
getCss(environmentName) {
|
|
3403
|
+
return results[environmentName]?.css;
|
|
3404
|
+
},
|
|
3405
|
+
getSourceMap(environmentName, fileName) {
|
|
3406
|
+
const normalized = normalizeEnvironmentFileName(fileName);
|
|
3407
|
+
return results[environmentName]?.sourceMaps?.[normalized];
|
|
3408
|
+
},
|
|
3409
|
+
resolvePublicPath(environmentName, fileName) {
|
|
3410
|
+
const result = results[environmentName];
|
|
3411
|
+
if (!result) return void 0;
|
|
3412
|
+
const normalized = normalizeEnvironmentFileName(fileName);
|
|
3413
|
+
const base = result.publicPath ?? config.base;
|
|
3414
|
+
return joinPublicPath(base, normalized);
|
|
3415
|
+
},
|
|
3049
3416
|
emitFile(file) {
|
|
3050
3417
|
const fileName = normalizeAppFileName(file.fileName);
|
|
3051
3418
|
const collisionKey = artifactCollisionKey(fileName);
|
|
@@ -3075,6 +3442,9 @@ function createBuildAppContext(config, results) {
|
|
|
3075
3442
|
}
|
|
3076
3443
|
};
|
|
3077
3444
|
}
|
|
3445
|
+
function joinPublicPath(base, fileName) {
|
|
3446
|
+
return `${base.endsWith("/") ? base : `${base}/`}${fileName.replace(/^\//, "")}`;
|
|
3447
|
+
}
|
|
3078
3448
|
function normalizeEnvironmentFileName(fileName) {
|
|
3079
3449
|
return path9.posix.normalize(fileName.replace(/\\/g, "/").replace(/^\.\//, ""));
|
|
3080
3450
|
}
|
|
@@ -3177,7 +3547,11 @@ function getRolldownOptions(environment, entryPoints, rolldownPlugins) {
|
|
|
3177
3547
|
const inputOptions = {
|
|
3178
3548
|
...restInputOptions,
|
|
3179
3549
|
input: entryPoints,
|
|
3180
|
-
transform: {
|
|
3550
|
+
transform: {
|
|
3551
|
+
...userTransform,
|
|
3552
|
+
target: userTransform?.target ?? envOptions.build.target,
|
|
3553
|
+
define: mergedDefine
|
|
3554
|
+
},
|
|
3181
3555
|
plugins: rolldownPlugins,
|
|
3182
3556
|
// client/server consumer 都必须使用当前环境的 conditions/mainFields;Lynx
|
|
3183
3557
|
// BG/MT 通常同为 client consumer,但仍可能声明不同的运行时条件。
|
|
@@ -3200,7 +3574,7 @@ function getRolldownOptions(environment, entryPoints, rolldownPlugins) {
|
|
|
3200
3574
|
};
|
|
3201
3575
|
const outputOptions = isServer ? {
|
|
3202
3576
|
format: "esm",
|
|
3203
|
-
sourcemap:
|
|
3577
|
+
sourcemap: envOptions.build.sourcemap,
|
|
3204
3578
|
minify: !!envOptions.build.minify,
|
|
3205
3579
|
entryFileNames: "[name].js",
|
|
3206
3580
|
chunkFileNames: "chunks/[name]-[hash].js",
|
|
@@ -3209,7 +3583,7 @@ function getRolldownOptions(environment, entryPoints, rolldownPlugins) {
|
|
|
3209
3583
|
dir: outDir
|
|
3210
3584
|
} : {
|
|
3211
3585
|
format: "esm",
|
|
3212
|
-
sourcemap:
|
|
3586
|
+
sourcemap: envOptions.build.sourcemap,
|
|
3213
3587
|
minify: !!envOptions.build.minify,
|
|
3214
3588
|
entryFileNames: `${assetsDir}/[name].[hash].js`,
|
|
3215
3589
|
chunkFileNames: `${assetsDir}/[name].[hash].js`,
|
|
@@ -3284,13 +3658,68 @@ function finalizeEnvironmentResult(environment, result) {
|
|
|
3284
3658
|
return [name, normalized];
|
|
3285
3659
|
})
|
|
3286
3660
|
);
|
|
3661
|
+
const inferredMetadata = inferOutputMetadata(environment, result.output);
|
|
3287
3662
|
return {
|
|
3663
|
+
publicPath: environment.config.base,
|
|
3664
|
+
...inferredMetadata,
|
|
3288
3665
|
...metadata,
|
|
3289
3666
|
...result,
|
|
3290
3667
|
output: result.output,
|
|
3668
|
+
chunks: {
|
|
3669
|
+
...inferredMetadata.chunks,
|
|
3670
|
+
...metadata.chunks,
|
|
3671
|
+
...result.chunks
|
|
3672
|
+
},
|
|
3673
|
+
assets: {
|
|
3674
|
+
...inferredMetadata.assets,
|
|
3675
|
+
...metadata.assets,
|
|
3676
|
+
...result.assets
|
|
3677
|
+
},
|
|
3678
|
+
sourceMaps: {
|
|
3679
|
+
...inferredMetadata.sourceMaps,
|
|
3680
|
+
...metadata.sourceMaps,
|
|
3681
|
+
...result.sourceMaps
|
|
3682
|
+
},
|
|
3291
3683
|
...Object.keys(normalizedEntries).length > 0 ? { entries: normalizedEntries } : {}
|
|
3292
3684
|
};
|
|
3293
3685
|
}
|
|
3686
|
+
function inferOutputMetadata(environment, output) {
|
|
3687
|
+
const chunks = {};
|
|
3688
|
+
const assets = {};
|
|
3689
|
+
const sourceMaps = {};
|
|
3690
|
+
const cssChunks = environment.getBuildMetadata().css?.chunks ?? {};
|
|
3691
|
+
const assetModules = environment.getAssetModules();
|
|
3692
|
+
const publicPath = environment.config.base;
|
|
3693
|
+
for (const artifact of output) {
|
|
3694
|
+
const fileName = normalizeEnvironmentFileName(artifact.fileName);
|
|
3695
|
+
if (artifact.map != null) sourceMaps[fileName] = artifact.map;
|
|
3696
|
+
if (artifact.type === "chunk") {
|
|
3697
|
+
const moduleIds = [...artifact.moduleIds ?? []];
|
|
3698
|
+
chunks[fileName] = {
|
|
3699
|
+
fileName,
|
|
3700
|
+
name: artifact.name ?? fileName,
|
|
3701
|
+
isEntry: !!artifact.isEntry,
|
|
3702
|
+
isDynamicEntry: !!artifact.isDynamicEntry,
|
|
3703
|
+
imports: [...artifact.imports ?? []],
|
|
3704
|
+
dynamicImports: [...artifact.dynamicImports ?? []],
|
|
3705
|
+
moduleIds,
|
|
3706
|
+
css: [...cssChunks[fileName]?.cssFileNames ?? []],
|
|
3707
|
+
assets: [
|
|
3708
|
+
...new Set(
|
|
3709
|
+
moduleIds.map((id) => assetModules[id]).filter((asset) => !!asset)
|
|
3710
|
+
)
|
|
3711
|
+
]
|
|
3712
|
+
};
|
|
3713
|
+
} else if (artifact.type === "asset") {
|
|
3714
|
+
assets[fileName] = {
|
|
3715
|
+
fileName,
|
|
3716
|
+
names: [...artifact.names ?? (artifact.name ? [artifact.name] : [])],
|
|
3717
|
+
publicPath: joinPublicPath(publicPath, fileName)
|
|
3718
|
+
};
|
|
3719
|
+
}
|
|
3720
|
+
}
|
|
3721
|
+
return { chunks, assets, sourceMaps };
|
|
3722
|
+
}
|
|
3294
3723
|
function prepareBuildOutputDirectories(config, buildableNames) {
|
|
3295
3724
|
const directories = /* @__PURE__ */ new Set();
|
|
3296
3725
|
const protectedPaths = /* @__PURE__ */ new Set();
|
|
@@ -3368,6 +3797,7 @@ function createOxcTransformPlugin(config, environment) {
|
|
|
3368
3797
|
if (!shouldTransform(id)) return null;
|
|
3369
3798
|
const result = transformCode(id, code, {
|
|
3370
3799
|
sourcemap: !!environment.options.build.sourcemap,
|
|
3800
|
+
target: environment.options.build.target,
|
|
3371
3801
|
jsxRuntime: "automatic",
|
|
3372
3802
|
jsxImportSource: config.framework === "vue" ? "vue" : "react"
|
|
3373
3803
|
});
|
|
@@ -3381,9 +3811,9 @@ async function build(inlineConfig = {}) {
|
|
|
3381
3811
|
const startTime = performance.now();
|
|
3382
3812
|
logger.info(
|
|
3383
3813
|
pc4.cyan(`
|
|
3384
|
-
nasti v${"2.4.
|
|
3814
|
+
nasti v${"2.4.2"} `) + pc4.green(`building for ${config.mode}...`)
|
|
3385
3815
|
);
|
|
3386
|
-
|
|
3816
|
+
debug5?.(`root: ${config.root}`);
|
|
3387
3817
|
const buildableNames = Object.keys(config.environments).filter((name) => {
|
|
3388
3818
|
const environment = config.environments[name];
|
|
3389
3819
|
if (!environment.buildEnabled) return false;
|
|
@@ -3405,7 +3835,7 @@ nasti v${"2.4.0"} `) + pc4.green(`building for ${config.mode}...`)
|
|
|
3405
3835
|
environmentResults[name] = built.result;
|
|
3406
3836
|
if (name === "client") clientOutput = built.result.output;
|
|
3407
3837
|
if (buildableNames.length > 1) {
|
|
3408
|
-
|
|
3838
|
+
debug5?.(`environment "${name}" built (${built.result.output.length} files)`);
|
|
3409
3839
|
}
|
|
3410
3840
|
}
|
|
3411
3841
|
const pluginApi = getPluginApi(config);
|
|
@@ -3501,6 +3931,7 @@ async function buildClientEnvironment(config) {
|
|
|
3501
3931
|
const bundle2 = await rolldown(inputOptions);
|
|
3502
3932
|
const { output } = await bundle2.write(outputOptions);
|
|
3503
3933
|
await bundle2.close();
|
|
3934
|
+
clientEnv.setBuildMetadata({ css: getCssMetadata(cssEngine) });
|
|
3504
3935
|
if (html) {
|
|
3505
3936
|
let processedHtml = html;
|
|
3506
3937
|
const htmlPlugins = [...allPlugins.filter((p) => p.transformIndexHtml), htmlPlugin(config)];
|
|
@@ -3514,7 +3945,9 @@ async function buildClientEnvironment(config) {
|
|
|
3514
3945
|
processedHtml = processHtml(processedHtml, result);
|
|
3515
3946
|
}
|
|
3516
3947
|
}
|
|
3517
|
-
|
|
3948
|
+
if (clientEnv.options.build.css.inject !== false) {
|
|
3949
|
+
processedHtml = injectCssLinks(processedHtml, cssEngine, config);
|
|
3950
|
+
}
|
|
3518
3951
|
for (const chunk of output) {
|
|
3519
3952
|
if (chunk.type === "chunk" && chunk.isEntry && chunk.facadeModuleId) {
|
|
3520
3953
|
processedHtml = replaceEntryScript(
|
|
@@ -3552,9 +3985,11 @@ async function buildClientEnvironment(config) {
|
|
|
3552
3985
|
async function buildServerEnvironment(config, name) {
|
|
3553
3986
|
const envOptions = config.environments[name];
|
|
3554
3987
|
const logger = config.logger;
|
|
3988
|
+
const cssEngine = envOptions.consumer === "client" ? createCssEngine() : void 0;
|
|
3555
3989
|
const pluginList = resolvePluginList(config, config.plugins, {
|
|
3556
3990
|
consumer: envOptions.consumer,
|
|
3557
|
-
environmentName: name
|
|
3991
|
+
environmentName: name,
|
|
3992
|
+
cssEngine
|
|
3558
3993
|
});
|
|
3559
3994
|
const environment = new NastiEnvironment(name, config, {
|
|
3560
3995
|
mode: "build",
|
|
@@ -3597,6 +4032,7 @@ async function buildServerEnvironment(config, name) {
|
|
|
3597
4032
|
const bundle2 = await rolldown(inputOptions);
|
|
3598
4033
|
const { output } = await bundle2.write(outputOptions);
|
|
3599
4034
|
await bundle2.close();
|
|
4035
|
+
if (cssEngine) environment.setBuildMetadata({ css: getCssMetadata(cssEngine) });
|
|
3600
4036
|
logger.info(
|
|
3601
4037
|
pc4.dim(` [${name}] `) + output.map((o) => path10.join(envOptions.build.outDir, o.fileName)).join(pc4.dim(", "))
|
|
3602
4038
|
);
|
|
@@ -3648,7 +4084,7 @@ function replaceEntryScript(html, facadeModuleId, fileName, config, htmlFile, ur
|
|
|
3648
4084
|
}
|
|
3649
4085
|
return processed;
|
|
3650
4086
|
}
|
|
3651
|
-
var
|
|
4087
|
+
var debug5, NODE_BUILTINS;
|
|
3652
4088
|
var init_build = __esm({
|
|
3653
4089
|
"src/build/index.ts"() {
|
|
3654
4090
|
"use strict";
|
|
@@ -3663,7 +4099,7 @@ var init_build = __esm({
|
|
|
3663
4099
|
init_debug();
|
|
3664
4100
|
init_plugin_api();
|
|
3665
4101
|
init_build_app_context();
|
|
3666
|
-
|
|
4102
|
+
debug5 = createDebugger("nasti:build");
|
|
3667
4103
|
NODE_BUILTINS = /* @__PURE__ */ new Set([...builtinModules, ...builtinModules.map((m) => `node:${m}`)]);
|
|
3668
4104
|
}
|
|
3669
4105
|
});
|
|
@@ -3713,13 +4149,6 @@ var init_ws = __esm({
|
|
|
3713
4149
|
});
|
|
3714
4150
|
|
|
3715
4151
|
// src/server/middleware.ts
|
|
3716
|
-
var middleware_exports = {};
|
|
3717
|
-
__export(middleware_exports, {
|
|
3718
|
-
REACT_REFRESH_GLOBAL_PREAMBLE: () => REACT_REFRESH_GLOBAL_PREAMBLE,
|
|
3719
|
-
getReactRefreshRuntimeEsm: () => getReactRefreshRuntimeEsm,
|
|
3720
|
-
transformMiddleware: () => transformMiddleware,
|
|
3721
|
-
transformRequest: () => transformRequest
|
|
3722
|
-
});
|
|
3723
4152
|
import path12 from "path";
|
|
3724
4153
|
import fs9 from "fs";
|
|
3725
4154
|
import { createRequire as createRequire3 } from "module";
|
|
@@ -3827,7 +4256,8 @@ const __nasti_hot__ = __nasti_createHotContext__(${urlLit});
|
|
|
3827
4256
|
function transformMiddleware(ctx) {
|
|
3828
4257
|
ctx.envDefine = buildEnvDefine(
|
|
3829
4258
|
loadEnv(ctx.config.mode, ctx.config.root, ctx.config.envPrefix),
|
|
3830
|
-
ctx.config.mode
|
|
4259
|
+
ctx.config.mode,
|
|
4260
|
+
ssrDefineOverrides(ctx.environment?.consumer ?? "client")
|
|
3831
4261
|
);
|
|
3832
4262
|
return async (req, res, next) => {
|
|
3833
4263
|
const url = req.url ?? "/";
|
|
@@ -3872,7 +4302,7 @@ function transformMiddleware(ctx) {
|
|
|
3872
4302
|
return;
|
|
3873
4303
|
}
|
|
3874
4304
|
}
|
|
3875
|
-
if (isModuleRequest(url)) {
|
|
4305
|
+
if (isModuleRequest(url, req.headers["sec-fetch-dest"])) {
|
|
3876
4306
|
try {
|
|
3877
4307
|
const result = await transformRequest(url, ctx);
|
|
3878
4308
|
if (result) {
|
|
@@ -3943,12 +4373,16 @@ async function transformRequest(url, ctx) {
|
|
|
3943
4373
|
if (rawQuery && !/^t=\d+$/.test(rawQuery)) {
|
|
3944
4374
|
const mod2 = await moduleGraph.ensureEntryFromUrl(url);
|
|
3945
4375
|
const transformVersion2 = mod2.invalidationVersion;
|
|
3946
|
-
const
|
|
3947
|
-
if (
|
|
3948
|
-
let code2 = typeof
|
|
4376
|
+
const loaded2 = await pluginContainer.load(url);
|
|
4377
|
+
if (loaded2 != null) {
|
|
4378
|
+
let code2 = typeof loaded2 === "string" ? loaded2 : loaded2.code;
|
|
4379
|
+
let map2 = typeof loaded2 === "string" ? void 0 : loaded2.map;
|
|
3949
4380
|
const transformed = await pluginContainer.transform(code2, url);
|
|
3950
4381
|
if (transformed != null) {
|
|
3951
4382
|
code2 = typeof transformed === "string" ? transformed : transformed.code;
|
|
4383
|
+
if (typeof transformed !== "string" && transformed.map != null) {
|
|
4384
|
+
map2 = transformed.map;
|
|
4385
|
+
}
|
|
3952
4386
|
}
|
|
3953
4387
|
const parentFile = resolveUrlToFile(cleanReqUrl, config.root) ?? cleanReqUrl;
|
|
3954
4388
|
moduleGraph.registerModule(mod2, parentFile);
|
|
@@ -3956,7 +4390,8 @@ async function transformRequest(url, ctx) {
|
|
|
3956
4390
|
code2 = injectImportMetaHot(hotInfo2.code, url);
|
|
3957
4391
|
code2 = replaceEnvInCode(code2, ctx.envDefine ?? buildEnvDefine(
|
|
3958
4392
|
loadEnv(config.mode, config.root, config.envPrefix),
|
|
3959
|
-
config.mode
|
|
4393
|
+
config.mode,
|
|
4394
|
+
ssrDefineOverrides(ctx.environment?.consumer ?? "client")
|
|
3960
4395
|
));
|
|
3961
4396
|
const importedUrls2 = /* @__PURE__ */ new Set();
|
|
3962
4397
|
code2 = rewriteImports(code2, config, parentFile, importedUrls2, moduleGraph);
|
|
@@ -3967,7 +4402,7 @@ async function transformRequest(url, ctx) {
|
|
|
3967
4402
|
hotInfo2.isSelfAccepting,
|
|
3968
4403
|
transformVersion2
|
|
3969
4404
|
);
|
|
3970
|
-
const transformResult2 = { code: code2 };
|
|
4405
|
+
const transformResult2 = { code: code2, map: map2 };
|
|
3971
4406
|
if (pruned2) {
|
|
3972
4407
|
if (pruned2.size > 0) ctx.onPrune?.([...pruned2].map((item) => item.url));
|
|
3973
4408
|
mod2.transformResult = transformResult2;
|
|
@@ -3986,10 +4421,13 @@ async function transformRequest(url, ctx) {
|
|
|
3986
4421
|
mod.transformResult = transformResult2;
|
|
3987
4422
|
return transformResult2;
|
|
3988
4423
|
}
|
|
3989
|
-
|
|
4424
|
+
const loaded = await pluginContainer.load(filePath);
|
|
4425
|
+
let code = loaded == null ? fs9.readFileSync(filePath, "utf-8") : typeof loaded === "string" ? loaded : loaded.code;
|
|
4426
|
+
let map = loaded && typeof loaded !== "string" ? loaded.map : void 0;
|
|
3990
4427
|
const pluginResult = await pluginContainer.transform(code, filePath);
|
|
3991
4428
|
if (pluginResult) {
|
|
3992
4429
|
code = typeof pluginResult === "string" ? pluginResult : pluginResult.code;
|
|
4430
|
+
if (typeof pluginResult !== "string") map = pluginResult.map;
|
|
3993
4431
|
}
|
|
3994
4432
|
const stableUrl = cleanReqUrl;
|
|
3995
4433
|
let wrappedWithRefresh = false;
|
|
@@ -4000,9 +4438,11 @@ async function transformRequest(url, ctx) {
|
|
|
4000
4438
|
sourcemap: true,
|
|
4001
4439
|
jsxRuntime: "automatic",
|
|
4002
4440
|
jsxImportSource: config.framework === "vue" ? "vue" : "react",
|
|
4003
|
-
reactRefresh: useRefresh
|
|
4441
|
+
reactRefresh: useRefresh,
|
|
4442
|
+
target: ctx.environment?.options.build.target ?? config.build.target
|
|
4004
4443
|
});
|
|
4005
4444
|
code = result.code;
|
|
4445
|
+
if (result.map) map = JSON.parse(result.map);
|
|
4006
4446
|
if (useRefresh) {
|
|
4007
4447
|
code = buildReactRefreshWrapper(stableUrl, code);
|
|
4008
4448
|
wrappedWithRefresh = true;
|
|
@@ -4015,7 +4455,8 @@ async function transformRequest(url, ctx) {
|
|
|
4015
4455
|
}
|
|
4016
4456
|
const envDefine = ctx.envDefine ?? buildEnvDefine(
|
|
4017
4457
|
loadEnv(config.mode, config.root, config.envPrefix),
|
|
4018
|
-
config.mode
|
|
4458
|
+
config.mode,
|
|
4459
|
+
ssrDefineOverrides(ctx.environment?.consumer ?? "client")
|
|
4019
4460
|
);
|
|
4020
4461
|
code = replaceEnvInCode(code, envDefine);
|
|
4021
4462
|
const importedUrls = /* @__PURE__ */ new Set();
|
|
@@ -4027,7 +4468,7 @@ async function transformRequest(url, ctx) {
|
|
|
4027
4468
|
wrappedWithRefresh || hotInfo.isSelfAccepting,
|
|
4028
4469
|
transformVersion
|
|
4029
4470
|
);
|
|
4030
|
-
const transformResult = { code };
|
|
4471
|
+
const transformResult = { code, map };
|
|
4031
4472
|
if (pruned) {
|
|
4032
4473
|
if (pruned.size > 0) ctx.onPrune?.([...pruned].map((item) => item.url));
|
|
4033
4474
|
mod.transformResult = transformResult;
|
|
@@ -4050,7 +4491,8 @@ async function loadVirtualModule(spec, ctx) {
|
|
|
4050
4491
|
}
|
|
4051
4492
|
code = replaceEnvInCode(code, ctx.envDefine ?? buildEnvDefine(
|
|
4052
4493
|
loadEnv(config.mode, config.root, config.envPrefix),
|
|
4053
|
-
config.mode
|
|
4494
|
+
config.mode,
|
|
4495
|
+
ssrDefineOverrides(ctx.environment?.consumer ?? "client")
|
|
4054
4496
|
));
|
|
4055
4497
|
const anchor = path12.join(config.root, "__nasti_virtual__.ts");
|
|
4056
4498
|
code = rewriteImports(code, config, anchor);
|
|
@@ -4595,10 +5037,15 @@ function resolveUrlToFile(url, root) {
|
|
|
4595
5037
|
}
|
|
4596
5038
|
return null;
|
|
4597
5039
|
}
|
|
4598
|
-
function isModuleRequest(url) {
|
|
5040
|
+
function isModuleRequest(url, destination) {
|
|
4599
5041
|
const cleanUrl = url.split("?")[0];
|
|
4600
5042
|
if (/\.(ts|tsx|jsx|js|mjs|vue|css|json)$/.test(cleanUrl)) return true;
|
|
4601
5043
|
if (cleanUrl.startsWith("/@modules/")) return true;
|
|
5044
|
+
if (isAssetFile(cleanUrl)) {
|
|
5045
|
+
const query = url.includes("?") ? url.slice(url.indexOf("?") + 1) : "";
|
|
5046
|
+
const isExplicitAssetModule = /(?:^|&)(?:url|raw)(?:&|$)/.test(query);
|
|
5047
|
+
return isExplicitAssetModule || destination === "script";
|
|
5048
|
+
}
|
|
4602
5049
|
if (!path12.extname(cleanUrl)) return true;
|
|
4603
5050
|
return false;
|
|
4604
5051
|
}
|
|
@@ -4611,11 +5058,15 @@ const hotModulesMap = new Map();
|
|
|
4611
5058
|
const disposeMap = new Map();
|
|
4612
5059
|
const pruneMap = new Map();
|
|
4613
5060
|
const dataMap = new Map();
|
|
5061
|
+
const customListenersMap = new Map();
|
|
4614
5062
|
let updateQueue = [];
|
|
4615
5063
|
let pendingUpdateQueue = false;
|
|
4616
5064
|
|
|
4617
5065
|
socket.addEventListener('message', async ({ data }) => {
|
|
4618
5066
|
const payload = JSON.parse(data);
|
|
5067
|
+
// \u9ED8\u8BA4\u6D4F\u89C8\u5668 client \u53EA\u6D88\u8D39\u81EA\u5DF1\u7684 HMR \u6D88\u606F\uFF1Bnative/worker \u73AF\u5883\u901A\u8FC7\u5404\u81EA\u7684
|
|
5068
|
+
// HotChannel \u6216 app-level HMR \u534F\u8C03\u5668\u5904\u7406\u540C\u4E00 transport \u4E0A\u7684\u547D\u540D\u6D88\u606F\u3002
|
|
5069
|
+
if (payload.environment && payload.environment !== 'client') return;
|
|
4619
5070
|
switch (payload.type) {
|
|
4620
5071
|
case 'connected':
|
|
4621
5072
|
console.debug('[nasti] connected.');
|
|
@@ -4648,8 +5099,24 @@ socket.addEventListener('message', async ({ data }) => {
|
|
|
4648
5099
|
disposeMap.delete(path);
|
|
4649
5100
|
pruneMap.delete(path);
|
|
4650
5101
|
dataMap.delete(path);
|
|
5102
|
+
clearCustomListeners(path);
|
|
4651
5103
|
}));
|
|
4652
5104
|
break;
|
|
5105
|
+
case 'custom': {
|
|
5106
|
+
const listenersByOwner = customListenersMap.get(payload.event);
|
|
5107
|
+
if (!listenersByOwner) break;
|
|
5108
|
+
const results = await Promise.allSettled(
|
|
5109
|
+
[...listenersByOwner.values()]
|
|
5110
|
+
.flatMap((listeners) => [...listeners])
|
|
5111
|
+
.map((listener) => Promise.resolve().then(() => listener(payload.data)))
|
|
5112
|
+
);
|
|
5113
|
+
for (const result of results) {
|
|
5114
|
+
if (result.status === 'rejected') {
|
|
5115
|
+
console.error('[nasti] custom HMR event listener failed:', result.reason);
|
|
5116
|
+
}
|
|
5117
|
+
}
|
|
5118
|
+
break;
|
|
5119
|
+
}
|
|
4653
5120
|
case 'error':
|
|
4654
5121
|
console.error('[nasti] error:', payload.err.message);
|
|
4655
5122
|
showErrorOverlay(payload.err);
|
|
@@ -4748,6 +5215,7 @@ export function createHotContext(ownerPath) {
|
|
|
4748
5215
|
// \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
|
|
4749
5216
|
const existing = hotModulesMap.get(ownerPath);
|
|
4750
5217
|
if (existing) existing.callbacks = [];
|
|
5218
|
+
clearCustomListeners(ownerPath);
|
|
4751
5219
|
|
|
4752
5220
|
const acceptDeps = (deps, callback = () => {}) => {
|
|
4753
5221
|
const mod = hotModulesMap.get(ownerPath) || { id: ownerPath, callbacks: [] };
|
|
@@ -4773,12 +5241,39 @@ export function createHotContext(ownerPath) {
|
|
|
4773
5241
|
dispose(callback) {
|
|
4774
5242
|
disposeMap.set(ownerPath, callback);
|
|
4775
5243
|
},
|
|
5244
|
+
on(event, callback) {
|
|
5245
|
+
let listenersByOwner = customListenersMap.get(event);
|
|
5246
|
+
if (!listenersByOwner) {
|
|
5247
|
+
listenersByOwner = new Map();
|
|
5248
|
+
customListenersMap.set(event, listenersByOwner);
|
|
5249
|
+
}
|
|
5250
|
+
let listeners = listenersByOwner.get(ownerPath);
|
|
5251
|
+
if (!listeners) {
|
|
5252
|
+
listeners = new Set();
|
|
5253
|
+
listenersByOwner.set(ownerPath, listeners);
|
|
5254
|
+
}
|
|
5255
|
+
listeners.add(callback);
|
|
5256
|
+
},
|
|
5257
|
+
off(event, callback) {
|
|
5258
|
+
const listenersByOwner = customListenersMap.get(event);
|
|
5259
|
+
const listeners = listenersByOwner?.get(ownerPath);
|
|
5260
|
+
listeners?.delete(callback);
|
|
5261
|
+
if (listeners?.size === 0) listenersByOwner.delete(ownerPath);
|
|
5262
|
+
if (listenersByOwner?.size === 0) customListenersMap.delete(event);
|
|
5263
|
+
},
|
|
4776
5264
|
invalidate() {
|
|
4777
5265
|
location.reload();
|
|
4778
5266
|
},
|
|
4779
5267
|
data: dataMap.get(ownerPath),
|
|
4780
5268
|
};
|
|
4781
5269
|
}
|
|
5270
|
+
|
|
5271
|
+
function clearCustomListeners(ownerPath) {
|
|
5272
|
+
for (const [event, listenersByOwner] of customListenersMap) {
|
|
5273
|
+
listenersByOwner.delete(ownerPath);
|
|
5274
|
+
if (listenersByOwner.size === 0) customListenersMap.delete(event);
|
|
5275
|
+
}
|
|
5276
|
+
}
|
|
4782
5277
|
`;
|
|
4783
5278
|
}
|
|
4784
5279
|
var __dirname_esm, __require2, __refreshRuntimeCache, REACT_REFRESH_BOUNDARY_HELPERS, REACT_REFRESH_GLOBAL_PREAMBLE, esmBundleCache, VALID_IDENT, RESOLVE_EXTENSIONS, ESM_CONDITIONS;
|
|
@@ -4789,6 +5284,7 @@ var init_middleware = __esm({
|
|
|
4789
5284
|
init_html();
|
|
4790
5285
|
init_env();
|
|
4791
5286
|
init_url();
|
|
5287
|
+
init_assets();
|
|
4792
5288
|
__dirname_esm = path12.dirname(fileURLToPath(import.meta.url));
|
|
4793
5289
|
__require2 = createRequire3(import.meta.url);
|
|
4794
5290
|
__refreshRuntimeCache = null;
|
|
@@ -4873,19 +5369,25 @@ window.__vite_plugin_react_preamble_installed__ = true;
|
|
|
4873
5369
|
import path13 from "path";
|
|
4874
5370
|
import fs10 from "fs";
|
|
4875
5371
|
import pc7 from "picocolors";
|
|
4876
|
-
async function handleFileChange(file, server) {
|
|
4877
|
-
const {
|
|
5372
|
+
async function handleFileChange(file, server, environmentName = "client", timestamp = Date.now()) {
|
|
5373
|
+
const { config } = server;
|
|
5374
|
+
const environment = server.environments[environmentName];
|
|
5375
|
+
if (!environment) {
|
|
5376
|
+
throw new Error(`[nasti] unknown dev environment "${environmentName}"`);
|
|
5377
|
+
}
|
|
5378
|
+
const moduleGraph = environment.moduleGraph;
|
|
4878
5379
|
const logger = config.logger;
|
|
4879
5380
|
const relativePath = "/" + path13.relative(config.root, file);
|
|
4880
5381
|
const shortFile = path13.relative(config.root, file);
|
|
4881
5382
|
const mods = moduleGraph.getModulesByFile(file);
|
|
4882
5383
|
if (!mods || mods.size === 0) {
|
|
4883
|
-
return;
|
|
5384
|
+
return null;
|
|
4884
5385
|
}
|
|
4885
5386
|
const updates = [];
|
|
4886
|
-
const timestamp = Date.now();
|
|
4887
5387
|
const graph = moduleGraph;
|
|
4888
5388
|
const invalidatedModules = /* @__PURE__ */ new Set();
|
|
5389
|
+
const affectedSet = /* @__PURE__ */ new Set();
|
|
5390
|
+
let fullReload = false;
|
|
4889
5391
|
for (const mod of mods) {
|
|
4890
5392
|
graph.invalidateModuleAndImporters(mod, timestamp, invalidatedModules);
|
|
4891
5393
|
const ctx = {
|
|
@@ -4893,10 +5395,11 @@ async function handleFileChange(file, server) {
|
|
|
4893
5395
|
timestamp,
|
|
4894
5396
|
modules: [mod],
|
|
4895
5397
|
read: () => fs10.readFileSync(file, "utf-8"),
|
|
4896
|
-
server
|
|
5398
|
+
server,
|
|
5399
|
+
environment
|
|
4897
5400
|
};
|
|
4898
5401
|
let affectedModules = [mod];
|
|
4899
|
-
for (const plugin of
|
|
5402
|
+
for (const plugin of environment.plugins) {
|
|
4900
5403
|
if (plugin.handleHotUpdate) {
|
|
4901
5404
|
const result = await plugin.handleHotUpdate(ctx);
|
|
4902
5405
|
if (result) {
|
|
@@ -4905,12 +5408,12 @@ async function handleFileChange(file, server) {
|
|
|
4905
5408
|
}
|
|
4906
5409
|
}
|
|
4907
5410
|
for (const affected of affectedModules) {
|
|
5411
|
+
affectedSet.add(affected);
|
|
4908
5412
|
graph.invalidateModuleAndImporters(affected, timestamp, invalidatedModules);
|
|
4909
5413
|
const boundaries = graph.getHmrBoundaries(affected);
|
|
4910
5414
|
if (boundaries.length === 0) {
|
|
4911
|
-
|
|
4912
|
-
|
|
4913
|
-
return;
|
|
5415
|
+
fullReload = true;
|
|
5416
|
+
continue;
|
|
4914
5417
|
}
|
|
4915
5418
|
for (const { boundary, acceptedVia } of boundaries) {
|
|
4916
5419
|
const update = {
|
|
@@ -4927,13 +5430,30 @@ async function handleFileChange(file, server) {
|
|
|
4927
5430
|
}
|
|
4928
5431
|
}
|
|
4929
5432
|
}
|
|
4930
|
-
|
|
5433
|
+
const transformed = await Promise.all(
|
|
5434
|
+
[...affectedSet].map(async (module) => ({
|
|
5435
|
+
module,
|
|
5436
|
+
result: await environment.transformRequest(module.url)
|
|
5437
|
+
}))
|
|
5438
|
+
);
|
|
5439
|
+
const logPrefix = environmentName === "client" ? "" : `[${environmentName}] `;
|
|
5440
|
+
if (fullReload) {
|
|
5441
|
+
logger.info(pc7.green(`${logPrefix}reload `) + pc7.dim(shortFile), { timestamp: true });
|
|
5442
|
+
environment.hot.send({ type: "full-reload", path: relativePath });
|
|
5443
|
+
} else if (updates.length > 0) {
|
|
4931
5444
|
logger.info(
|
|
4932
|
-
updates.map((u) => pc7.green(
|
|
5445
|
+
updates.map((u) => pc7.green(`${logPrefix}hmr update `) + pc7.dim(u.path)).join("\n"),
|
|
4933
5446
|
{ timestamp: true }
|
|
4934
5447
|
);
|
|
4935
|
-
|
|
5448
|
+
environment.hot.send({ type: "update", updates });
|
|
4936
5449
|
}
|
|
5450
|
+
return {
|
|
5451
|
+
environment,
|
|
5452
|
+
modules: [...affectedSet],
|
|
5453
|
+
updates,
|
|
5454
|
+
transformed,
|
|
5455
|
+
fullReload
|
|
5456
|
+
};
|
|
4937
5457
|
}
|
|
4938
5458
|
var init_hmr = __esm({
|
|
4939
5459
|
"src/server/hmr.ts"() {
|
|
@@ -4959,14 +5479,14 @@ function createModuleRunner(environment) {
|
|
|
4959
5479
|
}
|
|
4960
5480
|
return new NastiModuleRunner(environment);
|
|
4961
5481
|
}
|
|
4962
|
-
var
|
|
5482
|
+
var debug6, NODE_BUILTINS3, NastiModuleRunner, AsyncFunction;
|
|
4963
5483
|
var init_runnable_environment = __esm({
|
|
4964
5484
|
"src/server/runnable-environment.ts"() {
|
|
4965
5485
|
"use strict";
|
|
4966
5486
|
init_transformer();
|
|
4967
5487
|
init_env();
|
|
4968
5488
|
init_debug();
|
|
4969
|
-
|
|
5489
|
+
debug6 = createDebugger("nasti:ssr");
|
|
4970
5490
|
NODE_BUILTINS3 = /* @__PURE__ */ new Set([...builtinModules3, ...builtinModules3.map((m) => `node:${m}`)]);
|
|
4971
5491
|
NastiModuleRunner = class {
|
|
4972
5492
|
environment;
|
|
@@ -5044,6 +5564,7 @@ var init_runnable_environment = __esm({
|
|
|
5044
5564
|
if (shouldTransform(cleanId)) {
|
|
5045
5565
|
const result = transformCode(cleanId, code, {
|
|
5046
5566
|
sourcemap: false,
|
|
5567
|
+
target: this.environment.options.build.target,
|
|
5047
5568
|
jsxRuntime: "automatic",
|
|
5048
5569
|
jsxImportSource: this.config.framework === "vue" ? "vue" : "react"
|
|
5049
5570
|
});
|
|
@@ -5060,7 +5581,7 @@ var init_runnable_environment = __esm({
|
|
|
5060
5581
|
);
|
|
5061
5582
|
}
|
|
5062
5583
|
const runnerResult = await moduleRunnerTransform(resolvedId, code);
|
|
5063
|
-
|
|
5584
|
+
debug6?.(`fetchModule ${resolvedId} (${runnerResult.deps?.length ?? 0} deps)`);
|
|
5064
5585
|
return { id: resolvedId, code: runnerResult.code };
|
|
5065
5586
|
}
|
|
5066
5587
|
completeExtension(id) {
|
|
@@ -5184,7 +5705,7 @@ async function createBundledDevServer(opts) {
|
|
|
5184
5705
|
}
|
|
5185
5706
|
} catch (err) {
|
|
5186
5707
|
throw new Error(
|
|
5187
|
-
`[nasti] experimental.bundledDev requires rolldown's experimental dev() API (locked
|
|
5708
|
+
`[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.`
|
|
5188
5709
|
);
|
|
5189
5710
|
}
|
|
5190
5711
|
const html = await readHtmlFile(config.root, config.environments.client?.html);
|
|
@@ -5237,7 +5758,7 @@ async function createBundledDevServer(opts) {
|
|
|
5237
5758
|
for (const { clientId, update } of updates) {
|
|
5238
5759
|
if (update.type === "Noop") continue;
|
|
5239
5760
|
if (update.type === "FullReload") {
|
|
5240
|
-
|
|
5761
|
+
debug7?.(`full reload for ${clientId}: ${update.reason ?? ""}`);
|
|
5241
5762
|
needsLatestOutput = true;
|
|
5242
5763
|
continue;
|
|
5243
5764
|
}
|
|
@@ -5287,7 +5808,7 @@ async function createBundledDevServer(opts) {
|
|
|
5287
5808
|
},
|
|
5288
5809
|
{
|
|
5289
5810
|
watch: { skipWrite: true },
|
|
5290
|
-
rebuildStrategy: "
|
|
5811
|
+
rebuildStrategy: "never",
|
|
5291
5812
|
onOutput(result) {
|
|
5292
5813
|
if (result instanceof Error) {
|
|
5293
5814
|
logger.error(pc8.red(`[bundled] build error: ${result.message}`), { error: result });
|
|
@@ -5303,7 +5824,13 @@ async function createBundledDevServer(opts) {
|
|
|
5303
5824
|
memoryFiles.set(`${file.fileName}.map`, JSON.stringify(file.map));
|
|
5304
5825
|
}
|
|
5305
5826
|
}
|
|
5306
|
-
|
|
5827
|
+
debug7?.(`bundle output refreshed (${result.output.length} files)`);
|
|
5828
|
+
},
|
|
5829
|
+
onAdditionalAssets(result) {
|
|
5830
|
+
for (const file of result.output) {
|
|
5831
|
+
const content = file.type === "chunk" ? file.code : file.source;
|
|
5832
|
+
if (content != null) memoryFiles.set(file.fileName, content);
|
|
5833
|
+
}
|
|
5307
5834
|
},
|
|
5308
5835
|
async onHmrUpdates(result) {
|
|
5309
5836
|
if (result instanceof Error) {
|
|
@@ -5312,7 +5839,7 @@ async function createBundledDevServer(opts) {
|
|
|
5312
5839
|
return;
|
|
5313
5840
|
}
|
|
5314
5841
|
const { updates, changedFiles } = result;
|
|
5315
|
-
|
|
5842
|
+
debug7?.(
|
|
5316
5843
|
`onHmrUpdates(engine watcher): ${changedFiles.length} changed, ${updates.length} updates`
|
|
5317
5844
|
);
|
|
5318
5845
|
if (changedFiles.length === 0) return;
|
|
@@ -5331,24 +5858,29 @@ async function createBundledDevServer(opts) {
|
|
|
5331
5858
|
if (!clientId) return;
|
|
5332
5859
|
wss.handleUpgrade(req, socket, head, (ws) => {
|
|
5333
5860
|
bundledClients.set(clientId, ws);
|
|
5334
|
-
|
|
5335
|
-
|
|
5861
|
+
debug7?.(`bundled client connected: ${clientId}`);
|
|
5862
|
+
void engine.registerClient(clientId).then(async () => {
|
|
5863
|
+
for (const fileName of entryFileNames.values()) {
|
|
5864
|
+
await engine.notifyPayloadDelivered(fileName);
|
|
5865
|
+
}
|
|
5866
|
+
ws.send(JSON.stringify({ type: "connected" }));
|
|
5867
|
+
}).catch((err) => {
|
|
5868
|
+
debug7?.(`registerClient failed for ${clientId}: ${err?.message ?? err}`);
|
|
5869
|
+
ws.close();
|
|
5870
|
+
});
|
|
5336
5871
|
ws.on("message", async (raw) => {
|
|
5337
5872
|
try {
|
|
5338
5873
|
const msg = JSON.parse(String(raw));
|
|
5339
|
-
if (msg.type === "hmr:
|
|
5340
|
-
await engine.registerModules(clientId, msg.modules);
|
|
5341
|
-
debug6?.(`registered ${msg.modules.length} modules for ${clientId}`);
|
|
5342
|
-
} else if (msg.type === "hmr:invalidate") {
|
|
5874
|
+
if (msg.type === "hmr:invalidate") {
|
|
5343
5875
|
scheduleFullReload();
|
|
5344
5876
|
}
|
|
5345
5877
|
} catch (err) {
|
|
5346
|
-
|
|
5878
|
+
debug7?.(`bundled ws message error: ${err.message}`);
|
|
5347
5879
|
}
|
|
5348
5880
|
});
|
|
5349
5881
|
ws.on("close", () => {
|
|
5350
5882
|
bundledClients.delete(clientId);
|
|
5351
|
-
engine.removeClient(clientId).catch((err) =>
|
|
5883
|
+
engine.removeClient(clientId).catch((err) => debug7?.(`removeClient failed for ${clientId}: ${err?.message ?? err}`));
|
|
5352
5884
|
});
|
|
5353
5885
|
});
|
|
5354
5886
|
});
|
|
@@ -5365,10 +5897,18 @@ async function createBundledDevServer(opts) {
|
|
|
5365
5897
|
res.end("// [nasti] lazy endpoint requires id & clientId");
|
|
5366
5898
|
return;
|
|
5367
5899
|
}
|
|
5368
|
-
const
|
|
5900
|
+
const output = await engine.compileEntry(id, clientId);
|
|
5901
|
+
if (output.sourcemap && output.sourcemapFilename) {
|
|
5902
|
+
memoryFiles.set(output.sourcemapFilename, output.sourcemap);
|
|
5903
|
+
}
|
|
5904
|
+
res.once("finish", () => {
|
|
5905
|
+
void engine.notifyPayloadDelivered(output.filename).catch(
|
|
5906
|
+
(err) => debug7?.(`notifyPayloadDelivered failed: ${err?.message ?? err}`)
|
|
5907
|
+
);
|
|
5908
|
+
});
|
|
5369
5909
|
res.setHeader("Content-Type", "application/javascript");
|
|
5370
5910
|
res.setHeader("Cache-Control", "no-store");
|
|
5371
|
-
res.end(code + "\n;export {}");
|
|
5911
|
+
res.end(output.code + "\n;export {}");
|
|
5372
5912
|
return;
|
|
5373
5913
|
}
|
|
5374
5914
|
const patchHit = patches.get(pathname.replace(/^\//, ""));
|
|
@@ -5389,6 +5929,11 @@ async function createBundledDevServer(opts) {
|
|
|
5389
5929
|
res.setHeader("ETag", hit.etag);
|
|
5390
5930
|
res.setHeader("Content-Type", MIME_TYPES[path15.extname(fileName)] ?? "application/octet-stream");
|
|
5391
5931
|
res.setHeader("Cache-Control", "no-cache");
|
|
5932
|
+
res.once("finish", () => {
|
|
5933
|
+
void engine.notifyPayloadDelivered(fileName).catch(
|
|
5934
|
+
(err) => debug7?.(`notifyPayloadDelivered failed: ${err?.message ?? err}`)
|
|
5935
|
+
);
|
|
5936
|
+
});
|
|
5392
5937
|
res.end(hit.content);
|
|
5393
5938
|
return;
|
|
5394
5939
|
}
|
|
@@ -5488,7 +6033,7 @@ async function renderBundledIndexHtml(html, config, entryFileNames) {
|
|
|
5488
6033
|
}
|
|
5489
6034
|
return processed;
|
|
5490
6035
|
}
|
|
5491
|
-
var
|
|
6036
|
+
var debug7, MIME_TYPES, MemoryFiles, PREAMBLE_SPEC, RESOLVED_PREAMBLE_ID, REFRESH_RUNTIME_URL, BUNDLED_PREAMBLE_CODE, WRAPPER_RUNTIME_HELPERS;
|
|
5492
6037
|
var init_dev_engine = __esm({
|
|
5493
6038
|
"src/server/bundled/dev-engine.ts"() {
|
|
5494
6039
|
"use strict";
|
|
@@ -5497,7 +6042,7 @@ var init_dev_engine = __esm({
|
|
|
5497
6042
|
init_transformer();
|
|
5498
6043
|
init_middleware();
|
|
5499
6044
|
init_debug();
|
|
5500
|
-
|
|
6045
|
+
debug7 = createDebugger("nasti:bundled");
|
|
5501
6046
|
MIME_TYPES = {
|
|
5502
6047
|
".js": "application/javascript",
|
|
5503
6048
|
".mjs": "application/javascript",
|
|
@@ -5631,7 +6176,7 @@ async function createServer(inlineConfig = {}) {
|
|
|
5631
6176
|
const ws = createWebSocketServer(httpServer);
|
|
5632
6177
|
const pluginApi = getPluginApi(config);
|
|
5633
6178
|
const clientEnv = new NastiEnvironment("client", config, {
|
|
5634
|
-
hot: createWsHotChannel(ws),
|
|
6179
|
+
hot: createWsHotChannel(ws, "client"),
|
|
5635
6180
|
mode: "dev",
|
|
5636
6181
|
plugins: allPlugins,
|
|
5637
6182
|
pluginApi
|
|
@@ -5646,13 +6191,40 @@ async function createServer(inlineConfig = {}) {
|
|
|
5646
6191
|
environmentName: name
|
|
5647
6192
|
});
|
|
5648
6193
|
environments[name] = new NastiEnvironment(name, config, {
|
|
6194
|
+
hot: consumer === "client" ? createWsHotChannel(ws, name) : void 0,
|
|
5649
6195
|
mode: "dev",
|
|
5650
6196
|
plugins: envPlugins,
|
|
5651
6197
|
pluginApi
|
|
5652
6198
|
});
|
|
5653
6199
|
}
|
|
5654
6200
|
for (const [name, environment] of Object.entries(environments)) {
|
|
5655
|
-
if (name
|
|
6201
|
+
if (name === "client" || environment.consumer === "client" || environment.options.driver) {
|
|
6202
|
+
await environment.init();
|
|
6203
|
+
}
|
|
6204
|
+
}
|
|
6205
|
+
const transformContexts = /* @__PURE__ */ new Map();
|
|
6206
|
+
for (const environment of Object.values(environments)) {
|
|
6207
|
+
if (environment.consumer !== "client" || environment.driver) continue;
|
|
6208
|
+
const environmentConfig = {
|
|
6209
|
+
...configWithPlugins,
|
|
6210
|
+
resolve: environment.options.resolve,
|
|
6211
|
+
build: environment.options.build,
|
|
6212
|
+
plugins: environment.plugins
|
|
6213
|
+
};
|
|
6214
|
+
const context = {
|
|
6215
|
+
config: environmentConfig,
|
|
6216
|
+
pluginContainer: environment.pluginContainer,
|
|
6217
|
+
moduleGraph: environment.moduleGraph,
|
|
6218
|
+
environment,
|
|
6219
|
+
envDefine: buildEnvDefine(
|
|
6220
|
+
loadEnv(environmentConfig.mode, environmentConfig.root, environmentConfig.envPrefix),
|
|
6221
|
+
environmentConfig.mode,
|
|
6222
|
+
ssrDefineOverrides(environment.consumer)
|
|
6223
|
+
),
|
|
6224
|
+
onPrune: (paths) => environment.hot.send({ type: "prune", paths })
|
|
6225
|
+
};
|
|
6226
|
+
transformContexts.set(environment.name, context);
|
|
6227
|
+
environment.configureDevPipeline((url) => transformRequest(url, context));
|
|
5656
6228
|
}
|
|
5657
6229
|
let ssrRunner = null;
|
|
5658
6230
|
async function getSsrRunner() {
|
|
@@ -5667,7 +6239,6 @@ async function createServer(inlineConfig = {}) {
|
|
|
5667
6239
|
return ssrRunner;
|
|
5668
6240
|
}
|
|
5669
6241
|
const moduleGraph = clientEnv.moduleGraph;
|
|
5670
|
-
const pluginContainer = clientEnv.pluginContainer;
|
|
5671
6242
|
let bundledServer = null;
|
|
5672
6243
|
if (config.experimental.bundledDev) {
|
|
5673
6244
|
const { createBundledDevServer: createBundledDevServer2 } = await Promise.resolve().then(() => (init_dev_engine(), dev_engine_exports));
|
|
@@ -5696,6 +6267,15 @@ async function createServer(inlineConfig = {}) {
|
|
|
5696
6267
|
let server;
|
|
5697
6268
|
const environmentServices = {};
|
|
5698
6269
|
let environmentDriversStarted = false;
|
|
6270
|
+
let devPipelinesStarted = false;
|
|
6271
|
+
const startDevPipelines = async () => {
|
|
6272
|
+
if (devPipelinesStarted) return;
|
|
6273
|
+
devPipelinesStarted = true;
|
|
6274
|
+
for (const environment of Object.values(environments)) {
|
|
6275
|
+
if (!transformContexts.has(environment.name)) continue;
|
|
6276
|
+
await environment.pluginContainer.buildStart();
|
|
6277
|
+
}
|
|
6278
|
+
};
|
|
5699
6279
|
const logCloseError = (target, error) => {
|
|
5700
6280
|
const normalized = error instanceof Error ? error : new Error(String(error));
|
|
5701
6281
|
logger.error(`[nasti] failed to close ${target}`, { error: normalized });
|
|
@@ -5747,14 +6327,61 @@ async function createServer(inlineConfig = {}) {
|
|
|
5747
6327
|
});
|
|
5748
6328
|
}
|
|
5749
6329
|
};
|
|
6330
|
+
const updateClientEnvironments = async (file) => {
|
|
6331
|
+
const timestamp = Date.now();
|
|
6332
|
+
const results = {};
|
|
6333
|
+
for (const environment of Object.values(environments)) {
|
|
6334
|
+
if (environment.consumer !== "client" || environment.driver) continue;
|
|
6335
|
+
try {
|
|
6336
|
+
const result = await handleFileChange(file, server, environment.name, timestamp);
|
|
6337
|
+
if (result) results[environment.name] = result;
|
|
6338
|
+
} catch (error) {
|
|
6339
|
+
const normalized = error instanceof Error ? error : new Error(String(error));
|
|
6340
|
+
logger.error(
|
|
6341
|
+
`[nasti] HMR failed for environment "${environment.name}": ${normalized.message}`,
|
|
6342
|
+
{ error: normalized }
|
|
6343
|
+
);
|
|
6344
|
+
try {
|
|
6345
|
+
environment.hot.send({
|
|
6346
|
+
type: "error",
|
|
6347
|
+
err: { message: normalized.message, stack: normalized.stack }
|
|
6348
|
+
});
|
|
6349
|
+
} catch (channelError) {
|
|
6350
|
+
const channelFailure = channelError instanceof Error ? channelError : new Error(String(channelError));
|
|
6351
|
+
logger.error(
|
|
6352
|
+
`[nasti] failed to deliver HMR error to environment "${environment.name}"`,
|
|
6353
|
+
{ error: channelFailure }
|
|
6354
|
+
);
|
|
6355
|
+
}
|
|
6356
|
+
}
|
|
6357
|
+
}
|
|
6358
|
+
if (Object.keys(results).length === 0) return;
|
|
6359
|
+
const context = {
|
|
6360
|
+
file,
|
|
6361
|
+
timestamp,
|
|
6362
|
+
environments: Object.freeze({ ...results }),
|
|
6363
|
+
server
|
|
6364
|
+
};
|
|
6365
|
+
for (const plugin of config.plugins) {
|
|
6366
|
+
await plugin.handleHotUpdateApp?.(context);
|
|
6367
|
+
}
|
|
6368
|
+
};
|
|
6369
|
+
const queueClientEnvironmentUpdate = (file) => {
|
|
6370
|
+
void updateClientEnvironments(file).catch((error) => {
|
|
6371
|
+
const normalized = error instanceof Error ? error : new Error(String(error));
|
|
6372
|
+
logger.error(`[nasti] multi-environment HMR failed: ${normalized.message}`, {
|
|
6373
|
+
error: normalized
|
|
6374
|
+
});
|
|
6375
|
+
});
|
|
6376
|
+
};
|
|
5750
6377
|
watcher.on("change", (file) => {
|
|
5751
6378
|
ssrRunner?.invalidateFile(file);
|
|
5752
|
-
|
|
6379
|
+
queueClientEnvironmentUpdate(file);
|
|
5753
6380
|
notifyEnvironmentDrivers(file, "change");
|
|
5754
6381
|
});
|
|
5755
6382
|
watcher.on("add", (file) => {
|
|
5756
6383
|
ssrRunner?.invalidateFile(file);
|
|
5757
|
-
|
|
6384
|
+
queueClientEnvironmentUpdate(file);
|
|
5758
6385
|
notifyEnvironmentDrivers(file, "add");
|
|
5759
6386
|
});
|
|
5760
6387
|
watcher.on("unlink", (file) => {
|
|
@@ -5772,7 +6399,7 @@ async function createServer(inlineConfig = {}) {
|
|
|
5772
6399
|
async listen(port) {
|
|
5773
6400
|
const finalPort = port ?? config.server.port;
|
|
5774
6401
|
const host = config.server.host === true ? "0.0.0.0" : config.server.host;
|
|
5775
|
-
await
|
|
6402
|
+
await startDevPipelines();
|
|
5776
6403
|
await startEnvironmentDrivers();
|
|
5777
6404
|
return new Promise((resolve, reject) => {
|
|
5778
6405
|
let currentPort = finalPort;
|
|
@@ -5787,7 +6414,7 @@ async function createServer(inlineConfig = {}) {
|
|
|
5787
6414
|
const readyIn = Math.ceil(performance.now() - startTime);
|
|
5788
6415
|
logger.info(
|
|
5789
6416
|
`
|
|
5790
|
-
${pc9.cyan(pc9.bold("NASTI"))} ${pc9.cyan(`v${"2.4.
|
|
6417
|
+
${pc9.cyan(pc9.bold("NASTI"))} ${pc9.cyan(`v${"2.4.2"}`)} ${pc9.dim("ready in")} ${pc9.bold(readyIn)} ${pc9.dim("ms")}
|
|
5791
6418
|
`
|
|
5792
6419
|
);
|
|
5793
6420
|
printServerUrls(
|
|
@@ -5814,20 +6441,26 @@ async function createServer(inlineConfig = {}) {
|
|
|
5814
6441
|
});
|
|
5815
6442
|
},
|
|
5816
6443
|
async transformRequest(url) {
|
|
5817
|
-
|
|
5818
|
-
|
|
5819
|
-
|
|
5820
|
-
|
|
5821
|
-
|
|
5822
|
-
|
|
5823
|
-
}
|
|
6444
|
+
return clientEnv.transformRequest(url);
|
|
6445
|
+
},
|
|
6446
|
+
async transformEnvironmentRequest(environmentName, url) {
|
|
6447
|
+
const environment = environments[environmentName];
|
|
6448
|
+
if (!environment) {
|
|
6449
|
+
throw new Error(`[nasti] unknown dev environment "${environmentName}"`);
|
|
6450
|
+
}
|
|
6451
|
+
return environment.transformRequest(url);
|
|
5824
6452
|
},
|
|
5825
6453
|
async ssrLoadModule(url) {
|
|
5826
6454
|
const runner = await getSsrRunner();
|
|
5827
6455
|
return runner.import(url);
|
|
5828
6456
|
},
|
|
5829
6457
|
async close() {
|
|
5830
|
-
|
|
6458
|
+
if (devPipelinesStarted) {
|
|
6459
|
+
for (const environment of Object.values(environments).reverse()) {
|
|
6460
|
+
if (!transformContexts.has(environment.name)) continue;
|
|
6461
|
+
await environment.pluginContainer.buildEnd();
|
|
6462
|
+
}
|
|
6463
|
+
}
|
|
5831
6464
|
await bundledServer?.close();
|
|
5832
6465
|
let environmentCloseFailed = false;
|
|
5833
6466
|
let firstEnvironmentCloseError;
|
|
@@ -5877,12 +6510,7 @@ async function createServer(inlineConfig = {}) {
|
|
|
5877
6510
|
}
|
|
5878
6511
|
throw error;
|
|
5879
6512
|
}
|
|
5880
|
-
app.use(transformMiddleware(
|
|
5881
|
-
config: configWithPlugins,
|
|
5882
|
-
pluginContainer,
|
|
5883
|
-
moduleGraph,
|
|
5884
|
-
onPrune: (paths) => ws.send({ type: "prune", paths })
|
|
5885
|
-
}));
|
|
6513
|
+
app.use(transformMiddleware(transformContexts.get("client")));
|
|
5886
6514
|
const publicDir = path16.resolve(config.root, "public");
|
|
5887
6515
|
app.use(sirv(publicDir, { dev: true, etag: true }));
|
|
5888
6516
|
app.use(sirv(config.root, { dev: true, etag: true }));
|
|
@@ -5921,6 +6549,7 @@ var init_server = __esm({
|
|
|
5921
6549
|
init_hmr();
|
|
5922
6550
|
init_builtins();
|
|
5923
6551
|
init_plugin_api();
|
|
6552
|
+
init_env();
|
|
5924
6553
|
}
|
|
5925
6554
|
});
|
|
5926
6555
|
|
|
@@ -5976,7 +6605,7 @@ async function buildElectron(inlineConfig = {}) {
|
|
|
5976
6605
|
const config = await resolveConfig({ ...inlineConfig, target: "electron" }, "build");
|
|
5977
6606
|
const startTime = performance.now();
|
|
5978
6607
|
assertElectronVersion(config);
|
|
5979
|
-
console.log(pc5.cyan("\n\u26A1 nasti build (electron)") + pc5.dim(` v${"2.4.
|
|
6608
|
+
console.log(pc5.cyan("\n\u26A1 nasti build (electron)") + pc5.dim(` v${"2.4.2"}`));
|
|
5980
6609
|
console.log(pc5.dim(` root: ${config.root}`));
|
|
5981
6610
|
console.log(pc5.dim(` mode: ${config.mode}`));
|
|
5982
6611
|
console.log(pc5.dim(` target: electron (\u2265 ${config.electron.minVersion})`));
|
|
@@ -6149,7 +6778,7 @@ async function startElectronDev(inlineConfig = {}) {
|
|
|
6149
6778
|
const { noSpawn, ...rest } = inlineConfig;
|
|
6150
6779
|
const config = await resolveConfig({ ...rest, target: "electron" }, "serve");
|
|
6151
6780
|
warnElectronVersion(config);
|
|
6152
|
-
console.log(pc10.cyan("\n\u26A1 nasti electron dev") + pc10.dim(` v${"2.4.
|
|
6781
|
+
console.log(pc10.cyan("\n\u26A1 nasti electron dev") + pc10.dim(` v${"2.4.2"}`));
|
|
6153
6782
|
const { createServer: createServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
|
|
6154
6783
|
const server = await createServer2({
|
|
6155
6784
|
...rest,
|