@nasti-toolchain/nasti 2.3.1 → 2.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +97 -1
- package/bin/nasti.js +0 -0
- package/client/hmr.ts +4 -3
- package/dist/cli.cjs +1896 -583
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +1891 -575
- package/dist/cli.js.map +1 -1
- package/dist/client/hmr.cjs.map +1 -1
- package/dist/client/hmr.d.cts +4 -3
- package/dist/client/hmr.d.ts +4 -3
- package/dist/index.cjs +1810 -497
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +233 -18
- package/dist/index.d.ts +233 -18
- package/dist/index.js +1810 -494
- package/dist/index.js.map +1 -1
- package/package.json +8 -4
package/dist/cli.cjs
CHANGED
|
@@ -5,10 +5,10 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __glob = (map) => (
|
|
9
|
-
var fn = map[
|
|
8
|
+
var __glob = (map) => (path18) => {
|
|
9
|
+
var fn = map[path18];
|
|
10
10
|
if (fn) return fn();
|
|
11
|
-
throw new Error("Module not found in bundle: " +
|
|
11
|
+
throw new Error("Module not found in bundle: " + path18);
|
|
12
12
|
};
|
|
13
13
|
var __esm = (fn, res) => function __init() {
|
|
14
14
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
@@ -184,7 +184,10 @@ var init_defaults = __esm({
|
|
|
184
184
|
target: "es2022",
|
|
185
185
|
rolldownOptions: {},
|
|
186
186
|
emptyOutDir: true,
|
|
187
|
-
css: {
|
|
187
|
+
css: {
|
|
188
|
+
inject: true,
|
|
189
|
+
emit: true
|
|
190
|
+
},
|
|
188
191
|
reportCompressedSize: true,
|
|
189
192
|
chunkSizeWarningLimit: 500,
|
|
190
193
|
cssCodeSplit: true,
|
|
@@ -420,7 +423,11 @@ async function resolveConfig(inlineConfig = {}, command) {
|
|
|
420
423
|
allowClearScreen: clearScreen2,
|
|
421
424
|
customLogger: merged.customLogger
|
|
422
425
|
});
|
|
423
|
-
const mergedBuild = {
|
|
426
|
+
const mergedBuild = {
|
|
427
|
+
...defaults.build,
|
|
428
|
+
...merged.build,
|
|
429
|
+
css: { ...defaults.build.css, ...merged.build?.css }
|
|
430
|
+
};
|
|
424
431
|
if (merged.build?.cssMinify === void 0) {
|
|
425
432
|
mergedBuild.cssMinify = !!mergedBuild.minify;
|
|
426
433
|
}
|
|
@@ -451,11 +458,17 @@ async function resolveConfig(inlineConfig = {}, command) {
|
|
|
451
458
|
bundledDev: merged.experimental?.bundledDev ?? defaults.experimental.bundledDev
|
|
452
459
|
}
|
|
453
460
|
};
|
|
454
|
-
const
|
|
461
|
+
const rawUserEnvironments = {
|
|
455
462
|
client: {},
|
|
456
463
|
ssr: {},
|
|
457
464
|
...merged.environments ?? {}
|
|
458
465
|
};
|
|
466
|
+
const userEnvironments = Object.fromEntries(
|
|
467
|
+
Object.entries(rawUserEnvironments).map(([name, options]) => [
|
|
468
|
+
name,
|
|
469
|
+
deepMerge({}, options)
|
|
470
|
+
])
|
|
471
|
+
);
|
|
459
472
|
for (const [name, envOptions] of Object.entries(userEnvironments)) {
|
|
460
473
|
for (const plugin of rawPlugins) {
|
|
461
474
|
if (plugin.configEnvironment) {
|
|
@@ -466,6 +479,7 @@ async function resolveConfig(inlineConfig = {}, command) {
|
|
|
466
479
|
}
|
|
467
480
|
for (const [name, envOptions] of Object.entries(userEnvironments)) {
|
|
468
481
|
const consumer = envOptions.consumer ?? (name === "client" ? "client" : "server");
|
|
482
|
+
const vueOptions = deepMerge({}, envOptions.vue ?? {});
|
|
469
483
|
if (name === "client") {
|
|
470
484
|
if (envOptions.resolve) {
|
|
471
485
|
Object.assign(resolved.resolve, {
|
|
@@ -473,9 +487,14 @@ async function resolveConfig(inlineConfig = {}, command) {
|
|
|
473
487
|
alias: { ...resolved.resolve.alias, ...envOptions.resolve.alias }
|
|
474
488
|
});
|
|
475
489
|
}
|
|
476
|
-
if (envOptions.build)
|
|
490
|
+
if (envOptions.build) {
|
|
491
|
+
const { css, ...environmentBuild } = envOptions.build;
|
|
492
|
+
Object.assign(resolved.build, environmentBuild);
|
|
493
|
+
if (css) resolved.build.css = { ...resolved.build.css, ...css };
|
|
494
|
+
}
|
|
477
495
|
resolved.environments.client = {
|
|
478
496
|
consumer,
|
|
497
|
+
buildEnabled: envOptions.buildEnabled ?? true,
|
|
479
498
|
entry: normalizeEnvironmentEntries(envOptions.entry, root),
|
|
480
499
|
html: import_node_path.default.resolve(
|
|
481
500
|
root,
|
|
@@ -484,15 +503,18 @@ async function resolveConfig(inlineConfig = {}, command) {
|
|
|
484
503
|
driver: envOptions.driver,
|
|
485
504
|
// 同引用 —— 精确镜像(assertClientEnvironmentMirror 校验)
|
|
486
505
|
resolve: resolved.resolve,
|
|
487
|
-
build: resolved.build
|
|
506
|
+
build: resolved.build,
|
|
507
|
+
vue: vueOptions
|
|
488
508
|
};
|
|
489
509
|
continue;
|
|
490
510
|
}
|
|
491
511
|
resolved.environments[name] = {
|
|
492
512
|
consumer,
|
|
513
|
+
buildEnabled: envOptions.buildEnabled ?? true,
|
|
493
514
|
entry: normalizeEnvironmentEntries(envOptions.entry, root),
|
|
494
515
|
html: envOptions.consumer === "client" && envOptions.html ? import_node_path.default.resolve(root, envOptions.html) : void 0,
|
|
495
516
|
driver: envOptions.driver,
|
|
517
|
+
vue: vueOptions,
|
|
496
518
|
resolve: {
|
|
497
519
|
alias: { ...resolved.resolve.alias, ...envOptions.resolve?.alias },
|
|
498
520
|
extensions: envOptions.resolve?.extensions ?? [...resolved.resolve.extensions],
|
|
@@ -503,6 +525,7 @@ async function resolveConfig(inlineConfig = {}, command) {
|
|
|
503
525
|
build: {
|
|
504
526
|
...resolved.build,
|
|
505
527
|
...envOptions.build,
|
|
528
|
+
css: { ...resolved.build.css, ...envOptions.build?.css },
|
|
506
529
|
// 非 client 环境默认产出到 <outDir>/<envName>(如 dist/ssr),可显式覆盖
|
|
507
530
|
outDir: envOptions.build?.outDir ?? import_node_path.default.join(resolved.build.outDir, name),
|
|
508
531
|
// server 产物默认不压缩(可调试性优先,与 Vite SSR 默认一致),可显式覆盖
|
|
@@ -749,17 +772,23 @@ var init_plugin_container = __esm({
|
|
|
749
772
|
}
|
|
750
773
|
async transform(code, id) {
|
|
751
774
|
let currentCode = code;
|
|
775
|
+
let lastResult;
|
|
752
776
|
for (const plugin of this.plugins) {
|
|
753
777
|
if (!plugin.transform) continue;
|
|
754
778
|
const result = await plugin.transform.call(this.ctx, currentCode, id);
|
|
755
779
|
if (result == null) continue;
|
|
756
780
|
if (typeof result === "string") {
|
|
757
781
|
currentCode = result;
|
|
782
|
+
lastResult = void 0;
|
|
758
783
|
} else {
|
|
759
784
|
currentCode = result.code;
|
|
785
|
+
lastResult = result;
|
|
760
786
|
}
|
|
761
787
|
}
|
|
762
|
-
return currentCode === code ? null : {
|
|
788
|
+
return currentCode === code ? null : {
|
|
789
|
+
...lastResult,
|
|
790
|
+
code: currentCode
|
|
791
|
+
};
|
|
763
792
|
}
|
|
764
793
|
/** 完整的模块处理管道: resolveId → load → transform */
|
|
765
794
|
async processModule(source, importer) {
|
|
@@ -782,17 +811,39 @@ var init_plugin_container = __esm({
|
|
|
782
811
|
}
|
|
783
812
|
});
|
|
784
813
|
|
|
814
|
+
// src/core/url.ts
|
|
815
|
+
function removeTimestampQuery(url) {
|
|
816
|
+
const hashIndex = url.indexOf("#");
|
|
817
|
+
const hash = hashIndex >= 0 ? url.slice(hashIndex) : "";
|
|
818
|
+
const withoutHash = hashIndex >= 0 ? url.slice(0, hashIndex) : url;
|
|
819
|
+
const queryIndex = withoutHash.indexOf("?");
|
|
820
|
+
if (queryIndex < 0) return url;
|
|
821
|
+
const pathname = withoutHash.slice(0, queryIndex);
|
|
822
|
+
const query = withoutHash.slice(queryIndex + 1).split("&").filter((part) => !/^t=\d+$/.test(part)).join("&");
|
|
823
|
+
return pathname + (query ? `?${query}` : "") + hash;
|
|
824
|
+
}
|
|
825
|
+
var init_url = __esm({
|
|
826
|
+
"src/core/url.ts"() {
|
|
827
|
+
"use strict";
|
|
828
|
+
}
|
|
829
|
+
});
|
|
830
|
+
|
|
785
831
|
// src/core/module-graph.ts
|
|
786
832
|
var ModuleGraph;
|
|
787
833
|
var init_module_graph = __esm({
|
|
788
834
|
"src/core/module-graph.ts"() {
|
|
789
835
|
"use strict";
|
|
836
|
+
init_url();
|
|
790
837
|
ModuleGraph = class {
|
|
838
|
+
environmentName;
|
|
791
839
|
urlToModuleMap = /* @__PURE__ */ new Map();
|
|
792
840
|
idToModuleMap = /* @__PURE__ */ new Map();
|
|
793
841
|
fileToModulesMap = /* @__PURE__ */ new Map();
|
|
842
|
+
constructor(environmentName = "client") {
|
|
843
|
+
this.environmentName = environmentName;
|
|
844
|
+
}
|
|
794
845
|
getModuleByUrl(url) {
|
|
795
|
-
return this.urlToModuleMap.get(url);
|
|
846
|
+
return this.urlToModuleMap.get(removeTimestampQuery(url));
|
|
796
847
|
}
|
|
797
848
|
getModuleById(id) {
|
|
798
849
|
return this.idToModuleMap.get(id);
|
|
@@ -801,10 +852,11 @@ var init_module_graph = __esm({
|
|
|
801
852
|
return this.fileToModulesMap.get(file);
|
|
802
853
|
}
|
|
803
854
|
async ensureEntryFromUrl(url) {
|
|
804
|
-
|
|
855
|
+
const normalizedUrl = removeTimestampQuery(url);
|
|
856
|
+
let mod = this.urlToModuleMap.get(normalizedUrl);
|
|
805
857
|
if (mod) return mod;
|
|
806
|
-
mod = this.createModule(
|
|
807
|
-
this.urlToModuleMap.set(
|
|
858
|
+
mod = this.createModule(normalizedUrl);
|
|
859
|
+
this.urlToModuleMap.set(normalizedUrl, mod);
|
|
808
860
|
return mod;
|
|
809
861
|
}
|
|
810
862
|
createModule(url, id) {
|
|
@@ -818,7 +870,9 @@ var init_module_graph = __esm({
|
|
|
818
870
|
acceptedHmrDeps: /* @__PURE__ */ new Set(),
|
|
819
871
|
transformResult: null,
|
|
820
872
|
lastHMRTimestamp: 0,
|
|
821
|
-
|
|
873
|
+
invalidationVersion: 0,
|
|
874
|
+
isSelfAccepting: false,
|
|
875
|
+
environment: this.environmentName
|
|
822
876
|
};
|
|
823
877
|
this.idToModuleMap.set(mod.id, mod);
|
|
824
878
|
return mod;
|
|
@@ -860,10 +914,64 @@ var init_module_graph = __esm({
|
|
|
860
914
|
}
|
|
861
915
|
}
|
|
862
916
|
}
|
|
917
|
+
/**
|
|
918
|
+
* 用一次转换得到的信息原子更新 import 与 HMR accept 关系。
|
|
919
|
+
* 依赖节点会在真正被浏览器请求前预先创建,这样入口模块先转换时也能建立完整图。
|
|
920
|
+
*/
|
|
921
|
+
async updateModuleInfo(mod, importedUrls, acceptedUrls, isSelfAccepting, expectedInvalidationVersion) {
|
|
922
|
+
const importedModules = await Promise.all(
|
|
923
|
+
[...importedUrls].map((url) => this.ensureEntryFromUrl(url))
|
|
924
|
+
);
|
|
925
|
+
const acceptedModules = await Promise.all(
|
|
926
|
+
[...acceptedUrls].map((url) => this.ensureEntryFromUrl(url))
|
|
927
|
+
);
|
|
928
|
+
if (expectedInvalidationVersion !== void 0 && mod.invalidationVersion !== expectedInvalidationVersion) {
|
|
929
|
+
return null;
|
|
930
|
+
}
|
|
931
|
+
const previousImports = new Set(mod.importedModules);
|
|
932
|
+
for (const imported of previousImports) {
|
|
933
|
+
imported.importers.delete(mod);
|
|
934
|
+
}
|
|
935
|
+
mod.importedModules.clear();
|
|
936
|
+
mod.acceptedHmrDeps.clear();
|
|
937
|
+
for (const imported of importedModules) {
|
|
938
|
+
mod.importedModules.add(imported);
|
|
939
|
+
imported.importers.add(mod);
|
|
940
|
+
}
|
|
941
|
+
for (const accepted of acceptedModules) {
|
|
942
|
+
mod.acceptedHmrDeps.add(accepted);
|
|
943
|
+
}
|
|
944
|
+
mod.isSelfAccepting = isSelfAccepting;
|
|
945
|
+
const pruned = /* @__PURE__ */ new Set();
|
|
946
|
+
for (const imported of previousImports) {
|
|
947
|
+
if (!mod.importedModules.has(imported) && imported.importers.size === 0) {
|
|
948
|
+
pruned.add(imported);
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
return pruned;
|
|
952
|
+
}
|
|
863
953
|
/** 使模块的转换缓存失效 */
|
|
864
|
-
invalidateModule(mod) {
|
|
954
|
+
invalidateModule(mod, timestamp = Date.now()) {
|
|
865
955
|
mod.transformResult = null;
|
|
866
|
-
mod.lastHMRTimestamp =
|
|
956
|
+
mod.lastHMRTimestamp = timestamp;
|
|
957
|
+
mod.invalidationVersion++;
|
|
958
|
+
}
|
|
959
|
+
/**
|
|
960
|
+
* 仅失效到 HMR 边界:显式接受依赖的模块本身不会重执行;自接受模块需要失效,
|
|
961
|
+
* 但不再继续影响其 importer。这样既能传播依赖时间戳,也不会隐式重复副作用。
|
|
962
|
+
*/
|
|
963
|
+
invalidateModuleAndImporters(mod, timestamp = Date.now(), seen = /* @__PURE__ */ new Set()) {
|
|
964
|
+
if (seen.has(mod)) return;
|
|
965
|
+
seen.add(mod);
|
|
966
|
+
this.invalidateModule(mod, timestamp);
|
|
967
|
+
for (const importer of mod.importers) {
|
|
968
|
+
if (importer.acceptedHmrDeps.has(mod)) continue;
|
|
969
|
+
if (importer.isSelfAccepting) {
|
|
970
|
+
this.invalidateModule(importer, timestamp);
|
|
971
|
+
continue;
|
|
972
|
+
}
|
|
973
|
+
this.invalidateModuleAndImporters(importer, timestamp, seen);
|
|
974
|
+
}
|
|
867
975
|
}
|
|
868
976
|
/** 使所有模块缓存失效 */
|
|
869
977
|
invalidateAll() {
|
|
@@ -874,34 +982,32 @@ var init_module_graph = __esm({
|
|
|
874
982
|
/** 获取 HMR 传播边界 - 从变更模块向上遍历找到接受更新的边界 */
|
|
875
983
|
getHmrBoundaries(mod) {
|
|
876
984
|
const boundaries = [];
|
|
877
|
-
const
|
|
878
|
-
const
|
|
879
|
-
if (
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
boundaries.push({ boundary
|
|
883
|
-
return true;
|
|
985
|
+
const traversed = /* @__PURE__ */ new Set();
|
|
986
|
+
const addBoundary = (boundary, acceptedVia) => {
|
|
987
|
+
if (!boundaries.some(
|
|
988
|
+
(item) => item.boundary === boundary && item.acceptedVia === acceptedVia
|
|
989
|
+
)) {
|
|
990
|
+
boundaries.push({ boundary, acceptedVia });
|
|
884
991
|
}
|
|
885
|
-
|
|
886
|
-
|
|
992
|
+
};
|
|
993
|
+
const propagate = (node) => {
|
|
994
|
+
if (traversed.has(node)) return true;
|
|
995
|
+
traversed.add(node);
|
|
996
|
+
if (node.isSelfAccepting) {
|
|
997
|
+
addBoundary(node, node);
|
|
887
998
|
return true;
|
|
888
999
|
}
|
|
889
1000
|
if (node.importers.size === 0) return false;
|
|
890
1001
|
for (const importer of node.importers) {
|
|
891
|
-
if (
|
|
1002
|
+
if (importer.acceptedHmrDeps.has(node)) {
|
|
1003
|
+
addBoundary(importer, node);
|
|
1004
|
+
continue;
|
|
1005
|
+
}
|
|
1006
|
+
if (!propagate(importer)) return false;
|
|
892
1007
|
}
|
|
893
1008
|
return true;
|
|
894
1009
|
};
|
|
895
|
-
|
|
896
|
-
boundaries.push({ boundary: mod, acceptedVia: mod });
|
|
897
|
-
return boundaries;
|
|
898
|
-
}
|
|
899
|
-
for (const importer of mod.importers) {
|
|
900
|
-
if (!propagate(importer, mod)) {
|
|
901
|
-
return [];
|
|
902
|
-
}
|
|
903
|
-
}
|
|
904
|
-
return boundaries;
|
|
1010
|
+
return propagate(mod) ? boundaries : [];
|
|
905
1011
|
}
|
|
906
1012
|
};
|
|
907
1013
|
}
|
|
@@ -924,12 +1030,12 @@ function createNoopHotChannel() {
|
|
|
924
1030
|
}
|
|
925
1031
|
};
|
|
926
1032
|
}
|
|
927
|
-
function createWsHotChannel(ws) {
|
|
1033
|
+
function createWsHotChannel(ws, environmentName = "client") {
|
|
928
1034
|
const listeners = /* @__PURE__ */ new Map();
|
|
929
1035
|
let invokeHandlers;
|
|
930
1036
|
return {
|
|
931
1037
|
send(payload) {
|
|
932
|
-
ws.send(payload);
|
|
1038
|
+
ws.send({ ...payload, environment: payload.environment ?? environmentName });
|
|
933
1039
|
},
|
|
934
1040
|
on(event, listener) {
|
|
935
1041
|
let set = listeners.get(event);
|
|
@@ -941,8 +1047,8 @@ function createWsHotChannel(ws) {
|
|
|
941
1047
|
},
|
|
942
1048
|
listen() {
|
|
943
1049
|
},
|
|
1050
|
+
// 多个 environment 共享底层 WebSocket server;它由 DevServer.close() 统一关闭。
|
|
944
1051
|
close() {
|
|
945
|
-
ws.close();
|
|
946
1052
|
},
|
|
947
1053
|
setInvokeHandler(handlers) {
|
|
948
1054
|
invokeHandlers = handlers;
|
|
@@ -1040,6 +1146,10 @@ var init_environment = __esm({
|
|
|
1040
1146
|
moduleGraph;
|
|
1041
1147
|
candidatePlugins;
|
|
1042
1148
|
pluginApi;
|
|
1149
|
+
buildMetadata = {};
|
|
1150
|
+
cssModules = /* @__PURE__ */ new Map();
|
|
1151
|
+
assetModules = /* @__PURE__ */ new Map();
|
|
1152
|
+
transformRequestHandler;
|
|
1043
1153
|
initialized = false;
|
|
1044
1154
|
constructor(name, config, init = {}) {
|
|
1045
1155
|
const options = config.environments[name];
|
|
@@ -1054,7 +1164,7 @@ var init_environment = __esm({
|
|
|
1054
1164
|
this.config = config;
|
|
1055
1165
|
this.options = options;
|
|
1056
1166
|
this.hot = init.hot ?? createNoopHotChannel();
|
|
1057
|
-
this.moduleGraph = new ModuleGraph();
|
|
1167
|
+
this.moduleGraph = new ModuleGraph(name);
|
|
1058
1168
|
this.candidatePlugins = init.plugins ?? config.plugins;
|
|
1059
1169
|
this.pluginApi = init.pluginApi ?? getPluginApi(config);
|
|
1060
1170
|
}
|
|
@@ -1096,6 +1206,53 @@ var init_environment = __esm({
|
|
|
1096
1206
|
logger: this.config.logger
|
|
1097
1207
|
};
|
|
1098
1208
|
}
|
|
1209
|
+
configureDevPipeline(transformRequest2) {
|
|
1210
|
+
this.transformRequestHandler = transformRequest2;
|
|
1211
|
+
}
|
|
1212
|
+
async transformRequest(url) {
|
|
1213
|
+
if (!this.transformRequestHandler) {
|
|
1214
|
+
throw new Error(
|
|
1215
|
+
`[nasti] environment "${this.name}" does not have an initialized dev transform pipeline`
|
|
1216
|
+
);
|
|
1217
|
+
}
|
|
1218
|
+
return this.transformRequestHandler(url);
|
|
1219
|
+
}
|
|
1220
|
+
setCssModule(module2) {
|
|
1221
|
+
this.cssModules.set(module2.id, { ...module2 });
|
|
1222
|
+
}
|
|
1223
|
+
getCssModule(id) {
|
|
1224
|
+
const module2 = this.cssModules.get(id);
|
|
1225
|
+
return module2 ? { ...module2 } : void 0;
|
|
1226
|
+
}
|
|
1227
|
+
getCssModules() {
|
|
1228
|
+
return Object.freeze(
|
|
1229
|
+
Object.fromEntries(
|
|
1230
|
+
[...this.cssModules].map(([id, module2]) => [id, { ...module2 }])
|
|
1231
|
+
)
|
|
1232
|
+
);
|
|
1233
|
+
}
|
|
1234
|
+
setAssetModule(id, fileName) {
|
|
1235
|
+
this.assetModules.set(id, fileName);
|
|
1236
|
+
}
|
|
1237
|
+
getAssetModules() {
|
|
1238
|
+
return Object.freeze(Object.fromEntries(this.assetModules));
|
|
1239
|
+
}
|
|
1240
|
+
setBuildMetadata(metadata) {
|
|
1241
|
+
const { entries: currentEntries, ...currentMetadata } = this.buildMetadata;
|
|
1242
|
+
const { entries, ...nextMetadata } = metadata;
|
|
1243
|
+
this.buildMetadata = {
|
|
1244
|
+
...currentMetadata,
|
|
1245
|
+
...nextMetadata,
|
|
1246
|
+
...currentEntries || entries ? { entries: { ...currentEntries, ...entries } } : {}
|
|
1247
|
+
};
|
|
1248
|
+
}
|
|
1249
|
+
getBuildMetadata() {
|
|
1250
|
+
const { entries, ...metadata } = this.buildMetadata;
|
|
1251
|
+
return {
|
|
1252
|
+
...metadata,
|
|
1253
|
+
...entries ? { entries: { ...entries } } : {}
|
|
1254
|
+
};
|
|
1255
|
+
}
|
|
1099
1256
|
async close() {
|
|
1100
1257
|
try {
|
|
1101
1258
|
await this.driver?.close?.(this.getDriverContext());
|
|
@@ -1338,23 +1495,106 @@ var init_env = __esm({
|
|
|
1338
1495
|
}
|
|
1339
1496
|
});
|
|
1340
1497
|
|
|
1341
|
-
// src/
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1498
|
+
// src/plugins/assets.ts
|
|
1499
|
+
function assetsPlugin(config) {
|
|
1500
|
+
const emittedAssets = /* @__PURE__ */ new Set();
|
|
1501
|
+
return {
|
|
1502
|
+
name: "nasti:assets",
|
|
1503
|
+
resolveId(source) {
|
|
1504
|
+
if (source.endsWith("?url") || source.endsWith("?raw")) {
|
|
1505
|
+
return source;
|
|
1506
|
+
}
|
|
1507
|
+
return null;
|
|
1508
|
+
},
|
|
1509
|
+
load(id) {
|
|
1510
|
+
const ext = import_node_path4.default.extname(id.replace(/\?.*$/, ""));
|
|
1511
|
+
if (id.endsWith("?raw")) {
|
|
1512
|
+
const file = id.slice(0, -4);
|
|
1513
|
+
if (import_node_fs4.default.existsSync(file)) {
|
|
1514
|
+
const content = import_node_fs4.default.readFileSync(file, "utf-8");
|
|
1515
|
+
return `export default ${JSON.stringify(content)}`;
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
if (id.endsWith("?url") || ASSET_EXTENSIONS.has(ext)) {
|
|
1519
|
+
const file = id.replace(/\?.*$/, "");
|
|
1520
|
+
if (!import_node_fs4.default.existsSync(file)) return null;
|
|
1521
|
+
if (config.command === "serve") {
|
|
1522
|
+
const url = "/" + import_node_path4.default.relative(config.root, file);
|
|
1523
|
+
return `export default ${JSON.stringify(url)}`;
|
|
1524
|
+
}
|
|
1525
|
+
const content = import_node_fs4.default.readFileSync(file);
|
|
1526
|
+
const hash = import_node_crypto.default.createHash("sha256").update(content).digest("hex").slice(0, 8);
|
|
1527
|
+
const basename = import_node_path4.default.basename(file, ext);
|
|
1528
|
+
const hashedName = `${config.build.assetsDir}/${basename}.${hash}${ext}`;
|
|
1529
|
+
const environment = this.environment;
|
|
1530
|
+
if (!environment) {
|
|
1531
|
+
throw new Error("[nasti:assets] build environment is not initialized");
|
|
1532
|
+
}
|
|
1533
|
+
if (!emittedAssets.has(hashedName)) {
|
|
1534
|
+
this.emitFile({
|
|
1535
|
+
type: "asset",
|
|
1536
|
+
fileName: hashedName,
|
|
1537
|
+
source: content
|
|
1538
|
+
});
|
|
1539
|
+
emittedAssets.add(hashedName);
|
|
1540
|
+
}
|
|
1541
|
+
environment.setAssetModule(file, hashedName);
|
|
1542
|
+
return `export default ${JSON.stringify(config.base + hashedName)}`;
|
|
1543
|
+
}
|
|
1544
|
+
return null;
|
|
1545
|
+
}
|
|
1546
|
+
};
|
|
1547
|
+
}
|
|
1548
|
+
function isAssetFile(id) {
|
|
1549
|
+
const ext = import_node_path4.default.extname(id.replace(/\?.*$/, ""));
|
|
1550
|
+
return ASSET_EXTENSIONS.has(ext);
|
|
1551
|
+
}
|
|
1552
|
+
var import_node_path4, import_node_fs4, import_node_crypto, ASSET_EXTENSIONS;
|
|
1553
|
+
var init_assets = __esm({
|
|
1554
|
+
"src/plugins/assets.ts"() {
|
|
1555
|
+
"use strict";
|
|
1556
|
+
import_node_path4 = __toESM(require("path"), 1);
|
|
1557
|
+
import_node_fs4 = __toESM(require("fs"), 1);
|
|
1558
|
+
import_node_crypto = __toESM(require("crypto"), 1);
|
|
1559
|
+
ASSET_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
1560
|
+
".png",
|
|
1561
|
+
".jpg",
|
|
1562
|
+
".jpeg",
|
|
1563
|
+
".gif",
|
|
1564
|
+
".svg",
|
|
1565
|
+
".ico",
|
|
1566
|
+
".webp",
|
|
1567
|
+
".avif",
|
|
1568
|
+
".mp4",
|
|
1569
|
+
".webm",
|
|
1570
|
+
".ogg",
|
|
1571
|
+
".mp3",
|
|
1572
|
+
".wav",
|
|
1573
|
+
".flac",
|
|
1574
|
+
".aac",
|
|
1575
|
+
".woff",
|
|
1576
|
+
".woff2",
|
|
1577
|
+
".eot",
|
|
1578
|
+
".ttf",
|
|
1579
|
+
".otf",
|
|
1580
|
+
".pdf",
|
|
1581
|
+
".txt"
|
|
1582
|
+
]);
|
|
1583
|
+
}
|
|
1348
1584
|
});
|
|
1349
|
-
|
|
1350
|
-
|
|
1585
|
+
|
|
1586
|
+
// src/server/middleware.ts
|
|
1587
|
+
function getReactRefreshRuntimeEsm(includeBoundaryHelpers = false) {
|
|
1588
|
+
if (__refreshRuntimeCache) {
|
|
1589
|
+
return includeBoundaryHelpers ? __refreshRuntimeCache + REACT_REFRESH_BOUNDARY_HELPERS : __refreshRuntimeCache;
|
|
1590
|
+
}
|
|
1351
1591
|
let cjsPath;
|
|
1352
1592
|
try {
|
|
1353
1593
|
const pkgPath = __require.resolve("react-refresh/package.json");
|
|
1354
|
-
cjsPath =
|
|
1594
|
+
cjsPath = import_node_path5.default.join(import_node_path5.default.dirname(pkgPath), "cjs", "react-refresh-runtime.development.js");
|
|
1355
1595
|
} catch (err) {
|
|
1356
|
-
cjsPath =
|
|
1357
|
-
if (!
|
|
1596
|
+
cjsPath = import_node_path5.default.resolve(__dirname_esm, "../../node_modules/react-refresh/cjs/react-refresh-runtime.development.js");
|
|
1597
|
+
if (!import_node_fs5.default.existsSync(cjsPath)) {
|
|
1358
1598
|
const origMsg = err instanceof Error ? err.message : String(err);
|
|
1359
1599
|
throw new Error(
|
|
1360
1600
|
`[nasti] Missing dependency "react-refresh". Install it with: npm install react-refresh
|
|
@@ -1362,7 +1602,7 @@ Original resolve error: ${origMsg}`
|
|
|
1362
1602
|
);
|
|
1363
1603
|
}
|
|
1364
1604
|
}
|
|
1365
|
-
const cjsSource =
|
|
1605
|
+
const cjsSource = import_node_fs5.default.readFileSync(cjsPath, "utf-8");
|
|
1366
1606
|
__refreshRuntimeCache = `// Wrapped react-refresh runtime -> ESM
|
|
1367
1607
|
const exports = {};
|
|
1368
1608
|
const module = { exports };
|
|
@@ -1382,7 +1622,7 @@ export const findAffectedHostInstances = __rt.findAffectedHostInstances;
|
|
|
1382
1622
|
export const collectCustomHooksForSignature = __rt.collectCustomHooksForSignature;
|
|
1383
1623
|
export default __rt;
|
|
1384
1624
|
`;
|
|
1385
|
-
return __refreshRuntimeCache;
|
|
1625
|
+
return includeBoundaryHelpers ? __refreshRuntimeCache + REACT_REFRESH_BOUNDARY_HELPERS : __refreshRuntimeCache;
|
|
1386
1626
|
}
|
|
1387
1627
|
function buildReactRefreshWrapper(moduleUrl, transformedCode) {
|
|
1388
1628
|
const urlLit = JSON.stringify(moduleUrl);
|
|
@@ -1408,27 +1648,46 @@ window.$RefreshReg$ = prevRefreshReg;
|
|
|
1408
1648
|
window.$RefreshSig$ = prevRefreshSig;
|
|
1409
1649
|
|
|
1410
1650
|
if (__nasti_hot__) {
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1651
|
+
let __nasti_current_exports__;
|
|
1652
|
+
__nasti_hot__.accept((nextExports) => {
|
|
1653
|
+
if (!nextExports) return;
|
|
1654
|
+
if (!__nasti_current_exports__) {
|
|
1655
|
+
__nasti_hot__.invalidate('Could not Fast Refresh (previous exports unavailable)');
|
|
1656
|
+
return;
|
|
1657
|
+
}
|
|
1658
|
+
const invalidateMessage = RefreshRuntime.validateRefreshBoundaryAndEnqueueUpdate(
|
|
1659
|
+
${urlLit},
|
|
1660
|
+
__nasti_current_exports__,
|
|
1661
|
+
nextExports,
|
|
1662
|
+
);
|
|
1663
|
+
if (invalidateMessage) __nasti_hot__.invalidate(invalidateMessage);
|
|
1664
|
+
});
|
|
1665
|
+
RefreshRuntime.__hmr_import(import.meta.url).then((currentExports) => {
|
|
1666
|
+
__nasti_current_exports__ = currentExports;
|
|
1667
|
+
RefreshRuntime.registerExportsForReactRefresh(${urlLit}, currentExports);
|
|
1416
1668
|
});
|
|
1417
1669
|
}
|
|
1418
1670
|
`;
|
|
1419
1671
|
}
|
|
1420
1672
|
function injectImportMetaHot(code, moduleUrl) {
|
|
1421
|
-
|
|
1673
|
+
const hotRE = /\bimport\.meta\.hot\b/g;
|
|
1674
|
+
const matches = [...maskStringsAndComments(code).matchAll(hotRE)];
|
|
1675
|
+
if (matches.length === 0) return code;
|
|
1676
|
+
for (const match of matches.reverse()) {
|
|
1677
|
+
const start = match.index;
|
|
1678
|
+
code = code.slice(0, start) + "__nasti_hot__" + code.slice(start + match[0].length);
|
|
1679
|
+
}
|
|
1422
1680
|
const urlLit = JSON.stringify(moduleUrl);
|
|
1423
1681
|
const header = `import { createHotContext as __nasti_createHotContext__ } from "/@nasti/client";
|
|
1424
1682
|
const __nasti_hot__ = __nasti_createHotContext__(${urlLit});
|
|
1425
1683
|
`;
|
|
1426
|
-
return header + code
|
|
1684
|
+
return header + code;
|
|
1427
1685
|
}
|
|
1428
1686
|
function transformMiddleware(ctx) {
|
|
1429
1687
|
ctx.envDefine = buildEnvDefine(
|
|
1430
1688
|
loadEnv(ctx.config.mode, ctx.config.root, ctx.config.envPrefix),
|
|
1431
|
-
ctx.config.mode
|
|
1689
|
+
ctx.config.mode,
|
|
1690
|
+
ssrDefineOverrides(ctx.environment?.consumer ?? "client")
|
|
1432
1691
|
);
|
|
1433
1692
|
return async (req, res, next) => {
|
|
1434
1693
|
const url = req.url ?? "/";
|
|
@@ -1473,7 +1732,7 @@ function transformMiddleware(ctx) {
|
|
|
1473
1732
|
return;
|
|
1474
1733
|
}
|
|
1475
1734
|
}
|
|
1476
|
-
if (isModuleRequest(url)) {
|
|
1735
|
+
if (isModuleRequest(url, req.headers["sec-fetch-dest"])) {
|
|
1477
1736
|
try {
|
|
1478
1737
|
const result = await transformRequest(url, ctx);
|
|
1479
1738
|
if (result) {
|
|
@@ -1499,13 +1758,14 @@ function transformMiddleware(ctx) {
|
|
|
1499
1758
|
}
|
|
1500
1759
|
async function transformRequest(url, ctx) {
|
|
1501
1760
|
const { config, pluginContainer, moduleGraph } = ctx;
|
|
1761
|
+
url = removeTimestampQuery(url);
|
|
1502
1762
|
const cleanReqUrl = url.split("?")[0];
|
|
1503
1763
|
const cached2 = moduleGraph.getModuleByUrl(url);
|
|
1504
1764
|
if (cached2?.transformResult) {
|
|
1505
1765
|
return cached2.transformResult;
|
|
1506
1766
|
}
|
|
1507
1767
|
if (cleanReqUrl === "/@react-refresh") {
|
|
1508
|
-
return { code: getReactRefreshRuntimeEsm() };
|
|
1768
|
+
return { code: getReactRefreshRuntimeEsm(true) };
|
|
1509
1769
|
}
|
|
1510
1770
|
if (cleanReqUrl.startsWith("/@modules/") && url.includes("?")) {
|
|
1511
1771
|
const idParam = new URLSearchParams(url.slice(url.indexOf("?") + 1)).get("id");
|
|
@@ -1513,8 +1773,8 @@ async function transformRequest(url, ctx) {
|
|
|
1513
1773
|
let realIdValid = false;
|
|
1514
1774
|
try {
|
|
1515
1775
|
if (idParam) {
|
|
1516
|
-
realId =
|
|
1517
|
-
realIdValid =
|
|
1776
|
+
realId = import_node_fs5.default.realpathSync(idParam);
|
|
1777
|
+
realIdValid = import_node_fs5.default.statSync(realId).isFile() && (realId.includes(`${import_node_path5.default.sep}node_modules${import_node_path5.default.sep}`) || isUnderRoot(realId, config.root));
|
|
1518
1778
|
}
|
|
1519
1779
|
} catch {
|
|
1520
1780
|
realId = null;
|
|
@@ -1541,40 +1801,63 @@ async function transformRequest(url, ctx) {
|
|
|
1541
1801
|
}
|
|
1542
1802
|
const rawQuery = url.includes("?") ? url.slice(url.indexOf("?") + 1) : "";
|
|
1543
1803
|
if (rawQuery && !/^t=\d+$/.test(rawQuery)) {
|
|
1544
|
-
const
|
|
1545
|
-
|
|
1546
|
-
|
|
1804
|
+
const mod2 = await moduleGraph.ensureEntryFromUrl(url);
|
|
1805
|
+
const transformVersion2 = mod2.invalidationVersion;
|
|
1806
|
+
const loaded2 = await pluginContainer.load(url);
|
|
1807
|
+
if (loaded2 != null) {
|
|
1808
|
+
let code2 = typeof loaded2 === "string" ? loaded2 : loaded2.code;
|
|
1809
|
+
let map2 = typeof loaded2 === "string" ? void 0 : loaded2.map;
|
|
1547
1810
|
const transformed = await pluginContainer.transform(code2, url);
|
|
1548
1811
|
if (transformed != null) {
|
|
1549
1812
|
code2 = typeof transformed === "string" ? transformed : transformed.code;
|
|
1813
|
+
if (typeof transformed !== "string" && transformed.map != null) {
|
|
1814
|
+
map2 = transformed.map;
|
|
1815
|
+
}
|
|
1550
1816
|
}
|
|
1551
|
-
const
|
|
1552
|
-
moduleGraph.registerModule(mod2,
|
|
1553
|
-
|
|
1817
|
+
const parentFile = resolveUrlToFile(cleanReqUrl, config.root) ?? cleanReqUrl;
|
|
1818
|
+
moduleGraph.registerModule(mod2, parentFile);
|
|
1819
|
+
const hotInfo2 = rewriteHotAcceptDeps(code2, config, parentFile);
|
|
1820
|
+
code2 = injectImportMetaHot(hotInfo2.code, url);
|
|
1554
1821
|
code2 = replaceEnvInCode(code2, ctx.envDefine ?? buildEnvDefine(
|
|
1555
1822
|
loadEnv(config.mode, config.root, config.envPrefix),
|
|
1556
|
-
config.mode
|
|
1823
|
+
config.mode,
|
|
1824
|
+
ssrDefineOverrides(ctx.environment?.consumer ?? "client")
|
|
1557
1825
|
));
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1826
|
+
const importedUrls2 = /* @__PURE__ */ new Set();
|
|
1827
|
+
code2 = rewriteImports(code2, config, parentFile, importedUrls2, moduleGraph);
|
|
1828
|
+
const pruned2 = await moduleGraph.updateModuleInfo(
|
|
1829
|
+
mod2,
|
|
1830
|
+
importedUrls2,
|
|
1831
|
+
hotInfo2.acceptedUrls,
|
|
1832
|
+
hotInfo2.isSelfAccepting,
|
|
1833
|
+
transformVersion2
|
|
1834
|
+
);
|
|
1835
|
+
const transformResult2 = { code: code2, map: map2 };
|
|
1836
|
+
if (pruned2) {
|
|
1837
|
+
if (pruned2.size > 0) ctx.onPrune?.([...pruned2].map((item) => item.url));
|
|
1838
|
+
mod2.transformResult = transformResult2;
|
|
1839
|
+
}
|
|
1561
1840
|
return transformResult2;
|
|
1562
1841
|
}
|
|
1563
1842
|
}
|
|
1564
1843
|
const filePath = resolveUrlToFile(url, config.root);
|
|
1565
|
-
if (!filePath || !
|
|
1844
|
+
if (!filePath || !import_node_fs5.default.existsSync(filePath)) return null;
|
|
1566
1845
|
const mod = await moduleGraph.ensureEntryFromUrl(url);
|
|
1567
1846
|
moduleGraph.registerModule(mod, filePath);
|
|
1847
|
+
const transformVersion = mod.invalidationVersion;
|
|
1568
1848
|
if (cleanReqUrl.startsWith("/@modules/")) {
|
|
1569
1849
|
const code2 = await bundlePackageAsEsm(filePath, config.root);
|
|
1570
1850
|
const transformResult2 = { code: code2 };
|
|
1571
1851
|
mod.transformResult = transformResult2;
|
|
1572
1852
|
return transformResult2;
|
|
1573
1853
|
}
|
|
1574
|
-
|
|
1854
|
+
const loaded = await pluginContainer.load(filePath);
|
|
1855
|
+
let code = loaded == null ? import_node_fs5.default.readFileSync(filePath, "utf-8") : typeof loaded === "string" ? loaded : loaded.code;
|
|
1856
|
+
let map = loaded && typeof loaded !== "string" ? loaded.map : void 0;
|
|
1575
1857
|
const pluginResult = await pluginContainer.transform(code, filePath);
|
|
1576
1858
|
if (pluginResult) {
|
|
1577
1859
|
code = typeof pluginResult === "string" ? pluginResult : pluginResult.code;
|
|
1860
|
+
if (typeof pluginResult !== "string") map = pluginResult.map;
|
|
1578
1861
|
}
|
|
1579
1862
|
const stableUrl = cleanReqUrl;
|
|
1580
1863
|
let wrappedWithRefresh = false;
|
|
@@ -1585,26 +1868,41 @@ async function transformRequest(url, ctx) {
|
|
|
1585
1868
|
sourcemap: true,
|
|
1586
1869
|
jsxRuntime: "automatic",
|
|
1587
1870
|
jsxImportSource: config.framework === "vue" ? "vue" : "react",
|
|
1588
|
-
reactRefresh: useRefresh
|
|
1871
|
+
reactRefresh: useRefresh,
|
|
1872
|
+
target: ctx.environment?.options.build.target ?? config.build.target
|
|
1589
1873
|
});
|
|
1590
1874
|
code = result.code;
|
|
1875
|
+
if (result.map) map = JSON.parse(result.map);
|
|
1591
1876
|
if (useRefresh) {
|
|
1592
1877
|
code = buildReactRefreshWrapper(stableUrl, code);
|
|
1593
1878
|
wrappedWithRefresh = true;
|
|
1594
|
-
mod.isSelfAccepting = true;
|
|
1595
1879
|
}
|
|
1596
1880
|
}
|
|
1881
|
+
const hotInfo = rewriteHotAcceptDeps(code, config, filePath);
|
|
1882
|
+
code = hotInfo.code;
|
|
1597
1883
|
if (!wrappedWithRefresh) {
|
|
1598
1884
|
code = injectImportMetaHot(code, stableUrl);
|
|
1599
1885
|
}
|
|
1600
1886
|
const envDefine = ctx.envDefine ?? buildEnvDefine(
|
|
1601
1887
|
loadEnv(config.mode, config.root, config.envPrefix),
|
|
1602
|
-
config.mode
|
|
1888
|
+
config.mode,
|
|
1889
|
+
ssrDefineOverrides(ctx.environment?.consumer ?? "client")
|
|
1603
1890
|
);
|
|
1604
1891
|
code = replaceEnvInCode(code, envDefine);
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1892
|
+
const importedUrls = /* @__PURE__ */ new Set();
|
|
1893
|
+
code = rewriteImports(code, config, filePath, importedUrls, moduleGraph);
|
|
1894
|
+
const pruned = await moduleGraph.updateModuleInfo(
|
|
1895
|
+
mod,
|
|
1896
|
+
importedUrls,
|
|
1897
|
+
hotInfo.acceptedUrls,
|
|
1898
|
+
wrappedWithRefresh || hotInfo.isSelfAccepting,
|
|
1899
|
+
transformVersion
|
|
1900
|
+
);
|
|
1901
|
+
const transformResult = { code, map };
|
|
1902
|
+
if (pruned) {
|
|
1903
|
+
if (pruned.size > 0) ctx.onPrune?.([...pruned].map((item) => item.url));
|
|
1904
|
+
mod.transformResult = transformResult;
|
|
1905
|
+
}
|
|
1608
1906
|
return transformResult;
|
|
1609
1907
|
}
|
|
1610
1908
|
async function loadVirtualModule(spec, ctx) {
|
|
@@ -1612,7 +1910,7 @@ async function loadVirtualModule(spec, ctx) {
|
|
|
1612
1910
|
const resolved = await pluginContainer.resolveId(spec);
|
|
1613
1911
|
if (resolved == null) return null;
|
|
1614
1912
|
const resolvedId = typeof resolved === "string" ? resolved : resolved.id;
|
|
1615
|
-
const looksVirtual = resolvedId.startsWith("\0") || !
|
|
1913
|
+
const looksVirtual = resolvedId.startsWith("\0") || !import_node_fs5.default.existsSync(resolvedId);
|
|
1616
1914
|
if (!looksVirtual) return null;
|
|
1617
1915
|
const loadResult = await pluginContainer.load(resolvedId);
|
|
1618
1916
|
if (loadResult == null) return null;
|
|
@@ -1623,9 +1921,10 @@ async function loadVirtualModule(spec, ctx) {
|
|
|
1623
1921
|
}
|
|
1624
1922
|
code = replaceEnvInCode(code, ctx.envDefine ?? buildEnvDefine(
|
|
1625
1923
|
loadEnv(config.mode, config.root, config.envPrefix),
|
|
1626
|
-
config.mode
|
|
1924
|
+
config.mode,
|
|
1925
|
+
ssrDefineOverrides(ctx.environment?.consumer ?? "client")
|
|
1627
1926
|
));
|
|
1628
|
-
const anchor =
|
|
1927
|
+
const anchor = import_node_path5.default.join(config.root, "__nasti_virtual__.ts");
|
|
1629
1928
|
code = rewriteImports(code, config, anchor);
|
|
1630
1929
|
return { id: resolvedId, result: { code } };
|
|
1631
1930
|
}
|
|
@@ -1651,7 +1950,7 @@ async function doBundlePackage(entryFile, root) {
|
|
|
1651
1950
|
await bundle2.close();
|
|
1652
1951
|
let code = result.output[0].code;
|
|
1653
1952
|
code = code.replace(/process\.env\.NODE_ENV/g, '"development"');
|
|
1654
|
-
const externalBaseDir =
|
|
1953
|
+
const externalBaseDir = import_node_path5.default.dirname(entryFile);
|
|
1655
1954
|
code = code.replace(
|
|
1656
1955
|
/^(import\b[^;'"]*?\bfrom\s+)(['"])([^'"./][^'"]*)(\2)/gm,
|
|
1657
1956
|
(_, prefix, q, spec) => `${prefix}${q}${externalSpecToModuleUrl(spec, externalBaseDir, root)}${q}`
|
|
@@ -1669,16 +1968,16 @@ async function doBundlePackage(entryFile, root) {
|
|
|
1669
1968
|
return code;
|
|
1670
1969
|
}
|
|
1671
1970
|
async function tryGenerateSubpathShim(entryFile, root) {
|
|
1672
|
-
const NM = `${
|
|
1971
|
+
const NM = `${import_node_path5.default.sep}node_modules${import_node_path5.default.sep}`;
|
|
1673
1972
|
if (!entryFile.includes(NM)) return null;
|
|
1674
1973
|
let pkgDir = null;
|
|
1675
1974
|
let pkgName = null;
|
|
1676
|
-
let dir =
|
|
1975
|
+
let dir = import_node_path5.default.dirname(entryFile);
|
|
1677
1976
|
while (true) {
|
|
1678
|
-
const pkgJsonPath =
|
|
1679
|
-
if (
|
|
1977
|
+
const pkgJsonPath = import_node_path5.default.join(dir, "package.json");
|
|
1978
|
+
if (import_node_fs5.default.existsSync(pkgJsonPath)) {
|
|
1680
1979
|
try {
|
|
1681
|
-
const pkg = JSON.parse(
|
|
1980
|
+
const pkg = JSON.parse(import_node_fs5.default.readFileSync(pkgJsonPath, "utf-8"));
|
|
1682
1981
|
if (typeof pkg?.name === "string" && pkg.name) {
|
|
1683
1982
|
pkgDir = dir;
|
|
1684
1983
|
pkgName = pkg.name;
|
|
@@ -1687,16 +1986,16 @@ async function tryGenerateSubpathShim(entryFile, root) {
|
|
|
1687
1986
|
} catch {
|
|
1688
1987
|
}
|
|
1689
1988
|
}
|
|
1690
|
-
const parent =
|
|
1989
|
+
const parent = import_node_path5.default.dirname(dir);
|
|
1691
1990
|
if (parent === dir) return null;
|
|
1692
1991
|
dir = parent;
|
|
1693
1992
|
if (!dir.includes(NM)) return null;
|
|
1694
1993
|
}
|
|
1695
1994
|
if (!pkgDir || !pkgName) return null;
|
|
1696
|
-
const entryExt =
|
|
1995
|
+
const entryExt = import_node_path5.default.extname(entryFile);
|
|
1697
1996
|
const mainEntry = pickMainEntryByExtension(pkgDir, entryExt);
|
|
1698
1997
|
if (!mainEntry) return null;
|
|
1699
|
-
if (
|
|
1998
|
+
if (import_node_path5.default.resolve(mainEntry) === import_node_path5.default.resolve(entryFile)) return null;
|
|
1700
1999
|
let mainNs;
|
|
1701
2000
|
let subNs;
|
|
1702
2001
|
try {
|
|
@@ -1720,7 +2019,7 @@ async function tryGenerateSubpathShim(entryFile, root) {
|
|
|
1720
2019
|
if (mainNs["default"] !== subNs["default"]) return null;
|
|
1721
2020
|
}
|
|
1722
2021
|
const rootMain = resolveNodeModule(root, pkgName);
|
|
1723
|
-
const mainEntryUrl = rootMain && rootMain.startsWith(pkgDir +
|
|
2022
|
+
const mainEntryUrl = rootMain && rootMain.startsWith(pkgDir + import_node_path5.default.sep) ? `/@modules/${pkgName}` : `/@modules/${pkgName}?id=${encodeURIComponent(mainEntry)}`;
|
|
1724
2023
|
const lines = [
|
|
1725
2024
|
`// Nasti subpath shim \u2192 ${pkgName} (avoid duplicate bundling)`,
|
|
1726
2025
|
`import * as __pkg from "${mainEntryUrl}";`
|
|
@@ -1734,10 +2033,10 @@ async function tryGenerateSubpathShim(entryFile, root) {
|
|
|
1734
2033
|
return lines.join("\n") + "\n";
|
|
1735
2034
|
}
|
|
1736
2035
|
function pickMainEntryByExtension(pkgDir, preferredExt) {
|
|
1737
|
-
const pkgJsonPath =
|
|
2036
|
+
const pkgJsonPath = import_node_path5.default.join(pkgDir, "package.json");
|
|
1738
2037
|
let pkg;
|
|
1739
2038
|
try {
|
|
1740
|
-
pkg = JSON.parse(
|
|
2039
|
+
pkg = JSON.parse(import_node_fs5.default.readFileSync(pkgJsonPath, "utf-8"));
|
|
1741
2040
|
} catch {
|
|
1742
2041
|
return null;
|
|
1743
2042
|
}
|
|
@@ -1756,14 +2055,14 @@ function pickMainEntryByExtension(pkgDir, preferredExt) {
|
|
|
1756
2055
|
if (typeof pkg.module === "string") candidates.push(pkg.module);
|
|
1757
2056
|
if (typeof pkg.main === "string") candidates.push(pkg.main);
|
|
1758
2057
|
for (const cand of candidates) {
|
|
1759
|
-
if (
|
|
1760
|
-
const full =
|
|
1761
|
-
if (
|
|
2058
|
+
if (import_node_path5.default.extname(cand) === preferredExt) {
|
|
2059
|
+
const full = import_node_path5.default.resolve(pkgDir, cand);
|
|
2060
|
+
if (import_node_fs5.default.existsSync(full)) return full;
|
|
1762
2061
|
}
|
|
1763
2062
|
}
|
|
1764
2063
|
for (const cand of candidates) {
|
|
1765
|
-
const full =
|
|
1766
|
-
if (
|
|
2064
|
+
const full = import_node_path5.default.resolve(pkgDir, cand);
|
|
2065
|
+
if (import_node_fs5.default.existsSync(full)) return full;
|
|
1767
2066
|
}
|
|
1768
2067
|
return null;
|
|
1769
2068
|
}
|
|
@@ -1809,72 +2108,231 @@ async function injectCjsNamedExports(code, entryFile) {
|
|
|
1809
2108
|
return code;
|
|
1810
2109
|
}
|
|
1811
2110
|
}
|
|
1812
|
-
function rewriteImports(code, config, filePath) {
|
|
2111
|
+
function rewriteImports(code, config, filePath, importedUrls, moduleGraph) {
|
|
2112
|
+
const resolveSpec = createModuleSpecifierResolver(config, filePath);
|
|
2113
|
+
const transformSpec = (spec) => {
|
|
2114
|
+
const resolved = removeTimestampQuery(resolveSpec(spec));
|
|
2115
|
+
importedUrls?.add(resolved);
|
|
2116
|
+
const timestamp = moduleGraph?.getModuleByUrl(resolved)?.lastHMRTimestamp ?? 0;
|
|
2117
|
+
return timestamp > 0 ? appendTimestampQuery(resolved, timestamp) : resolved;
|
|
2118
|
+
};
|
|
2119
|
+
return code.replace(
|
|
2120
|
+
/\bfrom\s+(['"])([^'"]+)\1/g,
|
|
2121
|
+
(_m, q, s) => `from ${q}${transformSpec(s)}${q}`
|
|
2122
|
+
).replace(
|
|
2123
|
+
/\bimport\s+(['"])([^'"]+)\1/g,
|
|
2124
|
+
(_m, q, s) => `import ${q}${transformSpec(s)}${q}`
|
|
2125
|
+
).replace(
|
|
2126
|
+
/\bimport\s*\(\s*(['"])([^'"]+)\1\s*\)/g,
|
|
2127
|
+
(_m, q, s) => `import(${q}${transformSpec(s)}${q})`
|
|
2128
|
+
);
|
|
2129
|
+
}
|
|
2130
|
+
function createModuleSpecifierResolver(config, filePath) {
|
|
1813
2131
|
const root = config.root;
|
|
1814
|
-
const fileDir =
|
|
2132
|
+
const fileDir = import_node_path5.default.dirname(filePath);
|
|
1815
2133
|
const aliasEntries = Object.entries(config.resolve.alias).sort(
|
|
1816
2134
|
([a], [b]) => b.length - a.length
|
|
1817
2135
|
);
|
|
1818
|
-
const toRootUrl = (abs) => "/" +
|
|
1819
|
-
|
|
1820
|
-
const suffixMatch =
|
|
2136
|
+
const toRootUrl = (abs) => "/" + import_node_path5.default.relative(root, abs).replace(/\\/g, "/");
|
|
2137
|
+
return (specifier) => {
|
|
2138
|
+
const suffixMatch = specifier.match(/[?#].*$/);
|
|
1821
2139
|
const suffix = suffixMatch ? suffixMatch[0] : "";
|
|
1822
|
-
const baseSpec = suffix ?
|
|
2140
|
+
const baseSpec = suffix ? specifier.slice(0, -suffix.length) : specifier;
|
|
1823
2141
|
for (const [key, value] of aliasEntries) {
|
|
1824
2142
|
if (baseSpec === key || baseSpec.startsWith(key + "/")) {
|
|
1825
2143
|
const aliasBase = resolveAliasTarget(value, root);
|
|
1826
2144
|
const sub = baseSpec.slice(key.length).replace(/^\//, "");
|
|
1827
|
-
const target = sub ?
|
|
2145
|
+
const target = sub ? import_node_path5.default.join(aliasBase, sub) : aliasBase;
|
|
1828
2146
|
const resolved = tryResolveDiskPath(target);
|
|
1829
|
-
return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix :
|
|
2147
|
+
return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix : specifier;
|
|
1830
2148
|
}
|
|
1831
2149
|
}
|
|
1832
2150
|
if (baseSpec.startsWith("./") || baseSpec.startsWith("../")) {
|
|
1833
|
-
const
|
|
1834
|
-
|
|
1835
|
-
return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix : spec;
|
|
2151
|
+
const resolved = tryResolveDiskPath(import_node_path5.default.resolve(fileDir, baseSpec));
|
|
2152
|
+
return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix : specifier;
|
|
1836
2153
|
}
|
|
1837
2154
|
if (baseSpec.startsWith("/") && !baseSpec.startsWith("/@")) {
|
|
1838
|
-
const
|
|
1839
|
-
|
|
1840
|
-
return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix : spec;
|
|
2155
|
+
const resolved = tryResolveDiskPath(import_node_path5.default.join(root, baseSpec.replace(/^\//, "")));
|
|
2156
|
+
return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix : specifier;
|
|
1841
2157
|
}
|
|
1842
|
-
if (baseSpec.startsWith("/")) return
|
|
1843
|
-
return `/@modules/${
|
|
2158
|
+
if (baseSpec.startsWith("/")) return specifier;
|
|
2159
|
+
return `/@modules/${specifier}`;
|
|
1844
2160
|
};
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
)
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
)
|
|
2161
|
+
}
|
|
2162
|
+
function rewriteHotAcceptDeps(code, config, filePath) {
|
|
2163
|
+
const acceptedUrls = /* @__PURE__ */ new Set();
|
|
2164
|
+
const edits = [];
|
|
2165
|
+
const resolveSpec = createModuleSpecifierResolver(config, filePath);
|
|
2166
|
+
const acceptRE = /(?:\bimport\.meta\.hot|\b__nasti_hot__)(?:(?:\?\.)|\.)accept\s*\(/g;
|
|
2167
|
+
const searchableCode = maskStringsAndComments(code);
|
|
2168
|
+
let isSelfAccepting = false;
|
|
2169
|
+
let match;
|
|
2170
|
+
while (match = acceptRE.exec(searchableCode)) {
|
|
2171
|
+
let cursor = match.index + match[0].length;
|
|
2172
|
+
const skipTrivia = () => {
|
|
2173
|
+
while (cursor < code.length) {
|
|
2174
|
+
if (/\s/.test(code[cursor])) {
|
|
2175
|
+
cursor++;
|
|
2176
|
+
continue;
|
|
2177
|
+
}
|
|
2178
|
+
if (code[cursor] === "/" && code[cursor + 1] === "/") {
|
|
2179
|
+
cursor += 2;
|
|
2180
|
+
while (cursor < code.length && code[cursor] !== "\n") cursor++;
|
|
2181
|
+
continue;
|
|
2182
|
+
}
|
|
2183
|
+
if (code[cursor] === "/" && code[cursor + 1] === "*") {
|
|
2184
|
+
cursor += 2;
|
|
2185
|
+
while (cursor < code.length && !(code[cursor] === "*" && code[cursor + 1] === "/")) cursor++;
|
|
2186
|
+
cursor += 2;
|
|
2187
|
+
continue;
|
|
2188
|
+
}
|
|
2189
|
+
break;
|
|
2190
|
+
}
|
|
2191
|
+
};
|
|
2192
|
+
skipTrivia();
|
|
2193
|
+
const first = code[cursor];
|
|
2194
|
+
if (!first || first === ")" || first !== "[" && first !== "'" && first !== '"' && first !== "`") {
|
|
2195
|
+
isSelfAccepting = true;
|
|
2196
|
+
continue;
|
|
2197
|
+
}
|
|
2198
|
+
const readLiteral = () => {
|
|
2199
|
+
const quote = code[cursor];
|
|
2200
|
+
if (quote !== "'" && quote !== '"' && quote !== "`") return;
|
|
2201
|
+
const start = cursor;
|
|
2202
|
+
cursor++;
|
|
2203
|
+
let raw = "";
|
|
2204
|
+
while (cursor < code.length) {
|
|
2205
|
+
const char = code[cursor];
|
|
2206
|
+
if (char === "\\") {
|
|
2207
|
+
raw += code[cursor + 1] ?? "";
|
|
2208
|
+
cursor += 2;
|
|
2209
|
+
continue;
|
|
2210
|
+
}
|
|
2211
|
+
if (char === quote) {
|
|
2212
|
+
cursor++;
|
|
2213
|
+
const resolved = removeTimestampQuery(resolveSpec(raw));
|
|
2214
|
+
acceptedUrls.add(resolved);
|
|
2215
|
+
edits.push({ start, end: cursor, value: JSON.stringify(resolved) });
|
|
2216
|
+
return;
|
|
2217
|
+
}
|
|
2218
|
+
if (quote === "`" && char === "$" && code[cursor + 1] === "{") return;
|
|
2219
|
+
raw += char;
|
|
2220
|
+
cursor++;
|
|
2221
|
+
}
|
|
2222
|
+
};
|
|
2223
|
+
if (first === "[") {
|
|
2224
|
+
cursor++;
|
|
2225
|
+
while (cursor < code.length) {
|
|
2226
|
+
skipTrivia();
|
|
2227
|
+
if (code[cursor] === ",") {
|
|
2228
|
+
cursor++;
|
|
2229
|
+
skipTrivia();
|
|
2230
|
+
}
|
|
2231
|
+
if (code[cursor] === "]") break;
|
|
2232
|
+
const before = cursor;
|
|
2233
|
+
readLiteral();
|
|
2234
|
+
if (cursor === before) break;
|
|
2235
|
+
}
|
|
2236
|
+
} else {
|
|
2237
|
+
readLiteral();
|
|
2238
|
+
}
|
|
2239
|
+
}
|
|
2240
|
+
for (const edit of edits.sort((a, b) => b.start - a.start)) {
|
|
2241
|
+
code = code.slice(0, edit.start) + edit.value + code.slice(edit.end);
|
|
2242
|
+
}
|
|
2243
|
+
return { code, acceptedUrls, isSelfAccepting };
|
|
2244
|
+
}
|
|
2245
|
+
function maskStringsAndComments(code) {
|
|
2246
|
+
const masked = code.split("");
|
|
2247
|
+
let state = "code";
|
|
2248
|
+
const isRegexStart = (index2) => {
|
|
2249
|
+
let previous = index2 - 1;
|
|
2250
|
+
while (previous >= 0 && /\s/.test(code[previous])) previous--;
|
|
2251
|
+
return previous < 0 || "=(:,!&|?{};[]+-*%^~<>".includes(code[previous]);
|
|
2252
|
+
};
|
|
2253
|
+
for (let i = 0; i < code.length; i++) {
|
|
2254
|
+
const char = code[i];
|
|
2255
|
+
const next = code[i + 1];
|
|
2256
|
+
if (state === "code") {
|
|
2257
|
+
if (char === "'") state = "single";
|
|
2258
|
+
else if (char === '"') state = "double";
|
|
2259
|
+
else if (char === "`") state = "template";
|
|
2260
|
+
else if (char === "/" && next === "/") state = "line-comment";
|
|
2261
|
+
else if (char === "/" && next === "*") state = "block-comment";
|
|
2262
|
+
else if (char === "/" && isRegexStart(i)) state = "regex";
|
|
2263
|
+
else continue;
|
|
2264
|
+
masked[i] = " ";
|
|
2265
|
+
continue;
|
|
2266
|
+
}
|
|
2267
|
+
if (state === "line-comment") {
|
|
2268
|
+
if (char === "\n") {
|
|
2269
|
+
state = "code";
|
|
2270
|
+
} else {
|
|
2271
|
+
masked[i] = " ";
|
|
2272
|
+
}
|
|
2273
|
+
continue;
|
|
2274
|
+
}
|
|
2275
|
+
if (state === "block-comment") {
|
|
2276
|
+
masked[i] = char === "\n" ? "\n" : " ";
|
|
2277
|
+
if (char === "*" && next === "/") {
|
|
2278
|
+
masked[i + 1] = " ";
|
|
2279
|
+
i++;
|
|
2280
|
+
state = "code";
|
|
2281
|
+
}
|
|
2282
|
+
continue;
|
|
2283
|
+
}
|
|
2284
|
+
if (state === "regex" || state === "regex-class") {
|
|
2285
|
+
masked[i] = char === "\n" ? "\n" : " ";
|
|
2286
|
+
if (char === "\\") {
|
|
2287
|
+
if (i + 1 < code.length) masked[++i] = " ";
|
|
2288
|
+
} else if (state === "regex" && char === "[") {
|
|
2289
|
+
state = "regex-class";
|
|
2290
|
+
} else if (state === "regex-class" && char === "]") {
|
|
2291
|
+
state = "regex";
|
|
2292
|
+
} else if (state === "regex" && char === "/") {
|
|
2293
|
+
state = "code";
|
|
2294
|
+
}
|
|
2295
|
+
continue;
|
|
2296
|
+
}
|
|
2297
|
+
masked[i] = char === "\n" ? "\n" : " ";
|
|
2298
|
+
if (char === "\\") {
|
|
2299
|
+
if (i + 1 < code.length) masked[++i] = " ";
|
|
2300
|
+
continue;
|
|
2301
|
+
}
|
|
2302
|
+
if (state === "single" && char === "'" || state === "double" && char === '"' || state === "template" && char === "`") {
|
|
2303
|
+
state = "code";
|
|
2304
|
+
}
|
|
2305
|
+
}
|
|
2306
|
+
return masked.join("");
|
|
1855
2307
|
}
|
|
1856
2308
|
function resolveAliasTarget(value, root) {
|
|
1857
|
-
if (
|
|
1858
|
-
if (value.startsWith("/")) return
|
|
1859
|
-
return
|
|
2309
|
+
if (import_node_path5.default.isAbsolute(value) && import_node_fs5.default.existsSync(value)) return value;
|
|
2310
|
+
if (value.startsWith("/")) return import_node_path5.default.join(root, value.slice(1));
|
|
2311
|
+
return import_node_path5.default.resolve(root, value);
|
|
1860
2312
|
}
|
|
1861
2313
|
function tryResolveDiskPath(target) {
|
|
1862
|
-
if (
|
|
2314
|
+
if (import_node_fs5.default.existsSync(target) && import_node_fs5.default.statSync(target).isFile()) return target;
|
|
1863
2315
|
for (const ext of RESOLVE_EXTENSIONS) {
|
|
1864
2316
|
const withExt = target + ext;
|
|
1865
|
-
if (
|
|
2317
|
+
if (import_node_fs5.default.existsSync(withExt) && import_node_fs5.default.statSync(withExt).isFile()) return withExt;
|
|
1866
2318
|
}
|
|
1867
|
-
if (
|
|
2319
|
+
if (import_node_fs5.default.existsSync(target) && import_node_fs5.default.statSync(target).isDirectory()) {
|
|
1868
2320
|
for (const ext of RESOLVE_EXTENSIONS) {
|
|
1869
|
-
const idx =
|
|
1870
|
-
if (
|
|
2321
|
+
const idx = import_node_path5.default.join(target, "index" + ext);
|
|
2322
|
+
if (import_node_fs5.default.existsSync(idx) && import_node_fs5.default.statSync(idx).isFile()) return idx;
|
|
1871
2323
|
}
|
|
1872
2324
|
}
|
|
1873
2325
|
return null;
|
|
1874
2326
|
}
|
|
1875
2327
|
function isUnderRoot(abs, root) {
|
|
1876
|
-
const rel =
|
|
1877
|
-
return !!rel && !rel.startsWith("..") && !
|
|
2328
|
+
const rel = import_node_path5.default.relative(root, abs);
|
|
2329
|
+
return !!rel && !rel.startsWith("..") && !import_node_path5.default.isAbsolute(rel);
|
|
2330
|
+
}
|
|
2331
|
+
function appendTimestampQuery(url, timestamp) {
|
|
2332
|
+
const hashIndex = url.indexOf("#");
|
|
2333
|
+
const hash = hashIndex >= 0 ? url.slice(hashIndex) : "";
|
|
2334
|
+
const withoutHash = hashIndex >= 0 ? url.slice(0, hashIndex) : url;
|
|
2335
|
+
return `${withoutHash}${withoutHash.includes("?") ? "&" : "?"}t=${timestamp}${hash}`;
|
|
1878
2336
|
}
|
|
1879
2337
|
function externalSpecToModuleUrl(spec, baseDir, root) {
|
|
1880
2338
|
const resolved = resolveNodeModule(baseDir, spec);
|
|
@@ -1887,7 +2345,7 @@ function resolveNodeModule(baseDir, moduleName) {
|
|
|
1887
2345
|
const resolved = resolveNodeModuleEntry(baseDir, moduleName);
|
|
1888
2346
|
if (!resolved) return null;
|
|
1889
2347
|
try {
|
|
1890
|
-
return
|
|
2348
|
+
return import_node_fs5.default.realpathSync(resolved);
|
|
1891
2349
|
} catch {
|
|
1892
2350
|
return resolved;
|
|
1893
2351
|
}
|
|
@@ -1907,21 +2365,21 @@ function resolveNodeModuleEntry(root, moduleName) {
|
|
|
1907
2365
|
let pkgDir = null;
|
|
1908
2366
|
let dir = root;
|
|
1909
2367
|
for (; ; ) {
|
|
1910
|
-
const candidate =
|
|
1911
|
-
if (
|
|
2368
|
+
const candidate = import_node_path5.default.join(dir, "node_modules", pkgName);
|
|
2369
|
+
if (import_node_fs5.default.existsSync(candidate)) {
|
|
1912
2370
|
pkgDir = candidate;
|
|
1913
2371
|
break;
|
|
1914
2372
|
}
|
|
1915
|
-
const parent =
|
|
2373
|
+
const parent = import_node_path5.default.dirname(dir);
|
|
1916
2374
|
if (parent === dir) break;
|
|
1917
2375
|
dir = parent;
|
|
1918
2376
|
}
|
|
1919
2377
|
if (!pkgDir) return null;
|
|
1920
|
-
const pkgJsonPath =
|
|
1921
|
-
if (!
|
|
2378
|
+
const pkgJsonPath = import_node_path5.default.join(pkgDir, "package.json");
|
|
2379
|
+
if (!import_node_fs5.default.existsSync(pkgJsonPath)) return null;
|
|
1922
2380
|
let pkg;
|
|
1923
2381
|
try {
|
|
1924
|
-
pkg = JSON.parse(
|
|
2382
|
+
pkg = JSON.parse(import_node_fs5.default.readFileSync(pkgJsonPath, "utf-8"));
|
|
1925
2383
|
} catch {
|
|
1926
2384
|
return null;
|
|
1927
2385
|
}
|
|
@@ -1934,32 +2392,32 @@ function resolveNodeModuleEntry(root, moduleName) {
|
|
|
1934
2392
|
const subDirs = [""];
|
|
1935
2393
|
for (const field of ["module", "main"]) {
|
|
1936
2394
|
if (typeof pkg[field] === "string") {
|
|
1937
|
-
const dir2 =
|
|
2395
|
+
const dir2 = import_node_path5.default.dirname(pkg[field]);
|
|
1938
2396
|
if (dir2 && dir2 !== "." && !subDirs.includes(dir2)) subDirs.push(dir2);
|
|
1939
2397
|
}
|
|
1940
2398
|
}
|
|
1941
2399
|
for (const dir2 of subDirs) {
|
|
1942
|
-
const direct =
|
|
1943
|
-
if (
|
|
2400
|
+
const direct = import_node_path5.default.join(pkgDir, dir2, subpath);
|
|
2401
|
+
if (import_node_fs5.default.existsSync(direct) && import_node_fs5.default.statSync(direct).isFile()) return direct;
|
|
1944
2402
|
for (const ext of RESOLVE_EXTENSIONS) {
|
|
1945
|
-
if (
|
|
2403
|
+
if (import_node_fs5.default.existsSync(direct + ext)) return direct + ext;
|
|
1946
2404
|
}
|
|
1947
2405
|
}
|
|
1948
2406
|
return null;
|
|
1949
2407
|
}
|
|
1950
2408
|
for (const field of ["module", "jsnext:main", "jsnext", "main"]) {
|
|
1951
2409
|
if (typeof pkg[field] === "string") {
|
|
1952
|
-
const entry =
|
|
1953
|
-
if (
|
|
2410
|
+
const entry = import_node_path5.default.join(pkgDir, pkg[field]);
|
|
2411
|
+
if (import_node_fs5.default.existsSync(entry)) return entry;
|
|
1954
2412
|
}
|
|
1955
2413
|
}
|
|
1956
|
-
const indexFallback =
|
|
1957
|
-
if (
|
|
2414
|
+
const indexFallback = import_node_path5.default.join(pkgDir, "index.js");
|
|
2415
|
+
if (import_node_fs5.default.existsSync(indexFallback)) return indexFallback;
|
|
1958
2416
|
return null;
|
|
1959
2417
|
}
|
|
1960
2418
|
function resolvePackageExports(exports2, key, pkgDir) {
|
|
1961
2419
|
if (typeof exports2 === "string") {
|
|
1962
|
-
return key === "." ?
|
|
2420
|
+
return key === "." ? import_node_path5.default.join(pkgDir, exports2) : null;
|
|
1963
2421
|
}
|
|
1964
2422
|
const entry = exports2[key];
|
|
1965
2423
|
if (entry === void 0) {
|
|
@@ -1971,7 +2429,7 @@ function resolvePackageExports(exports2, key, pkgDir) {
|
|
|
1971
2429
|
return resolveExportValue(entry, pkgDir);
|
|
1972
2430
|
}
|
|
1973
2431
|
function resolveExportValue(value, pkgDir) {
|
|
1974
|
-
if (typeof value === "string") return
|
|
2432
|
+
if (typeof value === "string") return import_node_path5.default.join(pkgDir, value);
|
|
1975
2433
|
if (Array.isArray(value)) {
|
|
1976
2434
|
for (const item of value) {
|
|
1977
2435
|
const r = resolveExportValue(item, pkgDir);
|
|
@@ -1995,54 +2453,62 @@ function resolveUrlToFile(url, root) {
|
|
|
1995
2453
|
const moduleName = cleanUrl.slice("/@modules/".length);
|
|
1996
2454
|
return resolveNodeModule(root, moduleName);
|
|
1997
2455
|
}
|
|
1998
|
-
const filePath =
|
|
1999
|
-
if (
|
|
2456
|
+
const filePath = import_node_path5.default.resolve(root, cleanUrl.replace(/^\//, ""));
|
|
2457
|
+
if (import_node_fs5.default.existsSync(filePath) && import_node_fs5.default.statSync(filePath).isFile()) {
|
|
2000
2458
|
return filePath;
|
|
2001
2459
|
}
|
|
2002
2460
|
for (const ext of RESOLVE_EXTENSIONS) {
|
|
2003
2461
|
const withExt = filePath + ext;
|
|
2004
|
-
if (
|
|
2462
|
+
if (import_node_fs5.default.existsSync(withExt)) return withExt;
|
|
2005
2463
|
}
|
|
2006
2464
|
for (const ext of RESOLVE_EXTENSIONS) {
|
|
2007
|
-
const indexFile =
|
|
2008
|
-
if (
|
|
2465
|
+
const indexFile = import_node_path5.default.join(filePath, "index" + ext);
|
|
2466
|
+
if (import_node_fs5.default.existsSync(indexFile)) return indexFile;
|
|
2009
2467
|
}
|
|
2010
2468
|
return null;
|
|
2011
2469
|
}
|
|
2012
|
-
function isModuleRequest(url) {
|
|
2470
|
+
function isModuleRequest(url, destination) {
|
|
2013
2471
|
const cleanUrl = url.split("?")[0];
|
|
2014
2472
|
if (/\.(ts|tsx|jsx|js|mjs|vue|css|json)$/.test(cleanUrl)) return true;
|
|
2015
2473
|
if (cleanUrl.startsWith("/@modules/")) return true;
|
|
2016
|
-
if (
|
|
2474
|
+
if (isAssetFile(cleanUrl)) {
|
|
2475
|
+
const query = url.includes("?") ? url.slice(url.indexOf("?") + 1) : "";
|
|
2476
|
+
const isExplicitAssetModule = /(?:^|&)(?:url|raw)(?:&|$)/.test(query);
|
|
2477
|
+
return isExplicitAssetModule || destination === "script";
|
|
2478
|
+
}
|
|
2479
|
+
if (!import_node_path5.default.extname(cleanUrl)) return true;
|
|
2017
2480
|
return false;
|
|
2018
2481
|
}
|
|
2019
2482
|
function getHmrClientCode() {
|
|
2020
2483
|
return `
|
|
2021
2484
|
// Nasti HMR Client
|
|
2022
|
-
const
|
|
2485
|
+
const socketProtocol = location.protocol === 'https:' ? 'wss' : 'ws';
|
|
2486
|
+
const socket = new WebSocket(socketProtocol + '://' + location.host, 'nasti-hmr');
|
|
2023
2487
|
const hotModulesMap = new Map();
|
|
2024
2488
|
const disposeMap = new Map();
|
|
2025
2489
|
const pruneMap = new Map();
|
|
2490
|
+
const dataMap = new Map();
|
|
2491
|
+
const customListenersMap = new Map();
|
|
2492
|
+
let updateQueue = [];
|
|
2493
|
+
let pendingUpdateQueue = false;
|
|
2026
2494
|
|
|
2027
2495
|
socket.addEventListener('message', async ({ data }) => {
|
|
2028
2496
|
const payload = JSON.parse(data);
|
|
2497
|
+
// \u9ED8\u8BA4\u6D4F\u89C8\u5668 client \u53EA\u6D88\u8D39\u81EA\u5DF1\u7684 HMR \u6D88\u606F\uFF1Bnative/worker \u73AF\u5883\u901A\u8FC7\u5404\u81EA\u7684
|
|
2498
|
+
// HotChannel \u6216 app-level HMR \u534F\u8C03\u5668\u5904\u7406\u540C\u4E00 transport \u4E0A\u7684\u547D\u540D\u6D88\u606F\u3002
|
|
2499
|
+
if (payload.environment && payload.environment !== 'client') return;
|
|
2029
2500
|
switch (payload.type) {
|
|
2030
2501
|
case 'connected':
|
|
2031
|
-
console.
|
|
2502
|
+
console.debug('[nasti] connected.');
|
|
2032
2503
|
clearErrorOverlay();
|
|
2033
2504
|
break;
|
|
2034
2505
|
case 'update':
|
|
2035
2506
|
try {
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
} else if (update.type === 'css-update') {
|
|
2040
|
-
return updateCss(update.path);
|
|
2041
|
-
}
|
|
2042
|
-
}));
|
|
2507
|
+
// CSS \u5728 unbundled \u6A21\u5F0F\u4E0B\u4E5F\u662F\u4F1A\u6CE8\u5165 <style> \u7684 JS \u6A21\u5757\uFF0C\u548C\u666E\u901A JS
|
|
2508
|
+
// \u4E00\u6837\u91CD\u65B0 import \u624D\u80FD\u6267\u884C dispose/accept \u5E76\u4FDD\u6301\u9875\u9762\u72B6\u6001\u3002
|
|
2509
|
+
await Promise.all(payload.updates.map(queueUpdate));
|
|
2043
2510
|
clearErrorOverlay();
|
|
2044
|
-
console.
|
|
2045
|
-
location.reload();
|
|
2511
|
+
console.debug('[nasti] HMR update complete.');
|
|
2046
2512
|
} catch (err) {
|
|
2047
2513
|
console.error('[nasti] HMR update failed:', err);
|
|
2048
2514
|
showErrorOverlay(err);
|
|
@@ -2053,11 +2519,34 @@ socket.addEventListener('message', async ({ data }) => {
|
|
|
2053
2519
|
location.reload();
|
|
2054
2520
|
break;
|
|
2055
2521
|
case 'prune':
|
|
2056
|
-
payload.paths.
|
|
2057
|
-
const
|
|
2058
|
-
|
|
2059
|
-
|
|
2522
|
+
await Promise.all(payload.paths.map(async (path) => {
|
|
2523
|
+
const data = dataMap.get(path);
|
|
2524
|
+
const dispose = disposeMap.get(path);
|
|
2525
|
+
const prune = pruneMap.get(path);
|
|
2526
|
+
if (dispose) await dispose(data);
|
|
2527
|
+
if (prune) await prune(data);
|
|
2528
|
+
hotModulesMap.delete(path);
|
|
2529
|
+
disposeMap.delete(path);
|
|
2530
|
+
pruneMap.delete(path);
|
|
2531
|
+
dataMap.delete(path);
|
|
2532
|
+
clearCustomListeners(path);
|
|
2533
|
+
}));
|
|
2534
|
+
break;
|
|
2535
|
+
case 'custom': {
|
|
2536
|
+
const listenersByOwner = customListenersMap.get(payload.event);
|
|
2537
|
+
if (!listenersByOwner) break;
|
|
2538
|
+
const results = await Promise.allSettled(
|
|
2539
|
+
[...listenersByOwner.values()]
|
|
2540
|
+
.flatMap((listeners) => [...listeners])
|
|
2541
|
+
.map((listener) => Promise.resolve().then(() => listener(payload.data)))
|
|
2542
|
+
);
|
|
2543
|
+
for (const result of results) {
|
|
2544
|
+
if (result.status === 'rejected') {
|
|
2545
|
+
console.error('[nasti] custom HMR event listener failed:', result.reason);
|
|
2546
|
+
}
|
|
2547
|
+
}
|
|
2060
2548
|
break;
|
|
2549
|
+
}
|
|
2061
2550
|
case 'error':
|
|
2062
2551
|
console.error('[nasti] error:', payload.err.message);
|
|
2063
2552
|
showErrorOverlay(payload.err);
|
|
@@ -2065,33 +2554,64 @@ socket.addEventListener('message', async ({ data }) => {
|
|
|
2065
2554
|
}
|
|
2066
2555
|
});
|
|
2067
2556
|
|
|
2068
|
-
// \
|
|
2557
|
+
// \u670D\u52A1\u91CD\u542F\u540E\u65E7\u6A21\u5757\u56FE\u5DF2\u5931\u6548\uFF0C\u91CD\u8FDE\u65F6\u6574\u9875\u5237\u65B0\u662F\u5FC5\u8981\u515C\u5E95\uFF1B\u6B63\u5E38 update \u4E0D\u518D\u5237\u65B0\u3002
|
|
2069
2558
|
let reconnectTimer = 0;
|
|
2070
2559
|
socket.addEventListener('close', () => {
|
|
2071
2560
|
clearTimeout(reconnectTimer);
|
|
2072
2561
|
reconnectTimer = setTimeout(() => location.reload(), 1000);
|
|
2073
2562
|
});
|
|
2074
2563
|
|
|
2564
|
+
/**
|
|
2565
|
+
* \u540C\u4E00\u6279\u66F4\u65B0\u5148\u5168\u90E8\u62C9\u53D6\uFF0C\u518D\u6309\u670D\u52A1\u7AEF\u6D88\u606F\u987A\u5E8F\u6267\u884C accept \u56DE\u8C03\uFF0C\u907F\u514D HTTP \u5F80\u8FD4\u901F\u5EA6
|
|
2566
|
+
* \u6539\u53D8\u6A21\u5757\u5E94\u7528\u987A\u5E8F\u3002\u8FD9\u4E0E Vite HMRClient \u7684 fetch/apply \u4E24\u9636\u6BB5\u4E00\u81F4\u3002
|
|
2567
|
+
*/
|
|
2568
|
+
async function queueUpdate(update) {
|
|
2569
|
+
updateQueue.push(fetchUpdate(update));
|
|
2570
|
+
if (pendingUpdateQueue) return;
|
|
2571
|
+
|
|
2572
|
+
pendingUpdateQueue = true;
|
|
2573
|
+
await Promise.resolve();
|
|
2574
|
+
pendingUpdateQueue = false;
|
|
2575
|
+
const loading = updateQueue;
|
|
2576
|
+
updateQueue = [];
|
|
2577
|
+
const applyUpdates = await Promise.all(loading);
|
|
2578
|
+
for (const apply of applyUpdates) {
|
|
2579
|
+
if (apply) apply();
|
|
2580
|
+
}
|
|
2581
|
+
}
|
|
2582
|
+
|
|
2075
2583
|
async function fetchUpdate(update) {
|
|
2076
2584
|
const mod = hotModulesMap.get(update.path);
|
|
2077
|
-
// \
|
|
2078
|
-
|
|
2079
|
-
if (dispose) dispose();
|
|
2585
|
+
// \u5C1A\u672A\u5728\u5F53\u524D\u9875\u9762\u52A0\u8F7D\u7684\u52A8\u6001\u6A21\u5757\u4E0D\u9700\u8981\u66F4\u65B0\u3002
|
|
2586
|
+
if (!mod) return;
|
|
2080
2587
|
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2588
|
+
// \u5FC5\u987B\u5728\u91CD\u65B0 import \u524D\u786E\u5B9A\u65E7\u56DE\u8C03\uFF1B\u65B0\u6A21\u5757\u6267\u884C createHotContext \u65F6\u4F1A\u6E05\u7A7A\u5E76\u6CE8\u518C\u65B0\u56DE\u8C03\u3002
|
|
2589
|
+
const qualifiedCallbacks = mod.callbacks.filter(({ deps }) =>
|
|
2590
|
+
deps.includes(update.acceptedPath)
|
|
2591
|
+
);
|
|
2592
|
+
const isSelfUpdate = update.path === update.acceptedPath;
|
|
2593
|
+
if (!isSelfUpdate && qualifiedCallbacks.length === 0) return;
|
|
2594
|
+
|
|
2595
|
+
const dispose = disposeMap.get(update.acceptedPath);
|
|
2596
|
+
if (dispose) await dispose(dataMap.get(update.acceptedPath));
|
|
2597
|
+
const newMod = await import(appendTimestampQuery(update.acceptedPath, update.timestamp));
|
|
2598
|
+
|
|
2599
|
+
return () => {
|
|
2600
|
+
for (const { deps, fn } of qualifiedCallbacks) {
|
|
2601
|
+
fn(deps.map((dep) => dep === update.acceptedPath ? newMod : undefined));
|
|
2602
|
+
}
|
|
2603
|
+
const detail = isSelfUpdate
|
|
2604
|
+
? update.path
|
|
2605
|
+
: update.acceptedPath + ' via ' + update.path;
|
|
2606
|
+
console.debug('[nasti] hot updated:', detail);
|
|
2607
|
+
};
|
|
2086
2608
|
}
|
|
2087
2609
|
|
|
2088
|
-
function
|
|
2089
|
-
const
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
.then(css => { el.textContent = css; });
|
|
2094
|
-
}
|
|
2610
|
+
function appendTimestampQuery(url, timestamp) {
|
|
2611
|
+
const hashIndex = url.indexOf('#');
|
|
2612
|
+
const hash = hashIndex >= 0 ? url.slice(hashIndex) : '';
|
|
2613
|
+
const withoutHash = hashIndex >= 0 ? url.slice(0, hashIndex) : url;
|
|
2614
|
+
return withoutHash + (withoutHash.includes('?') ? '&' : '?') + 't=' + timestamp + hash;
|
|
2095
2615
|
}
|
|
2096
2616
|
|
|
2097
2617
|
function clearErrorOverlay() {
|
|
@@ -2119,23 +2639,31 @@ function showErrorOverlay(err) {
|
|
|
2119
2639
|
document.body.appendChild(overlay);
|
|
2120
2640
|
}
|
|
2121
2641
|
|
|
2122
|
-
/**
|
|
2123
|
-
* \u751F\u6210 import.meta.hot \u7684 hot context\u3002
|
|
2124
|
-
* \u5173\u952E\u7EA6\u675F\uFF1A\u540C\u4E00 ownerPath \u7684 accept \u56DE\u8C03\u5FC5\u987B\u66FF\u6362\uFF08\u4E0D\u662F append\uFF09\u3002
|
|
2125
|
-
* \u6BCF\u6B21\u6A21\u5757\u91CD\u65B0 import \u90FD\u4F1A\u8C03\u7528 createHotContext\uFF0C\u65E7\u56DE\u8C03\u4F1A\u88AB fetchUpdate \u8C03\u7528\u540E\u7ACB\u5373\u88AB\u65B0 import
|
|
2126
|
-
* \u91CC\u7684 accept \u66FF\u6362\u3002\u4E0D\u66FF\u6362\u7684\u8BDD\u6BCF\u7F16\u8F91\u4E00\u6B21\u5C31\u591A\u4E00\u4E2A\u56DE\u8C03\uFF0C\u8D8A\u8DD1\u8D8A\u6162\u3002
|
|
2127
|
-
*/
|
|
2128
2642
|
export function createHotContext(ownerPath) {
|
|
2643
|
+
if (!dataMap.has(ownerPath)) dataMap.set(ownerPath, {});
|
|
2644
|
+
|
|
2645
|
+
// \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
|
|
2646
|
+
const existing = hotModulesMap.get(ownerPath);
|
|
2647
|
+
if (existing) existing.callbacks = [];
|
|
2648
|
+
clearCustomListeners(ownerPath);
|
|
2649
|
+
|
|
2650
|
+
const acceptDeps = (deps, callback = () => {}) => {
|
|
2651
|
+
const mod = hotModulesMap.get(ownerPath) || { id: ownerPath, callbacks: [] };
|
|
2652
|
+
mod.callbacks.push({ deps, fn: callback });
|
|
2653
|
+
hotModulesMap.set(ownerPath, mod);
|
|
2654
|
+
};
|
|
2655
|
+
|
|
2129
2656
|
return {
|
|
2130
2657
|
accept(deps, callback) {
|
|
2131
|
-
// \u81EA\u63A5\u53D7: hot.accept() \u6216 hot.accept(callback)
|
|
2132
2658
|
if (typeof deps === 'function' || deps === undefined) {
|
|
2133
|
-
|
|
2134
|
-
|
|
2659
|
+
acceptDeps([ownerPath], ([mod]) => deps?.(mod));
|
|
2660
|
+
} else if (typeof deps === 'string') {
|
|
2661
|
+
acceptDeps([deps], ([mod]) => callback?.(mod));
|
|
2662
|
+
} else if (Array.isArray(deps)) {
|
|
2663
|
+
acceptDeps(deps, callback);
|
|
2664
|
+
} else {
|
|
2665
|
+
throw new Error('invalid hot.accept() usage');
|
|
2135
2666
|
}
|
|
2136
|
-
// \u4F9D\u8D56\u63A5\u53D7: hot.accept(deps, callback)\uFF0C\u591A\u6B21\u8C03\u7528\u8FFD\u52A0
|
|
2137
|
-
const existing = hotModulesMap.get(ownerPath)?.callbacks ?? [];
|
|
2138
|
-
hotModulesMap.set(ownerPath, { callbacks: [...existing, callback] });
|
|
2139
2667
|
},
|
|
2140
2668
|
prune(callback) {
|
|
2141
2669
|
pruneMap.set(ownerPath, callback);
|
|
@@ -2143,30 +2671,122 @@ export function createHotContext(ownerPath) {
|
|
|
2143
2671
|
dispose(callback) {
|
|
2144
2672
|
disposeMap.set(ownerPath, callback);
|
|
2145
2673
|
},
|
|
2674
|
+
on(event, callback) {
|
|
2675
|
+
let listenersByOwner = customListenersMap.get(event);
|
|
2676
|
+
if (!listenersByOwner) {
|
|
2677
|
+
listenersByOwner = new Map();
|
|
2678
|
+
customListenersMap.set(event, listenersByOwner);
|
|
2679
|
+
}
|
|
2680
|
+
let listeners = listenersByOwner.get(ownerPath);
|
|
2681
|
+
if (!listeners) {
|
|
2682
|
+
listeners = new Set();
|
|
2683
|
+
listenersByOwner.set(ownerPath, listeners);
|
|
2684
|
+
}
|
|
2685
|
+
listeners.add(callback);
|
|
2686
|
+
},
|
|
2687
|
+
off(event, callback) {
|
|
2688
|
+
const listenersByOwner = customListenersMap.get(event);
|
|
2689
|
+
const listeners = listenersByOwner?.get(ownerPath);
|
|
2690
|
+
listeners?.delete(callback);
|
|
2691
|
+
if (listeners?.size === 0) listenersByOwner.delete(ownerPath);
|
|
2692
|
+
if (listenersByOwner?.size === 0) customListenersMap.delete(event);
|
|
2693
|
+
},
|
|
2146
2694
|
invalidate() {
|
|
2147
2695
|
location.reload();
|
|
2148
2696
|
},
|
|
2149
|
-
data:
|
|
2697
|
+
data: dataMap.get(ownerPath),
|
|
2150
2698
|
};
|
|
2151
2699
|
}
|
|
2700
|
+
|
|
2701
|
+
function clearCustomListeners(ownerPath) {
|
|
2702
|
+
for (const [event, listenersByOwner] of customListenersMap) {
|
|
2703
|
+
listenersByOwner.delete(ownerPath);
|
|
2704
|
+
if (listenersByOwner.size === 0) customListenersMap.delete(event);
|
|
2705
|
+
}
|
|
2706
|
+
}
|
|
2152
2707
|
`;
|
|
2153
2708
|
}
|
|
2154
|
-
var
|
|
2709
|
+
var import_node_path5, import_node_fs5, import_node_module, import_node_url2, import_picocolors3, import_meta, __dirname_esm, __require, __refreshRuntimeCache, REACT_REFRESH_BOUNDARY_HELPERS, REACT_REFRESH_GLOBAL_PREAMBLE, esmBundleCache, VALID_IDENT, RESOLVE_EXTENSIONS, ESM_CONDITIONS;
|
|
2155
2710
|
var init_middleware = __esm({
|
|
2156
2711
|
"src/server/middleware.ts"() {
|
|
2157
2712
|
"use strict";
|
|
2158
|
-
|
|
2159
|
-
|
|
2713
|
+
import_node_path5 = __toESM(require("path"), 1);
|
|
2714
|
+
import_node_fs5 = __toESM(require("fs"), 1);
|
|
2160
2715
|
import_node_module = require("module");
|
|
2161
2716
|
import_node_url2 = require("url");
|
|
2162
2717
|
import_picocolors3 = __toESM(require("picocolors"), 1);
|
|
2163
2718
|
init_transformer();
|
|
2164
2719
|
init_html();
|
|
2165
2720
|
init_env();
|
|
2721
|
+
init_url();
|
|
2722
|
+
init_assets();
|
|
2166
2723
|
import_meta = {};
|
|
2167
|
-
__dirname_esm =
|
|
2724
|
+
__dirname_esm = import_node_path5.default.dirname((0, import_node_url2.fileURLToPath)(import_meta.url));
|
|
2168
2725
|
__require = (0, import_node_module.createRequire)(import_meta.url);
|
|
2169
2726
|
__refreshRuntimeCache = null;
|
|
2727
|
+
REACT_REFRESH_BOUNDARY_HELPERS = `
|
|
2728
|
+
function __nastiIsPlainObject(obj) {
|
|
2729
|
+
return Object.prototype.toString.call(obj) === '[object Object]' &&
|
|
2730
|
+
(obj.constructor === Object || obj.constructor === undefined);
|
|
2731
|
+
}
|
|
2732
|
+
function __nastiIsCompoundComponent(type) {
|
|
2733
|
+
if (!__nastiIsPlainObject(type)) return false;
|
|
2734
|
+
for (const key in type) {
|
|
2735
|
+
if (!isLikelyComponentType(type[key])) return false;
|
|
2736
|
+
}
|
|
2737
|
+
return true;
|
|
2738
|
+
}
|
|
2739
|
+
export function registerExportsForReactRefresh(filename, moduleExports) {
|
|
2740
|
+
for (const key in moduleExports) {
|
|
2741
|
+
if (key === '__esModule') continue;
|
|
2742
|
+
const value = moduleExports[key];
|
|
2743
|
+
if (isLikelyComponentType(value)) {
|
|
2744
|
+
register(value, filename + ' export ' + key);
|
|
2745
|
+
} else if (__nastiIsCompoundComponent(value)) {
|
|
2746
|
+
for (const subKey in value) {
|
|
2747
|
+
register(value[subKey], filename + ' export ' + key + '-' + subKey);
|
|
2748
|
+
}
|
|
2749
|
+
}
|
|
2750
|
+
}
|
|
2751
|
+
}
|
|
2752
|
+
let __nastiRefreshTimer;
|
|
2753
|
+
function __nastiEnqueueRefresh() {
|
|
2754
|
+
clearTimeout(__nastiRefreshTimer);
|
|
2755
|
+
__nastiRefreshTimer = setTimeout(() => performReactRefresh(), 16);
|
|
2756
|
+
}
|
|
2757
|
+
function __nastiCheckExports(ignored, exports, predicate) {
|
|
2758
|
+
for (const key in exports) {
|
|
2759
|
+
if (ignored.includes(key)) continue;
|
|
2760
|
+
if (!predicate(key, exports[key])) return key;
|
|
2761
|
+
}
|
|
2762
|
+
return true;
|
|
2763
|
+
}
|
|
2764
|
+
export function validateRefreshBoundaryAndEnqueueUpdate(id, prevExports, nextExports) {
|
|
2765
|
+
const ignored = window.__getReactRefreshIgnoredExports?.({ id }) ?? [];
|
|
2766
|
+
if (__nastiCheckExports(ignored, prevExports, (key) => key in nextExports) !== true) {
|
|
2767
|
+
return 'Could not Fast Refresh (export removed)';
|
|
2768
|
+
}
|
|
2769
|
+
if (__nastiCheckExports(ignored, nextExports, (key) => key in prevExports) !== true) {
|
|
2770
|
+
return 'Could not Fast Refresh (new export)';
|
|
2771
|
+
}
|
|
2772
|
+
let hasExports = false;
|
|
2773
|
+
const compatible = __nastiCheckExports(ignored, nextExports, (key, value) => {
|
|
2774
|
+
hasExports = true;
|
|
2775
|
+
return isLikelyComponentType(value) ||
|
|
2776
|
+
__nastiIsCompoundComponent(value) ||
|
|
2777
|
+
prevExports[key] === value;
|
|
2778
|
+
});
|
|
2779
|
+
if (!hasExports) {
|
|
2780
|
+
return 'Could not Fast Refresh (no exports)';
|
|
2781
|
+
}
|
|
2782
|
+
if (compatible === true) {
|
|
2783
|
+
__nastiEnqueueRefresh();
|
|
2784
|
+
return;
|
|
2785
|
+
}
|
|
2786
|
+
return 'Could not Fast Refresh ("' + compatible + '" export is incompatible)';
|
|
2787
|
+
}
|
|
2788
|
+
export const __hmr_import = (module) => import(module);
|
|
2789
|
+
`;
|
|
2170
2790
|
REACT_REFRESH_GLOBAL_PREAMBLE = `
|
|
2171
2791
|
import RefreshRuntime from "/@react-refresh";
|
|
2172
2792
|
RefreshRuntime.injectIntoGlobalHook(window);
|
|
@@ -2182,28 +2802,37 @@ window.__vite_plugin_react_preamble_installed__ = true;
|
|
|
2182
2802
|
});
|
|
2183
2803
|
|
|
2184
2804
|
// src/server/hmr.ts
|
|
2185
|
-
async function handleFileChange(file, server) {
|
|
2186
|
-
const {
|
|
2805
|
+
async function handleFileChange(file, server, environmentName = "client", timestamp = Date.now()) {
|
|
2806
|
+
const { config } = server;
|
|
2807
|
+
const environment = server.environments[environmentName];
|
|
2808
|
+
if (!environment) {
|
|
2809
|
+
throw new Error(`[nasti] unknown dev environment "${environmentName}"`);
|
|
2810
|
+
}
|
|
2811
|
+
const moduleGraph = environment.moduleGraph;
|
|
2187
2812
|
const logger = config.logger;
|
|
2188
|
-
const relativePath = "/" +
|
|
2189
|
-
const shortFile =
|
|
2813
|
+
const relativePath = "/" + import_node_path6.default.relative(config.root, file);
|
|
2814
|
+
const shortFile = import_node_path6.default.relative(config.root, file);
|
|
2190
2815
|
const mods = moduleGraph.getModulesByFile(file);
|
|
2191
2816
|
if (!mods || mods.size === 0) {
|
|
2192
|
-
return;
|
|
2817
|
+
return null;
|
|
2193
2818
|
}
|
|
2194
2819
|
const updates = [];
|
|
2195
|
-
const
|
|
2820
|
+
const graph = moduleGraph;
|
|
2821
|
+
const invalidatedModules = /* @__PURE__ */ new Set();
|
|
2822
|
+
const affectedSet = /* @__PURE__ */ new Set();
|
|
2823
|
+
let fullReload = false;
|
|
2196
2824
|
for (const mod of mods) {
|
|
2197
|
-
|
|
2825
|
+
graph.invalidateModuleAndImporters(mod, timestamp, invalidatedModules);
|
|
2198
2826
|
const ctx = {
|
|
2199
2827
|
file,
|
|
2200
2828
|
timestamp,
|
|
2201
2829
|
modules: [mod],
|
|
2202
|
-
read: () =>
|
|
2203
|
-
server
|
|
2830
|
+
read: () => import_node_fs6.default.readFileSync(file, "utf-8"),
|
|
2831
|
+
server,
|
|
2832
|
+
environment
|
|
2204
2833
|
};
|
|
2205
2834
|
let affectedModules = [mod];
|
|
2206
|
-
for (const plugin of
|
|
2835
|
+
for (const plugin of environment.plugins) {
|
|
2207
2836
|
if (plugin.handleHotUpdate) {
|
|
2208
2837
|
const result = await plugin.handleHotUpdate(ctx);
|
|
2209
2838
|
if (result) {
|
|
@@ -2212,36 +2841,59 @@ async function handleFileChange(file, server) {
|
|
|
2212
2841
|
}
|
|
2213
2842
|
}
|
|
2214
2843
|
for (const affected of affectedModules) {
|
|
2215
|
-
|
|
2844
|
+
affectedSet.add(affected);
|
|
2845
|
+
graph.invalidateModuleAndImporters(affected, timestamp, invalidatedModules);
|
|
2846
|
+
const boundaries = graph.getHmrBoundaries(affected);
|
|
2216
2847
|
if (boundaries.length === 0) {
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
return;
|
|
2848
|
+
fullReload = true;
|
|
2849
|
+
continue;
|
|
2220
2850
|
}
|
|
2221
|
-
for (const { boundary } of boundaries) {
|
|
2222
|
-
|
|
2851
|
+
for (const { boundary, acceptedVia } of boundaries) {
|
|
2852
|
+
const update = {
|
|
2223
2853
|
type: boundary.type === "css" ? "css-update" : "js-update",
|
|
2224
2854
|
path: boundary.url,
|
|
2225
|
-
acceptedPath:
|
|
2855
|
+
acceptedPath: acceptedVia.url,
|
|
2226
2856
|
timestamp
|
|
2227
|
-
}
|
|
2857
|
+
};
|
|
2858
|
+
if (!updates.some(
|
|
2859
|
+
(existing) => existing.type === update.type && existing.path === update.path && existing.acceptedPath === update.acceptedPath
|
|
2860
|
+
)) {
|
|
2861
|
+
updates.push(update);
|
|
2862
|
+
}
|
|
2228
2863
|
}
|
|
2229
2864
|
}
|
|
2230
2865
|
}
|
|
2231
|
-
|
|
2866
|
+
const transformed = await Promise.all(
|
|
2867
|
+
[...affectedSet].map(async (module2) => ({
|
|
2868
|
+
module: module2,
|
|
2869
|
+
result: await environment.transformRequest(module2.url)
|
|
2870
|
+
}))
|
|
2871
|
+
);
|
|
2872
|
+
const logPrefix = environmentName === "client" ? "" : `[${environmentName}] `;
|
|
2873
|
+
if (fullReload) {
|
|
2874
|
+
logger.info(import_picocolors4.default.green(`${logPrefix}reload `) + import_picocolors4.default.dim(shortFile), { timestamp: true });
|
|
2875
|
+
environment.hot.send({ type: "full-reload", path: relativePath });
|
|
2876
|
+
} else if (updates.length > 0) {
|
|
2232
2877
|
logger.info(
|
|
2233
|
-
updates.map((u) => import_picocolors4.default.green(
|
|
2878
|
+
updates.map((u) => import_picocolors4.default.green(`${logPrefix}hmr update `) + import_picocolors4.default.dim(u.path)).join("\n"),
|
|
2234
2879
|
{ timestamp: true }
|
|
2235
2880
|
);
|
|
2236
|
-
|
|
2881
|
+
environment.hot.send({ type: "update", updates });
|
|
2237
2882
|
}
|
|
2883
|
+
return {
|
|
2884
|
+
environment,
|
|
2885
|
+
modules: [...affectedSet],
|
|
2886
|
+
updates,
|
|
2887
|
+
transformed,
|
|
2888
|
+
fullReload
|
|
2889
|
+
};
|
|
2238
2890
|
}
|
|
2239
|
-
var
|
|
2891
|
+
var import_node_path6, import_node_fs6, import_picocolors4;
|
|
2240
2892
|
var init_hmr = __esm({
|
|
2241
2893
|
"src/server/hmr.ts"() {
|
|
2242
2894
|
"use strict";
|
|
2243
|
-
|
|
2244
|
-
|
|
2895
|
+
import_node_path6 = __toESM(require("path"), 1);
|
|
2896
|
+
import_node_fs6 = __toESM(require("fs"), 1);
|
|
2245
2897
|
import_picocolors4 = __toESM(require("picocolors"), 1);
|
|
2246
2898
|
}
|
|
2247
2899
|
});
|
|
@@ -2249,7 +2901,7 @@ var init_hmr = __esm({
|
|
|
2249
2901
|
// src/plugins/resolve.ts
|
|
2250
2902
|
function resolvePlugin(config) {
|
|
2251
2903
|
const { alias, extensions } = config.resolve;
|
|
2252
|
-
const require2 = (0, import_node_module2.createRequire)(
|
|
2904
|
+
const require2 = (0, import_node_module2.createRequire)(import_node_path7.default.resolve(config.root, "package.json"));
|
|
2253
2905
|
const aliasEntries = Object.entries(alias).sort(
|
|
2254
2906
|
([a], [b]) => b.length - a.length
|
|
2255
2907
|
);
|
|
@@ -2257,10 +2909,10 @@ function resolvePlugin(config) {
|
|
|
2257
2909
|
if (config.framework === "vue") {
|
|
2258
2910
|
try {
|
|
2259
2911
|
const vuePkgJson = require2.resolve("vue/package.json", { paths: [config.root] });
|
|
2260
|
-
const vueDir =
|
|
2261
|
-
const mod = JSON.parse(
|
|
2262
|
-
const entry =
|
|
2263
|
-
if (
|
|
2912
|
+
const vueDir = import_node_path7.default.dirname(vuePkgJson);
|
|
2913
|
+
const mod = JSON.parse(import_node_fs7.default.readFileSync(vuePkgJson, "utf-8")).module;
|
|
2914
|
+
const entry = import_node_path7.default.join(vueDir, mod ?? "dist/vue.runtime.esm-bundler.js");
|
|
2915
|
+
if (import_node_fs7.default.existsSync(entry)) vueRuntimeEntry = entry;
|
|
2264
2916
|
} catch {
|
|
2265
2917
|
}
|
|
2266
2918
|
}
|
|
@@ -2272,32 +2924,33 @@ function resolvePlugin(config) {
|
|
|
2272
2924
|
if (source === key || source.startsWith(key + "/")) {
|
|
2273
2925
|
const aliasBase = resolveAliasTarget2(value, config.root);
|
|
2274
2926
|
const sub = source.slice(key.length).replace(/^\//, "");
|
|
2275
|
-
const target = sub ?
|
|
2927
|
+
const target = sub ? import_node_path7.default.join(aliasBase, sub) : aliasBase;
|
|
2276
2928
|
const resolved = tryResolveFile(target, extensions);
|
|
2277
2929
|
if (resolved) return resolved;
|
|
2278
2930
|
break;
|
|
2279
2931
|
}
|
|
2280
2932
|
}
|
|
2281
2933
|
if (source.startsWith("/") && !source.startsWith("//")) {
|
|
2282
|
-
const rootRelative =
|
|
2934
|
+
const rootRelative = import_node_path7.default.join(config.root, source.slice(1));
|
|
2283
2935
|
const resolved = tryResolveFile(rootRelative, extensions);
|
|
2284
2936
|
if (resolved) return resolved;
|
|
2285
2937
|
}
|
|
2286
|
-
if (
|
|
2938
|
+
if (import_node_path7.default.isAbsolute(source) && import_node_fs7.default.existsSync(source)) {
|
|
2287
2939
|
const resolved = tryResolveFile(source, extensions);
|
|
2288
2940
|
if (resolved) return resolved;
|
|
2289
2941
|
}
|
|
2290
2942
|
if (source.startsWith(".")) {
|
|
2291
|
-
const dir = importer ?
|
|
2292
|
-
const absolute =
|
|
2943
|
+
const dir = importer ? import_node_path7.default.dirname(importer) : config.root;
|
|
2944
|
+
const absolute = import_node_path7.default.resolve(dir, source);
|
|
2293
2945
|
const resolved = tryResolveFile(absolute, extensions);
|
|
2294
2946
|
if (resolved) return resolved;
|
|
2295
2947
|
}
|
|
2296
2948
|
if (!source.startsWith("/") && !source.startsWith(".")) {
|
|
2297
2949
|
if (vueRuntimeEntry && source === "vue") return vueRuntimeEntry;
|
|
2950
|
+
if (config.command === "build") return null;
|
|
2298
2951
|
try {
|
|
2299
2952
|
const resolved = require2.resolve(source, {
|
|
2300
|
-
paths: [importer ?
|
|
2953
|
+
paths: [importer ? import_node_path7.default.dirname(importer) : config.root]
|
|
2301
2954
|
});
|
|
2302
2955
|
return resolved;
|
|
2303
2956
|
} catch {
|
|
@@ -2308,46 +2961,46 @@ function resolvePlugin(config) {
|
|
|
2308
2961
|
},
|
|
2309
2962
|
load(id) {
|
|
2310
2963
|
if (id.startsWith("\0")) return null;
|
|
2311
|
-
if (!
|
|
2964
|
+
if (!import_node_fs7.default.existsSync(id)) return null;
|
|
2312
2965
|
if (id.endsWith(".json")) {
|
|
2313
|
-
const content =
|
|
2966
|
+
const content = import_node_fs7.default.readFileSync(id, "utf-8");
|
|
2314
2967
|
return `export default ${content}`;
|
|
2315
2968
|
}
|
|
2316
|
-
return
|
|
2969
|
+
return null;
|
|
2317
2970
|
}
|
|
2318
2971
|
};
|
|
2319
2972
|
}
|
|
2320
2973
|
function resolveAliasTarget2(value, root) {
|
|
2321
|
-
if (
|
|
2322
|
-
if (value.startsWith("/")) return
|
|
2323
|
-
return
|
|
2974
|
+
if (import_node_path7.default.isAbsolute(value) && import_node_fs7.default.existsSync(value)) return value;
|
|
2975
|
+
if (value.startsWith("/")) return import_node_path7.default.join(root, value.slice(1));
|
|
2976
|
+
return import_node_path7.default.resolve(root, value);
|
|
2324
2977
|
}
|
|
2325
2978
|
function tryResolveFile(file, extensions) {
|
|
2326
|
-
if (
|
|
2979
|
+
if (import_node_fs7.default.existsSync(file) && import_node_fs7.default.statSync(file).isFile()) {
|
|
2327
2980
|
return file;
|
|
2328
2981
|
}
|
|
2329
2982
|
for (const ext of extensions) {
|
|
2330
2983
|
const withExt = file + ext;
|
|
2331
|
-
if (
|
|
2984
|
+
if (import_node_fs7.default.existsSync(withExt) && import_node_fs7.default.statSync(withExt).isFile()) {
|
|
2332
2985
|
return withExt;
|
|
2333
2986
|
}
|
|
2334
2987
|
}
|
|
2335
|
-
if (
|
|
2988
|
+
if (import_node_fs7.default.existsSync(file) && import_node_fs7.default.statSync(file).isDirectory()) {
|
|
2336
2989
|
for (const ext of extensions) {
|
|
2337
|
-
const indexFile =
|
|
2338
|
-
if (
|
|
2990
|
+
const indexFile = import_node_path7.default.join(file, "index" + ext);
|
|
2991
|
+
if (import_node_fs7.default.existsSync(indexFile)) {
|
|
2339
2992
|
return indexFile;
|
|
2340
2993
|
}
|
|
2341
2994
|
}
|
|
2342
2995
|
}
|
|
2343
2996
|
return null;
|
|
2344
2997
|
}
|
|
2345
|
-
var
|
|
2998
|
+
var import_node_path7, import_node_fs7, import_node_module2;
|
|
2346
2999
|
var init_resolve = __esm({
|
|
2347
3000
|
"src/plugins/resolve.ts"() {
|
|
2348
3001
|
"use strict";
|
|
2349
|
-
|
|
2350
|
-
|
|
3002
|
+
import_node_path7 = __toESM(require("path"), 1);
|
|
3003
|
+
import_node_fs7 = __toESM(require("fs"), 1);
|
|
2351
3004
|
import_node_module2 = require("module");
|
|
2352
3005
|
}
|
|
2353
3006
|
});
|
|
@@ -2387,27 +3040,27 @@ var require_process = __commonJS({
|
|
|
2387
3040
|
var require_filesystem = __commonJS({
|
|
2388
3041
|
"node_modules/detect-libc/lib/filesystem.js"(exports2, module2) {
|
|
2389
3042
|
"use strict";
|
|
2390
|
-
var
|
|
3043
|
+
var fs13 = require("fs");
|
|
2391
3044
|
var LDD_PATH = "/usr/bin/ldd";
|
|
2392
3045
|
var SELF_PATH = "/proc/self/exe";
|
|
2393
3046
|
var MAX_LENGTH = 2048;
|
|
2394
|
-
var readFileSync = (
|
|
2395
|
-
const fd =
|
|
3047
|
+
var readFileSync = (path18) => {
|
|
3048
|
+
const fd = fs13.openSync(path18, "r");
|
|
2396
3049
|
const buffer = Buffer.alloc(MAX_LENGTH);
|
|
2397
|
-
const bytesRead =
|
|
2398
|
-
|
|
3050
|
+
const bytesRead = fs13.readSync(fd, buffer, 0, MAX_LENGTH, 0);
|
|
3051
|
+
fs13.close(fd, () => {
|
|
2399
3052
|
});
|
|
2400
3053
|
return buffer.subarray(0, bytesRead);
|
|
2401
3054
|
};
|
|
2402
|
-
var readFile = (
|
|
2403
|
-
|
|
3055
|
+
var readFile = (path18) => new Promise((resolve, reject) => {
|
|
3056
|
+
fs13.open(path18, "r", (err, fd) => {
|
|
2404
3057
|
if (err) {
|
|
2405
3058
|
reject(err);
|
|
2406
3059
|
} else {
|
|
2407
3060
|
const buffer = Buffer.alloc(MAX_LENGTH);
|
|
2408
|
-
|
|
3061
|
+
fs13.read(fd, buffer, 0, MAX_LENGTH, 0, (_, bytesRead) => {
|
|
2409
3062
|
resolve(buffer.subarray(0, bytesRead));
|
|
2410
|
-
|
|
3063
|
+
fs13.close(fd, () => {
|
|
2411
3064
|
});
|
|
2412
3065
|
});
|
|
2413
3066
|
}
|
|
@@ -2519,11 +3172,11 @@ var require_detect_libc = __commonJS({
|
|
|
2519
3172
|
}
|
|
2520
3173
|
return null;
|
|
2521
3174
|
};
|
|
2522
|
-
var familyFromInterpreterPath = (
|
|
2523
|
-
if (
|
|
2524
|
-
if (
|
|
3175
|
+
var familyFromInterpreterPath = (path18) => {
|
|
3176
|
+
if (path18) {
|
|
3177
|
+
if (path18.includes("/ld-musl-")) {
|
|
2525
3178
|
return MUSL;
|
|
2526
|
-
} else if (
|
|
3179
|
+
} else if (path18.includes("/ld-linux-")) {
|
|
2527
3180
|
return GLIBC;
|
|
2528
3181
|
}
|
|
2529
3182
|
}
|
|
@@ -2570,8 +3223,8 @@ var require_detect_libc = __commonJS({
|
|
|
2570
3223
|
cachedFamilyInterpreter = null;
|
|
2571
3224
|
try {
|
|
2572
3225
|
const selfContent = await readFile(SELF_PATH);
|
|
2573
|
-
const
|
|
2574
|
-
cachedFamilyInterpreter = familyFromInterpreterPath(
|
|
3226
|
+
const path18 = interpreterPath(selfContent);
|
|
3227
|
+
cachedFamilyInterpreter = familyFromInterpreterPath(path18);
|
|
2575
3228
|
} catch (e) {
|
|
2576
3229
|
}
|
|
2577
3230
|
return cachedFamilyInterpreter;
|
|
@@ -2583,8 +3236,8 @@ var require_detect_libc = __commonJS({
|
|
|
2583
3236
|
cachedFamilyInterpreter = null;
|
|
2584
3237
|
try {
|
|
2585
3238
|
const selfContent = readFileSync(SELF_PATH);
|
|
2586
|
-
const
|
|
2587
|
-
cachedFamilyInterpreter = familyFromInterpreterPath(
|
|
3239
|
+
const path18 = interpreterPath(selfContent);
|
|
3240
|
+
cachedFamilyInterpreter = familyFromInterpreterPath(path18);
|
|
2588
3241
|
} catch (e) {
|
|
2589
3242
|
}
|
|
2590
3243
|
return cachedFamilyInterpreter;
|
|
@@ -3231,12 +3884,31 @@ var init_node = __esm({
|
|
|
3231
3884
|
function createCssEngine() {
|
|
3232
3885
|
return {
|
|
3233
3886
|
styles: /* @__PURE__ */ new Map(),
|
|
3887
|
+
modules: /* @__PURE__ */ new Map(),
|
|
3888
|
+
chunks: /* @__PURE__ */ new Map(),
|
|
3234
3889
|
entryCss: /* @__PURE__ */ new Map(),
|
|
3235
3890
|
allCss: [],
|
|
3236
3891
|
pendingSingle: [],
|
|
3237
3892
|
singleFileName: null
|
|
3238
3893
|
};
|
|
3239
3894
|
}
|
|
3895
|
+
function getCssMetadata(engine) {
|
|
3896
|
+
return {
|
|
3897
|
+
modules: Object.fromEntries(
|
|
3898
|
+
[...engine.modules].map(([id, module2]) => [id, { ...module2 }])
|
|
3899
|
+
),
|
|
3900
|
+
chunks: Object.fromEntries(
|
|
3901
|
+
[...engine.chunks].map(([fileName, chunk]) => [
|
|
3902
|
+
fileName,
|
|
3903
|
+
{
|
|
3904
|
+
fileName,
|
|
3905
|
+
moduleIds: [...chunk.moduleIds],
|
|
3906
|
+
cssFileNames: [...chunk.cssFileNames]
|
|
3907
|
+
}
|
|
3908
|
+
])
|
|
3909
|
+
)
|
|
3910
|
+
};
|
|
3911
|
+
}
|
|
3240
3912
|
function normalizeCssModuleId(id) {
|
|
3241
3913
|
return id.startsWith("\0") ? id.slice(1) : id;
|
|
3242
3914
|
}
|
|
@@ -3291,7 +3963,7 @@ function hasTailwindDirectives(css) {
|
|
|
3291
3963
|
}
|
|
3292
3964
|
async function loadTailwind(projectRoot) {
|
|
3293
3965
|
if (cached && cachedRoot === projectRoot) return cached;
|
|
3294
|
-
const req = (0, import_node_module3.createRequire)(
|
|
3966
|
+
const req = (0, import_node_module3.createRequire)(import_node_path8.default.join(projectRoot, "package.json"));
|
|
3295
3967
|
let nodePath;
|
|
3296
3968
|
let oxidePath;
|
|
3297
3969
|
try {
|
|
@@ -3312,7 +3984,7 @@ async function compileTailwind(css, fromFile, projectRoot) {
|
|
|
3312
3984
|
const { node, oxide } = await loadTailwind(projectRoot);
|
|
3313
3985
|
const dependencies = [];
|
|
3314
3986
|
const compiler2 = await node.compile(css, {
|
|
3315
|
-
base:
|
|
3987
|
+
base: import_node_path8.default.dirname(fromFile),
|
|
3316
3988
|
from: fromFile,
|
|
3317
3989
|
onDependency: (p) => dependencies.push(p)
|
|
3318
3990
|
});
|
|
@@ -3323,11 +3995,11 @@ async function compileTailwind(css, fromFile, projectRoot) {
|
|
|
3323
3995
|
dependencies: [...dependencies, ...scanner.files]
|
|
3324
3996
|
};
|
|
3325
3997
|
}
|
|
3326
|
-
var
|
|
3998
|
+
var import_node_path8, import_node_module3, import_node_url3, TAILWIND_DIRECTIVE_RE, cached, cachedRoot;
|
|
3327
3999
|
var init_tailwind = __esm({
|
|
3328
4000
|
"src/plugins/tailwind.ts"() {
|
|
3329
4001
|
"use strict";
|
|
3330
|
-
|
|
4002
|
+
import_node_path8 = __toESM(require("path"), 1);
|
|
3331
4003
|
import_node_module3 = require("module");
|
|
3332
4004
|
import_node_url3 = require("url");
|
|
3333
4005
|
TAILWIND_DIRECTIVE_RE = /@(?:import\s+["']tailwindcss(?:\b|\/)|tailwind\b|theme\b|apply\b|plugin\b|source\b|utility\b|variant\b|custom-variant\b|reference\b)/;
|
|
@@ -3356,15 +4028,29 @@ function cssPlugin(config, engine, consumer = "client") {
|
|
|
3356
4028
|
}
|
|
3357
4029
|
const rewritten = rewriteCssUrls(cssSource, file, config.root);
|
|
3358
4030
|
const escaped = JSON.stringify(rewritten);
|
|
4031
|
+
const normalizedId = normalizeCssModuleId(id);
|
|
4032
|
+
const cssModule = { id: normalizedId, source: code, code: rewritten };
|
|
4033
|
+
const map = config.build.sourcemap ? createIdentitySourceMap(code, id) : void 0;
|
|
4034
|
+
engine?.modules.set(normalizedId, cssModule);
|
|
4035
|
+
this.environment?.setCssModule?.(cssModule);
|
|
3359
4036
|
if (query === "inline") {
|
|
3360
4037
|
return { code: `export default ${escaped};
|
|
3361
|
-
`, moduleType: "js" };
|
|
4038
|
+
`, map, moduleType: "js" };
|
|
3362
4039
|
}
|
|
3363
4040
|
if (consumer === "server") {
|
|
3364
4041
|
return { code: `export default ${escaped};
|
|
3365
|
-
`, moduleType: "js" };
|
|
4042
|
+
`, map, moduleType: "js" };
|
|
3366
4043
|
}
|
|
3367
4044
|
if (config.command === "serve") {
|
|
4045
|
+
if (config.build.css.inject === false) {
|
|
4046
|
+
return {
|
|
4047
|
+
code: `export default ${escaped};
|
|
4048
|
+
`,
|
|
4049
|
+
map,
|
|
4050
|
+
moduleType: "js",
|
|
4051
|
+
moduleSideEffects: "no-treeshake"
|
|
4052
|
+
};
|
|
4053
|
+
}
|
|
3368
4054
|
return {
|
|
3369
4055
|
code: `
|
|
3370
4056
|
const css = ${escaped};
|
|
@@ -3388,16 +4074,18 @@ if (import.meta.hot) {
|
|
|
3388
4074
|
|
|
3389
4075
|
export default css;
|
|
3390
4076
|
`,
|
|
4077
|
+
map,
|
|
3391
4078
|
// bundled dev(DevEngine)下该模块会进 Rolldown:不标 js 会按 .css
|
|
3392
4079
|
// 扩展名走 CSS 管线触发 #4271 报错;unbundled 中间件忽略此字段
|
|
3393
4080
|
moduleType: "js"
|
|
3394
4081
|
};
|
|
3395
4082
|
}
|
|
3396
4083
|
if (engine) {
|
|
3397
|
-
engine.styles.set(
|
|
4084
|
+
engine.styles.set(normalizedId, rewritten);
|
|
3398
4085
|
return {
|
|
3399
4086
|
code: `export default '';
|
|
3400
4087
|
`,
|
|
4088
|
+
map,
|
|
3401
4089
|
moduleType: "js",
|
|
3402
4090
|
// 防止空 stub 被 tree-shake 出 chunk.moduleIds(css-post 靠它定位)
|
|
3403
4091
|
moduleSideEffects: "no-treeshake"
|
|
@@ -3417,26 +4105,43 @@ document.head.appendChild(style);
|
|
|
3417
4105
|
|
|
3418
4106
|
export default css;
|
|
3419
4107
|
`,
|
|
4108
|
+
map,
|
|
3420
4109
|
moduleType: "js"
|
|
3421
4110
|
};
|
|
3422
4111
|
}
|
|
3423
4112
|
};
|
|
3424
4113
|
}
|
|
4114
|
+
function createIdentitySourceMap(code, id) {
|
|
4115
|
+
const map = new import_source_map_js.SourceMapGenerator({ file: id });
|
|
4116
|
+
const lines = code.split("\n");
|
|
4117
|
+
for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
|
|
4118
|
+
for (let column = 0; column <= lines[lineIndex].length; column++) {
|
|
4119
|
+
map.addMapping({
|
|
4120
|
+
generated: { line: lineIndex + 1, column },
|
|
4121
|
+
original: { line: lineIndex + 1, column },
|
|
4122
|
+
source: id
|
|
4123
|
+
});
|
|
4124
|
+
}
|
|
4125
|
+
}
|
|
4126
|
+
map.setSourceContent(id, code);
|
|
4127
|
+
return map.toJSON();
|
|
4128
|
+
}
|
|
3425
4129
|
function rewriteCssUrls(css, from, root) {
|
|
3426
4130
|
return css.replace(/url\(\s*['"]?([^'")\s]+)['"]?\s*\)/g, (match, url) => {
|
|
3427
4131
|
if (url.startsWith("/") || url.startsWith("data:") || url.startsWith("http")) {
|
|
3428
4132
|
return match;
|
|
3429
4133
|
}
|
|
3430
|
-
const resolved =
|
|
3431
|
-
const relative = "/" +
|
|
4134
|
+
const resolved = import_node_path9.default.resolve(import_node_path9.default.dirname(from), url);
|
|
4135
|
+
const relative = "/" + import_node_path9.default.relative(root, resolved).replace(/\\/g, "/");
|
|
3432
4136
|
return `url(${relative})`;
|
|
3433
4137
|
});
|
|
3434
4138
|
}
|
|
3435
|
-
var
|
|
4139
|
+
var import_node_path9, import_source_map_js;
|
|
3436
4140
|
var init_css = __esm({
|
|
3437
4141
|
"src/plugins/css.ts"() {
|
|
3438
4142
|
"use strict";
|
|
3439
|
-
|
|
4143
|
+
import_node_path9 = __toESM(require("path"), 1);
|
|
4144
|
+
import_source_map_js = require("source-map-js");
|
|
3440
4145
|
init_css_engine();
|
|
3441
4146
|
init_tailwind();
|
|
3442
4147
|
}
|
|
@@ -3446,19 +4151,27 @@ var init_css = __esm({
|
|
|
3446
4151
|
function collectChunkCss(chunk, engine) {
|
|
3447
4152
|
const ids = chunk.moduleIds ?? Object.keys(chunk.modules);
|
|
3448
4153
|
let css = "";
|
|
4154
|
+
const moduleIds = [];
|
|
3449
4155
|
for (const id of ids) {
|
|
3450
|
-
const
|
|
3451
|
-
|
|
4156
|
+
const normalizedId = normalizeCssModuleId(id);
|
|
4157
|
+
const styles = engine.styles.get(normalizedId);
|
|
4158
|
+
if (styles) {
|
|
4159
|
+
css += styles + "\n";
|
|
4160
|
+
moduleIds.push(normalizedId);
|
|
4161
|
+
}
|
|
3452
4162
|
}
|
|
3453
|
-
return css;
|
|
4163
|
+
return { css, moduleIds };
|
|
3454
4164
|
}
|
|
3455
4165
|
function cssPostPlugin(config, engine) {
|
|
3456
4166
|
return {
|
|
3457
4167
|
name: "nasti:css-post",
|
|
3458
4168
|
enforce: "post",
|
|
3459
4169
|
async renderChunk(code, chunk) {
|
|
3460
|
-
const css = collectChunkCss(chunk, engine);
|
|
4170
|
+
const { css, moduleIds } = collectChunkCss(chunk, engine);
|
|
3461
4171
|
if (!css) return null;
|
|
4172
|
+
const ownership = { moduleIds, cssFileNames: [] };
|
|
4173
|
+
engine.chunks.set(chunk.fileName, ownership);
|
|
4174
|
+
if (config.build.css.emit === false) return null;
|
|
3462
4175
|
if (!config.build.cssCodeSplit) {
|
|
3463
4176
|
engine.pendingSingle.push(css);
|
|
3464
4177
|
return null;
|
|
@@ -3471,6 +4184,7 @@ function cssPostPlugin(config, engine) {
|
|
|
3471
4184
|
});
|
|
3472
4185
|
const fileName = this.getFileName(ref);
|
|
3473
4186
|
engine.allCss.push(fileName);
|
|
4187
|
+
ownership.cssFileNames.push(fileName);
|
|
3474
4188
|
if (chunk.isEntry) {
|
|
3475
4189
|
const key = chunk.facadeModuleId ?? chunk.name;
|
|
3476
4190
|
const existing = engine.entryCss.get(key) ?? [];
|
|
@@ -3478,100 +4192,34 @@ function cssPostPlugin(config, engine) {
|
|
|
3478
4192
|
engine.entryCss.set(key, existing);
|
|
3479
4193
|
return null;
|
|
3480
4194
|
}
|
|
4195
|
+
if (config.build.css.inject === false) return null;
|
|
3481
4196
|
const href = JSON.stringify(config.base + fileName);
|
|
3482
4197
|
const snippet = `
|
|
3483
4198
|
;(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){}})();`;
|
|
3484
4199
|
return { code: code + snippet, map: null };
|
|
3485
4200
|
},
|
|
3486
4201
|
augmentChunkHash(chunk) {
|
|
3487
|
-
const css = collectChunkCss(chunk, engine);
|
|
4202
|
+
const { css } = collectChunkCss(chunk, engine);
|
|
3488
4203
|
return css || void 0;
|
|
3489
4204
|
},
|
|
3490
4205
|
async generateBundle() {
|
|
3491
4206
|
if (config.build.cssCodeSplit || engine.pendingSingle.length === 0) return;
|
|
3492
|
-
const merged = engine.pendingSingle.join("\n");
|
|
3493
|
-
const finalCss = config.build.cssMinify ? await minifyCss(merged, config) : merged;
|
|
3494
|
-
const ref = this.emitFile({ type: "asset", name: "style.css", source: finalCss });
|
|
3495
|
-
const fileName = this.getFileName(ref);
|
|
3496
|
-
engine.singleFileName = fileName;
|
|
3497
|
-
engine.allCss.push(fileName);
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
}
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
// src/plugins/assets.ts
|
|
3509
|
-
function assetsPlugin(config) {
|
|
3510
|
-
return {
|
|
3511
|
-
name: "nasti:assets",
|
|
3512
|
-
resolveId(source) {
|
|
3513
|
-
if (source.endsWith("?url") || source.endsWith("?raw")) {
|
|
3514
|
-
return source;
|
|
3515
|
-
}
|
|
3516
|
-
return null;
|
|
3517
|
-
},
|
|
3518
|
-
load(id) {
|
|
3519
|
-
const ext = import_node_path9.default.extname(id.replace(/\?.*$/, ""));
|
|
3520
|
-
if (id.endsWith("?raw")) {
|
|
3521
|
-
const file = id.slice(0, -4);
|
|
3522
|
-
if (import_node_fs7.default.existsSync(file)) {
|
|
3523
|
-
const content = import_node_fs7.default.readFileSync(file, "utf-8");
|
|
3524
|
-
return `export default ${JSON.stringify(content)}`;
|
|
3525
|
-
}
|
|
3526
|
-
}
|
|
3527
|
-
if (id.endsWith("?url") || ASSET_EXTENSIONS.has(ext)) {
|
|
3528
|
-
const file = id.replace(/\?.*$/, "");
|
|
3529
|
-
if (!import_node_fs7.default.existsSync(file)) return null;
|
|
3530
|
-
if (config.command === "serve") {
|
|
3531
|
-
const url = "/" + import_node_path9.default.relative(config.root, file);
|
|
3532
|
-
return `export default ${JSON.stringify(url)}`;
|
|
3533
|
-
}
|
|
3534
|
-
const content = import_node_fs7.default.readFileSync(file);
|
|
3535
|
-
const hash = import_node_crypto.default.createHash("sha256").update(content).digest("hex").slice(0, 8);
|
|
3536
|
-
const basename = import_node_path9.default.basename(file, ext);
|
|
3537
|
-
const hashedName = `${config.build.assetsDir}/${basename}.${hash}${ext}`;
|
|
3538
|
-
return `export default ${JSON.stringify(config.base + hashedName)}`;
|
|
3539
|
-
}
|
|
3540
|
-
return null;
|
|
3541
|
-
}
|
|
3542
|
-
};
|
|
3543
|
-
}
|
|
3544
|
-
var import_node_path9, import_node_fs7, import_node_crypto, ASSET_EXTENSIONS;
|
|
3545
|
-
var init_assets = __esm({
|
|
3546
|
-
"src/plugins/assets.ts"() {
|
|
3547
|
-
"use strict";
|
|
3548
|
-
import_node_path9 = __toESM(require("path"), 1);
|
|
3549
|
-
import_node_fs7 = __toESM(require("fs"), 1);
|
|
3550
|
-
import_node_crypto = __toESM(require("crypto"), 1);
|
|
3551
|
-
ASSET_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
3552
|
-
".png",
|
|
3553
|
-
".jpg",
|
|
3554
|
-
".jpeg",
|
|
3555
|
-
".gif",
|
|
3556
|
-
".svg",
|
|
3557
|
-
".ico",
|
|
3558
|
-
".webp",
|
|
3559
|
-
".avif",
|
|
3560
|
-
".mp4",
|
|
3561
|
-
".webm",
|
|
3562
|
-
".ogg",
|
|
3563
|
-
".mp3",
|
|
3564
|
-
".wav",
|
|
3565
|
-
".flac",
|
|
3566
|
-
".aac",
|
|
3567
|
-
".woff",
|
|
3568
|
-
".woff2",
|
|
3569
|
-
".eot",
|
|
3570
|
-
".ttf",
|
|
3571
|
-
".otf",
|
|
3572
|
-
".pdf",
|
|
3573
|
-
".txt"
|
|
3574
|
-
]);
|
|
4207
|
+
const merged = engine.pendingSingle.join("\n");
|
|
4208
|
+
const finalCss = config.build.cssMinify ? await minifyCss(merged, config) : merged;
|
|
4209
|
+
const ref = this.emitFile({ type: "asset", name: "style.css", source: finalCss });
|
|
4210
|
+
const fileName = this.getFileName(ref);
|
|
4211
|
+
engine.singleFileName = fileName;
|
|
4212
|
+
engine.allCss.push(fileName);
|
|
4213
|
+
for (const ownership of engine.chunks.values()) {
|
|
4214
|
+
if (ownership.moduleIds.length > 0) ownership.cssFileNames.push(fileName);
|
|
4215
|
+
}
|
|
4216
|
+
}
|
|
4217
|
+
};
|
|
4218
|
+
}
|
|
4219
|
+
var init_css_post = __esm({
|
|
4220
|
+
"src/plugins/css-post.ts"() {
|
|
4221
|
+
"use strict";
|
|
4222
|
+
init_css_engine();
|
|
3575
4223
|
}
|
|
3576
4224
|
});
|
|
3577
4225
|
|
|
@@ -3585,9 +4233,10 @@ async function loadVueCompiler() {
|
|
|
3585
4233
|
return null;
|
|
3586
4234
|
}
|
|
3587
4235
|
}
|
|
3588
|
-
function vuePlugin(config) {
|
|
4236
|
+
function vuePlugin(config, environmentName = "client") {
|
|
3589
4237
|
const isDev = config.command === "serve";
|
|
3590
4238
|
const descriptorCache = /* @__PURE__ */ new Map();
|
|
4239
|
+
const vueOptions = config.environments[environmentName]?.vue ?? {};
|
|
3591
4240
|
return {
|
|
3592
4241
|
name: "nasti:vue",
|
|
3593
4242
|
enforce: "pre",
|
|
@@ -3607,32 +4256,63 @@ function vuePlugin(config) {
|
|
|
3607
4256
|
const sfc = await loadVueCompiler();
|
|
3608
4257
|
if (!sfc) return null;
|
|
3609
4258
|
const [, filePath, indexStr] = match;
|
|
3610
|
-
let
|
|
3611
|
-
if (!
|
|
4259
|
+
let cached2 = descriptorCache.get(filePath);
|
|
4260
|
+
if (!cached2) {
|
|
3612
4261
|
try {
|
|
3613
|
-
const
|
|
3614
|
-
const
|
|
3615
|
-
const
|
|
4262
|
+
const fs13 = await import("fs");
|
|
4263
|
+
const rawSource = fs13.readFileSync(filePath, "utf-8");
|
|
4264
|
+
const transformedSfc = await applySourceTransform(
|
|
4265
|
+
vueOptions.transformSfc,
|
|
4266
|
+
rawSource,
|
|
4267
|
+
{ filename: filePath, environmentName, type: "sfc" }
|
|
4268
|
+
);
|
|
4269
|
+
const parsed = sfc.parse(transformedSfc.code, {
|
|
4270
|
+
...vueOptions.parse,
|
|
4271
|
+
filename: filePath,
|
|
4272
|
+
sourceMap: true
|
|
4273
|
+
});
|
|
3616
4274
|
if (parsed.errors.length) return null;
|
|
3617
|
-
|
|
3618
|
-
|
|
4275
|
+
cached2 = {
|
|
4276
|
+
descriptor: parsed.descriptor,
|
|
4277
|
+
sourceMap: transformedSfc.map
|
|
4278
|
+
};
|
|
4279
|
+
descriptorCache.set(filePath, cached2);
|
|
3619
4280
|
} catch {
|
|
3620
4281
|
return null;
|
|
3621
4282
|
}
|
|
3622
4283
|
}
|
|
4284
|
+
const { descriptor, sourceMap: sfcSourceMap } = cached2;
|
|
3623
4285
|
const index2 = parseInt(indexStr ?? "0", 10);
|
|
3624
4286
|
const style = descriptor.styles[index2];
|
|
3625
4287
|
if (!style) return null;
|
|
3626
4288
|
const scopeId = hashId(filePath);
|
|
4289
|
+
const transformedStyle = await applySourceTransform(
|
|
4290
|
+
vueOptions.transformStyle,
|
|
4291
|
+
style.content,
|
|
4292
|
+
{ filename: filePath, environmentName, type: "style", index: index2 }
|
|
4293
|
+
);
|
|
4294
|
+
const wantsStyleSourceMap = !!config.build.sourcemap || transformedStyle.map != null || sfcSourceMap != null;
|
|
4295
|
+
const styleInputMap = wantsStyleSourceMap ? composeSourceMapChain(
|
|
4296
|
+
[transformedStyle.map, style.map, sfcSourceMap],
|
|
4297
|
+
{ filename: filePath, environmentName, type: "style", index: index2 }
|
|
4298
|
+
) : void 0;
|
|
3627
4299
|
const result = await sfc.compileStyleAsync({
|
|
3628
|
-
|
|
4300
|
+
...vueOptions.style,
|
|
4301
|
+
source: transformedStyle.code,
|
|
3629
4302
|
filename: filePath,
|
|
3630
4303
|
id: `data-v-${scopeId}`,
|
|
3631
4304
|
scoped: style.scoped ?? false,
|
|
4305
|
+
inMap: styleInputMap,
|
|
3632
4306
|
// <style lang="scss|less|stylus"> 需经对应预处理器(缺省 undefined = 纯 CSS)
|
|
3633
4307
|
preprocessLang: style.lang
|
|
3634
4308
|
});
|
|
3635
|
-
|
|
4309
|
+
if (transformedStyle.map != null && result.map == null) {
|
|
4310
|
+
warnUnchainableMap(
|
|
4311
|
+
{ filename: filePath, environmentName, type: "style", index: index2 },
|
|
4312
|
+
"compiler-sfc did not return a style map"
|
|
4313
|
+
);
|
|
4314
|
+
}
|
|
4315
|
+
return wantsStyleSourceMap ? { code: result.code, map: result.map } : result.code;
|
|
3636
4316
|
},
|
|
3637
4317
|
async transform(code, id) {
|
|
3638
4318
|
if (!VUE_FILE_RE.test(id) && !VUE_QUERY_RE.test(id)) return null;
|
|
@@ -3644,57 +4324,144 @@ function vuePlugin(config) {
|
|
|
3644
4324
|
if (VUE_QUERY_RE.test(id)) {
|
|
3645
4325
|
return null;
|
|
3646
4326
|
}
|
|
3647
|
-
const
|
|
4327
|
+
const transformedSfc = await applySourceTransform(
|
|
4328
|
+
vueOptions.transformSfc,
|
|
4329
|
+
code,
|
|
4330
|
+
{ filename: id, environmentName, type: "sfc" }
|
|
4331
|
+
);
|
|
4332
|
+
code = transformedSfc.code;
|
|
4333
|
+
const { descriptor, errors } = sfc.parse(code, {
|
|
4334
|
+
...vueOptions.parse,
|
|
4335
|
+
filename: id,
|
|
4336
|
+
sourceMap: true
|
|
4337
|
+
});
|
|
3648
4338
|
if (errors.length) {
|
|
3649
|
-
|
|
4339
|
+
const firstError = errors[0];
|
|
4340
|
+
console.error(
|
|
4341
|
+
`[nasti:vue] Parse error in ${id}:`,
|
|
4342
|
+
typeof firstError === "string" ? firstError : firstError.message
|
|
4343
|
+
);
|
|
3650
4344
|
return null;
|
|
3651
4345
|
}
|
|
3652
|
-
descriptorCache.set(id,
|
|
4346
|
+
descriptorCache.set(id, {
|
|
4347
|
+
descriptor,
|
|
4348
|
+
sourceMap: transformedSfc.map
|
|
4349
|
+
});
|
|
3653
4350
|
const scopeId = hashId(id);
|
|
4351
|
+
const wantsSourceMap = !!config.build.sourcemap || transformedSfc.map != null;
|
|
3654
4352
|
let scriptCode = "";
|
|
4353
|
+
let scriptMap;
|
|
3655
4354
|
if (descriptor.script || descriptor.scriptSetup) {
|
|
4355
|
+
const inlineTemplate = vueOptions.script?.inlineTemplate !== false;
|
|
3656
4356
|
const compiled = sfc.compileScript(descriptor, {
|
|
4357
|
+
...vueOptions.script,
|
|
3657
4358
|
id: scopeId,
|
|
3658
4359
|
isProd: !isDev,
|
|
3659
|
-
inlineTemplate
|
|
4360
|
+
inlineTemplate,
|
|
4361
|
+
sourceMap: wantsSourceMap,
|
|
3660
4362
|
// 让 compileScript 产出 `const __sfc__ = ...`(而非默认的 `export default {...}`)。
|
|
3661
4363
|
// 否则下方追加的 `__sfc__.render` / `__sfc__.__scopeId` / HMR 记录会引用一个
|
|
3662
4364
|
// 不存在的 `__sfc__`,并与 compileScript 自带的 `export default` 形成双重默认导出。
|
|
3663
4365
|
genDefaultAs: "__sfc__"
|
|
3664
4366
|
});
|
|
3665
4367
|
scriptCode = compiled.content;
|
|
4368
|
+
scriptMap = composeSourceMapChain(
|
|
4369
|
+
[compiled.map, transformedSfc.map],
|
|
4370
|
+
{ filename: id, environmentName, type: "sfc" }
|
|
4371
|
+
);
|
|
4372
|
+
if (transformedSfc.map != null && scriptMap == null) {
|
|
4373
|
+
warnUnchainableMap(
|
|
4374
|
+
{ filename: id, environmentName, type: "sfc" },
|
|
4375
|
+
"compiler-sfc did not return a script map"
|
|
4376
|
+
);
|
|
4377
|
+
}
|
|
3666
4378
|
}
|
|
3667
4379
|
let templateCode = "";
|
|
3668
|
-
|
|
4380
|
+
let templateMap;
|
|
4381
|
+
const scriptSetupIsInline = !!descriptor.scriptSetup && vueOptions.script?.inlineTemplate !== false;
|
|
4382
|
+
if (descriptor.template && !scriptSetupIsInline) {
|
|
4383
|
+
const transformedTemplate = await applySourceTransform(
|
|
4384
|
+
vueOptions.transformTemplate,
|
|
4385
|
+
descriptor.template.content,
|
|
4386
|
+
{ filename: id, environmentName, type: "template" }
|
|
4387
|
+
);
|
|
4388
|
+
const templateInputMap = composeSourceMapChain(
|
|
4389
|
+
[
|
|
4390
|
+
transformedTemplate.map,
|
|
4391
|
+
descriptor.template.map,
|
|
4392
|
+
transformedSfc.map
|
|
4393
|
+
],
|
|
4394
|
+
{ filename: id, environmentName, type: "template" }
|
|
4395
|
+
);
|
|
4396
|
+
const customCompilerOptions = vueOptions.template?.compilerOptions ?? {};
|
|
3669
4397
|
const compiled = sfc.compileTemplate({
|
|
3670
|
-
|
|
4398
|
+
...vueOptions.template,
|
|
4399
|
+
source: transformedTemplate.code,
|
|
3671
4400
|
filename: id,
|
|
3672
4401
|
id: scopeId,
|
|
3673
|
-
|
|
4402
|
+
inMap: templateInputMap,
|
|
4403
|
+
compilerOptions: {
|
|
4404
|
+
...customCompilerOptions,
|
|
4405
|
+
scopeId: `data-v-${scopeId}`
|
|
4406
|
+
}
|
|
3674
4407
|
});
|
|
3675
4408
|
templateCode = compiled.code;
|
|
4409
|
+
if (wantsSourceMap || transformedTemplate.map != null) {
|
|
4410
|
+
templateMap = compiled.map;
|
|
4411
|
+
}
|
|
4412
|
+
if (transformedTemplate.map != null && templateMap == null) {
|
|
4413
|
+
warnUnchainableMap(
|
|
4414
|
+
{ filename: id, environmentName, type: "template" },
|
|
4415
|
+
"compiler-sfc did not return a template map"
|
|
4416
|
+
);
|
|
4417
|
+
}
|
|
3676
4418
|
}
|
|
3677
|
-
|
|
4419
|
+
const outputNode = new import_source_map_js2.SourceNode();
|
|
4420
|
+
let hasMappedOutput = false;
|
|
4421
|
+
const append = (fragment, map) => {
|
|
4422
|
+
const normalizedMap = normalizeSourceMap(
|
|
4423
|
+
map,
|
|
4424
|
+
{ filename: id, environmentName, type: "sfc" }
|
|
4425
|
+
);
|
|
4426
|
+
if (!normalizedMap) {
|
|
4427
|
+
outputNode.add(fragment);
|
|
4428
|
+
return;
|
|
4429
|
+
}
|
|
4430
|
+
try {
|
|
4431
|
+
outputNode.add(
|
|
4432
|
+
import_source_map_js2.SourceNode.fromStringWithSourceMap(
|
|
4433
|
+
fragment,
|
|
4434
|
+
new import_source_map_js2.SourceMapConsumer(normalizedMap)
|
|
4435
|
+
)
|
|
4436
|
+
);
|
|
4437
|
+
hasMappedOutput = true;
|
|
4438
|
+
} catch (error) {
|
|
4439
|
+
warnUnchainableMap(
|
|
4440
|
+
{ filename: id, environmentName, type: "sfc" },
|
|
4441
|
+
`source-map assembly failed: ${error instanceof Error ? error.message : String(error)}`
|
|
4442
|
+
);
|
|
4443
|
+
outputNode.add(fragment);
|
|
4444
|
+
}
|
|
4445
|
+
};
|
|
4446
|
+
append(scriptCode || "const __sfc__ = {}", scriptMap);
|
|
3678
4447
|
if (templateCode) {
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
__sfc__.render = render
|
|
3684
|
-
`;
|
|
4448
|
+
append("\n");
|
|
4449
|
+
append(templateCode, templateMap);
|
|
4450
|
+
append("\n");
|
|
4451
|
+
append("\n__sfc__.render = render\n");
|
|
3685
4452
|
}
|
|
3686
4453
|
if (descriptor.styles.length > 0) {
|
|
3687
4454
|
for (let i = 0; i < descriptor.styles.length; i++) {
|
|
3688
|
-
|
|
4455
|
+
append(`
|
|
3689
4456
|
import "${id}?vue&type=style&index=${i}&lang.css"
|
|
3690
|
-
|
|
4457
|
+
`);
|
|
3691
4458
|
}
|
|
3692
4459
|
}
|
|
3693
|
-
|
|
4460
|
+
append(`
|
|
3694
4461
|
__sfc__.__scopeId = "data-v-${scopeId}"
|
|
3695
|
-
|
|
4462
|
+
`);
|
|
3696
4463
|
if (isDev) {
|
|
3697
|
-
|
|
4464
|
+
append(`
|
|
3698
4465
|
__sfc__.__hmrId = ${JSON.stringify(scopeId)}
|
|
3699
4466
|
if (typeof __VUE_HMR_RUNTIME__ !== 'undefined') {
|
|
3700
4467
|
__VUE_HMR_RUNTIME__.createRecord(__sfc__.__hmrId, __sfc__)
|
|
@@ -3708,17 +4475,34 @@ if (import.meta.hot) {
|
|
|
3708
4475
|
}
|
|
3709
4476
|
})
|
|
3710
4477
|
}
|
|
3711
|
-
|
|
4478
|
+
`);
|
|
4479
|
+
}
|
|
4480
|
+
append("\nexport default __sfc__\n");
|
|
4481
|
+
const renderedOutput = outputNode.toStringWithSourceMap({ file: id });
|
|
4482
|
+
const output = renderedOutput.code;
|
|
4483
|
+
const outputMap = hasMappedOutput ? renderedOutput.map.toJSON() : void 0;
|
|
4484
|
+
if (transformedSfc.map != null && outputMap == null) {
|
|
4485
|
+
warnUnchainableMap(
|
|
4486
|
+
{ filename: id, environmentName, type: "sfc" },
|
|
4487
|
+
"the compiled SFC output contained no chainable mappings"
|
|
4488
|
+
);
|
|
3712
4489
|
}
|
|
3713
|
-
output += `
|
|
3714
|
-
export default __sfc__
|
|
3715
|
-
`;
|
|
3716
4490
|
const lang = descriptor.scriptSetup?.lang ?? descriptor.script?.lang;
|
|
3717
4491
|
if (lang === "ts") {
|
|
3718
|
-
const transpiled = transformCode(`${id}.ts`, output, {
|
|
3719
|
-
|
|
4492
|
+
const transpiled = transformCode(`${id}.ts`, output, {
|
|
4493
|
+
sourcemap: wantsSourceMap,
|
|
4494
|
+
target: config.build.target
|
|
4495
|
+
});
|
|
4496
|
+
const transpiledMap = transpiled.map ? JSON.parse(transpiled.map) : void 0;
|
|
4497
|
+
return {
|
|
4498
|
+
code: transpiled.code,
|
|
4499
|
+
map: composeSourceMapChain(
|
|
4500
|
+
[transpiledMap, outputMap],
|
|
4501
|
+
{ filename: id, environmentName, type: "sfc" }
|
|
4502
|
+
)
|
|
4503
|
+
};
|
|
3720
4504
|
}
|
|
3721
|
-
return { code: output };
|
|
4505
|
+
return { code: output, map: outputMap };
|
|
3722
4506
|
},
|
|
3723
4507
|
handleHotUpdate(ctx) {
|
|
3724
4508
|
const { file, modules } = ctx;
|
|
@@ -3732,17 +4516,77 @@ export default __sfc__
|
|
|
3732
4516
|
}
|
|
3733
4517
|
};
|
|
3734
4518
|
}
|
|
4519
|
+
async function applySourceTransform(transform2, source, context) {
|
|
4520
|
+
if (!transform2) return { code: source };
|
|
4521
|
+
const result = await transform2(source, context);
|
|
4522
|
+
return typeof result === "string" ? { code: result } : result;
|
|
4523
|
+
}
|
|
4524
|
+
function normalizeSourceMap(map, context) {
|
|
4525
|
+
if (map == null) return void 0;
|
|
4526
|
+
try {
|
|
4527
|
+
const value = typeof map === "string" ? JSON.parse(map) : map;
|
|
4528
|
+
if (value && typeof value === "object" && Array.isArray(value.sources) && Array.isArray(value.names) && typeof value.mappings === "string") {
|
|
4529
|
+
return value;
|
|
4530
|
+
}
|
|
4531
|
+
} catch {
|
|
4532
|
+
}
|
|
4533
|
+
warnUnchainableMap(context, "the provided map is not a valid source map");
|
|
4534
|
+
return void 0;
|
|
4535
|
+
}
|
|
4536
|
+
function composeSourceMapChain(maps, context) {
|
|
4537
|
+
const pending = maps.filter((map) => map != null);
|
|
4538
|
+
if (pending.length === 0) return void 0;
|
|
4539
|
+
let composed = normalizeSourceMap(pending.shift(), context);
|
|
4540
|
+
for (const map of pending) {
|
|
4541
|
+
const input = normalizeSourceMap(map, context);
|
|
4542
|
+
if (!input) continue;
|
|
4543
|
+
if (!composed) {
|
|
4544
|
+
composed = input;
|
|
4545
|
+
continue;
|
|
4546
|
+
}
|
|
4547
|
+
try {
|
|
4548
|
+
const consumer = new import_source_map_js2.SourceMapConsumer(composed);
|
|
4549
|
+
if (consumer.sources.length !== 1) {
|
|
4550
|
+
warnUnchainableMap(
|
|
4551
|
+
context,
|
|
4552
|
+
"a generated map has multiple sources and cannot be chained safely"
|
|
4553
|
+
);
|
|
4554
|
+
continue;
|
|
4555
|
+
}
|
|
4556
|
+
const generator = import_source_map_js2.SourceMapGenerator.fromSourceMap(consumer);
|
|
4557
|
+
generator.applySourceMap(
|
|
4558
|
+
new import_source_map_js2.SourceMapConsumer(input),
|
|
4559
|
+
consumer.sources[0]
|
|
4560
|
+
);
|
|
4561
|
+
composed = generator.toJSON();
|
|
4562
|
+
} catch (error) {
|
|
4563
|
+
warnUnchainableMap(
|
|
4564
|
+
context,
|
|
4565
|
+
`source-map composition failed: ${error instanceof Error ? error.message : String(error)}`
|
|
4566
|
+
);
|
|
4567
|
+
}
|
|
4568
|
+
}
|
|
4569
|
+
return composed;
|
|
4570
|
+
}
|
|
4571
|
+
function warnUnchainableMap(context, reason) {
|
|
4572
|
+
debug3?.(
|
|
4573
|
+
`source map warning for ${context.filename} (${context.type}, ${context.environmentName}): ${reason}`
|
|
4574
|
+
);
|
|
4575
|
+
}
|
|
3735
4576
|
function hashId(filename) {
|
|
3736
4577
|
return import_node_crypto2.default.createHash("sha256").update(filename).digest("hex").slice(0, 8);
|
|
3737
4578
|
}
|
|
3738
|
-
var import_node_crypto2, VUE_FILE_RE, VUE_QUERY_RE, compiler;
|
|
4579
|
+
var import_node_crypto2, import_source_map_js2, VUE_FILE_RE, VUE_QUERY_RE, debug3, compiler;
|
|
3739
4580
|
var init_vue = __esm({
|
|
3740
4581
|
"src/plugins/vue.ts"() {
|
|
3741
4582
|
"use strict";
|
|
3742
4583
|
import_node_crypto2 = __toESM(require("crypto"), 1);
|
|
4584
|
+
import_source_map_js2 = require("source-map-js");
|
|
3743
4585
|
init_transformer();
|
|
4586
|
+
init_debug();
|
|
3744
4587
|
VUE_FILE_RE = /\.vue$/;
|
|
3745
4588
|
VUE_QUERY_RE = /\.vue\?vue&type=(script|template|style)(&index=\d+)?(&lang[.=]\w+)?/;
|
|
4589
|
+
debug3 = createDebugger("nasti:vue");
|
|
3746
4590
|
compiler = null;
|
|
3747
4591
|
}
|
|
3748
4592
|
});
|
|
@@ -3750,16 +4594,27 @@ var init_vue = __esm({
|
|
|
3750
4594
|
// src/plugins/builtins.ts
|
|
3751
4595
|
function resolvePluginList(config, userPlugins, opts = {}) {
|
|
3752
4596
|
const isServe = config.command === "serve";
|
|
4597
|
+
let environmentOptions;
|
|
4598
|
+
if (opts.environmentName) {
|
|
4599
|
+
environmentOptions = config.environments[opts.environmentName];
|
|
4600
|
+
if (!environmentOptions) {
|
|
4601
|
+
throw new Error(
|
|
4602
|
+
`[nasti] unknown environment "${opts.environmentName}" \u2014 declare it in config.environments`
|
|
4603
|
+
);
|
|
4604
|
+
}
|
|
4605
|
+
}
|
|
4606
|
+
const pluginConfig = environmentOptions ? { ...config, resolve: environmentOptions.resolve, build: environmentOptions.build } : config;
|
|
4607
|
+
const consumer = opts.consumer ?? environmentOptions?.consumer;
|
|
3753
4608
|
return [
|
|
3754
4609
|
// vuePlugin 排最前(enforce: 'pre' 语义):.vue 先编译成 JS 再走后续管道
|
|
3755
|
-
...config.framework === "vue" ? [vuePlugin(
|
|
3756
|
-
resolvePlugin(
|
|
3757
|
-
cssPlugin(
|
|
3758
|
-
assetsPlugin(
|
|
3759
|
-
...isServe ? [htmlPlugin(
|
|
4610
|
+
...config.framework === "vue" ? [vuePlugin(pluginConfig, opts.environmentName ?? "client")] : [],
|
|
4611
|
+
resolvePlugin(pluginConfig),
|
|
4612
|
+
cssPlugin(pluginConfig, opts.cssEngine, consumer),
|
|
4613
|
+
assetsPlugin(pluginConfig),
|
|
4614
|
+
...isServe ? [htmlPlugin(pluginConfig)] : [],
|
|
3760
4615
|
...userPlugins,
|
|
3761
4616
|
// cssPostPlugin 最后(enforce: 'post' 语义):renderChunk 聚合抽取
|
|
3762
|
-
...!isServe && opts.cssEngine ? [cssPostPlugin(
|
|
4617
|
+
...!isServe && opts.cssEngine ? [cssPostPlugin(pluginConfig, opts.cssEngine)] : []
|
|
3763
4618
|
];
|
|
3764
4619
|
}
|
|
3765
4620
|
var init_builtins = __esm({
|
|
@@ -3788,7 +4643,7 @@ function createModuleRunner(environment) {
|
|
|
3788
4643
|
}
|
|
3789
4644
|
return new NastiModuleRunner(environment);
|
|
3790
4645
|
}
|
|
3791
|
-
var import_node_path10, import_node_fs8, import_node_module4, import_node_url4,
|
|
4646
|
+
var import_node_path10, import_node_fs8, import_node_module4, import_node_url4, debug4, NODE_BUILTINS, NastiModuleRunner, AsyncFunction;
|
|
3792
4647
|
var init_runnable_environment = __esm({
|
|
3793
4648
|
"src/server/runnable-environment.ts"() {
|
|
3794
4649
|
"use strict";
|
|
@@ -3799,7 +4654,7 @@ var init_runnable_environment = __esm({
|
|
|
3799
4654
|
init_transformer();
|
|
3800
4655
|
init_env();
|
|
3801
4656
|
init_debug();
|
|
3802
|
-
|
|
4657
|
+
debug4 = createDebugger("nasti:ssr");
|
|
3803
4658
|
NODE_BUILTINS = /* @__PURE__ */ new Set([...import_node_module4.builtinModules, ...import_node_module4.builtinModules.map((m) => `node:${m}`)]);
|
|
3804
4659
|
NastiModuleRunner = class {
|
|
3805
4660
|
environment;
|
|
@@ -3877,6 +4732,7 @@ var init_runnable_environment = __esm({
|
|
|
3877
4732
|
if (shouldTransform(cleanId)) {
|
|
3878
4733
|
const result = transformCode(cleanId, code, {
|
|
3879
4734
|
sourcemap: false,
|
|
4735
|
+
target: this.environment.options.build.target,
|
|
3880
4736
|
jsxRuntime: "automatic",
|
|
3881
4737
|
jsxImportSource: this.config.framework === "vue" ? "vue" : "react"
|
|
3882
4738
|
});
|
|
@@ -3893,7 +4749,7 @@ var init_runnable_environment = __esm({
|
|
|
3893
4749
|
);
|
|
3894
4750
|
}
|
|
3895
4751
|
const runnerResult = await moduleRunnerTransform(resolvedId, code);
|
|
3896
|
-
|
|
4752
|
+
debug4?.(`fetchModule ${resolvedId} (${runnerResult.deps?.length ?? 0} deps)`);
|
|
3897
4753
|
return { id: resolvedId, code: runnerResult.code };
|
|
3898
4754
|
}
|
|
3899
4755
|
completeExtension(id) {
|
|
@@ -4012,7 +4868,7 @@ async function tryNativeReporterPlugin(config, logger) {
|
|
|
4012
4868
|
logInfo: (msg) => logger.info(msg)
|
|
4013
4869
|
});
|
|
4014
4870
|
} catch (err) {
|
|
4015
|
-
|
|
4871
|
+
debug5?.(`native viteReporterPlugin unavailable, falling back to JS table: ${err}`);
|
|
4016
4872
|
return null;
|
|
4017
4873
|
}
|
|
4018
4874
|
}
|
|
@@ -4067,7 +4923,7 @@ function warnLargeChunks(output, config, logger) {
|
|
|
4067
4923
|
)
|
|
4068
4924
|
);
|
|
4069
4925
|
}
|
|
4070
|
-
var import_node_path11, import_node_zlib, import_picocolors5,
|
|
4926
|
+
var import_node_path11, import_node_zlib, import_picocolors5, debug5, numberFormatter;
|
|
4071
4927
|
var init_reporter = __esm({
|
|
4072
4928
|
"src/build/reporter.ts"() {
|
|
4073
4929
|
"use strict";
|
|
@@ -4075,7 +4931,7 @@ var init_reporter = __esm({
|
|
|
4075
4931
|
import_node_zlib = require("zlib");
|
|
4076
4932
|
import_picocolors5 = __toESM(require("picocolors"), 1);
|
|
4077
4933
|
init_debug();
|
|
4078
|
-
|
|
4934
|
+
debug5 = createDebugger("nasti:reporter");
|
|
4079
4935
|
numberFormatter = new Intl.NumberFormat("en", {
|
|
4080
4936
|
maximumFractionDigits: 2,
|
|
4081
4937
|
minimumFractionDigits: 2
|
|
@@ -4083,6 +4939,156 @@ var init_reporter = __esm({
|
|
|
4083
4939
|
}
|
|
4084
4940
|
});
|
|
4085
4941
|
|
|
4942
|
+
// src/core/build-app-context.ts
|
|
4943
|
+
function createBuildAppContext(config, results) {
|
|
4944
|
+
const output = [];
|
|
4945
|
+
const emitted = /* @__PURE__ */ new Set();
|
|
4946
|
+
const outDir = import_node_path12.default.resolve(config.root, config.build.outDir);
|
|
4947
|
+
let environmentArtifacts;
|
|
4948
|
+
return {
|
|
4949
|
+
config,
|
|
4950
|
+
results,
|
|
4951
|
+
get output() {
|
|
4952
|
+
return Object.freeze([...output]);
|
|
4953
|
+
},
|
|
4954
|
+
getResult(environmentName) {
|
|
4955
|
+
return results[environmentName];
|
|
4956
|
+
},
|
|
4957
|
+
getArtifact(environmentName, fileName) {
|
|
4958
|
+
const normalized = normalizeEnvironmentFileName(fileName);
|
|
4959
|
+
return results[environmentName]?.output.find(
|
|
4960
|
+
(artifact) => normalizeEnvironmentFileName(artifact.fileName) === normalized
|
|
4961
|
+
);
|
|
4962
|
+
},
|
|
4963
|
+
getEntry(environmentName, entryName) {
|
|
4964
|
+
const result = results[environmentName];
|
|
4965
|
+
const fileName = result?.entries?.[entryName];
|
|
4966
|
+
if (!fileName) return void 0;
|
|
4967
|
+
return result.output.find(
|
|
4968
|
+
(artifact) => normalizeEnvironmentFileName(artifact.fileName) === normalizeEnvironmentFileName(fileName)
|
|
4969
|
+
);
|
|
4970
|
+
},
|
|
4971
|
+
getManifest(environmentName) {
|
|
4972
|
+
return results[environmentName]?.manifest;
|
|
4973
|
+
},
|
|
4974
|
+
getChunk(environmentName, fileName) {
|
|
4975
|
+
const normalized = normalizeEnvironmentFileName(fileName);
|
|
4976
|
+
return results[environmentName]?.chunks?.[normalized];
|
|
4977
|
+
},
|
|
4978
|
+
getCss(environmentName) {
|
|
4979
|
+
return results[environmentName]?.css;
|
|
4980
|
+
},
|
|
4981
|
+
getSourceMap(environmentName, fileName) {
|
|
4982
|
+
const normalized = normalizeEnvironmentFileName(fileName);
|
|
4983
|
+
return results[environmentName]?.sourceMaps?.[normalized];
|
|
4984
|
+
},
|
|
4985
|
+
resolvePublicPath(environmentName, fileName) {
|
|
4986
|
+
const result = results[environmentName];
|
|
4987
|
+
if (!result) return void 0;
|
|
4988
|
+
const normalized = normalizeEnvironmentFileName(fileName);
|
|
4989
|
+
const base = result.publicPath ?? config.base;
|
|
4990
|
+
return joinPublicPath(base, normalized);
|
|
4991
|
+
},
|
|
4992
|
+
emitFile(file) {
|
|
4993
|
+
const fileName = normalizeAppFileName(file.fileName);
|
|
4994
|
+
const collisionKey = artifactCollisionKey(fileName);
|
|
4995
|
+
if (emitted.has(collisionKey)) {
|
|
4996
|
+
throw new Error(`[nasti] app artifact already emitted: ${fileName}`);
|
|
4997
|
+
}
|
|
4998
|
+
environmentArtifacts ??= collectEnvironmentArtifacts(config, results, outDir);
|
|
4999
|
+
if (environmentArtifacts.has(collisionKey)) {
|
|
5000
|
+
throw new Error(`[nasti] app artifact conflicts with environment output: ${fileName}`);
|
|
5001
|
+
}
|
|
5002
|
+
const target = import_node_path12.default.resolve(outDir, ...fileName.split("/"));
|
|
5003
|
+
const relative = import_node_path12.default.relative(outDir, target);
|
|
5004
|
+
if (relative.startsWith("..") || import_node_path12.default.isAbsolute(relative)) {
|
|
5005
|
+
throw new Error(`[nasti] app artifact must stay inside build.outDir: ${file.fileName}`);
|
|
5006
|
+
}
|
|
5007
|
+
assertNoSymlinkComponents(outDir, fileName);
|
|
5008
|
+
import_node_fs9.default.mkdirSync(import_node_path12.default.dirname(target), { recursive: true });
|
|
5009
|
+
import_node_fs9.default.writeFileSync(target, file.source);
|
|
5010
|
+
const artifact = {
|
|
5011
|
+
...file,
|
|
5012
|
+
fileName,
|
|
5013
|
+
type: "asset"
|
|
5014
|
+
};
|
|
5015
|
+
emitted.add(collisionKey);
|
|
5016
|
+
output.push(artifact);
|
|
5017
|
+
return fileName;
|
|
5018
|
+
}
|
|
5019
|
+
};
|
|
5020
|
+
}
|
|
5021
|
+
function joinPublicPath(base, fileName) {
|
|
5022
|
+
return `${base.endsWith("/") ? base : `${base}/`}${fileName.replace(/^\//, "")}`;
|
|
5023
|
+
}
|
|
5024
|
+
function normalizeEnvironmentFileName(fileName) {
|
|
5025
|
+
return import_node_path12.default.posix.normalize(fileName.replace(/\\/g, "/").replace(/^\.\//, ""));
|
|
5026
|
+
}
|
|
5027
|
+
function isInvalidEnvironmentFileName(fileName) {
|
|
5028
|
+
return !fileName || fileName === "." || fileName === ".." || fileName.startsWith("../") || import_node_path12.default.posix.isAbsolute(fileName) || /^[A-Za-z]:\//.test(fileName);
|
|
5029
|
+
}
|
|
5030
|
+
function normalizeAppFileName(fileName) {
|
|
5031
|
+
const normalized = normalizeEnvironmentFileName(fileName);
|
|
5032
|
+
if (isInvalidEnvironmentFileName(normalized)) {
|
|
5033
|
+
throw new Error(`[nasti] invalid app artifact fileName: ${fileName}`);
|
|
5034
|
+
}
|
|
5035
|
+
return normalized;
|
|
5036
|
+
}
|
|
5037
|
+
function artifactCollisionKey(fileName) {
|
|
5038
|
+
return normalizeEnvironmentFileName(fileName).toLowerCase();
|
|
5039
|
+
}
|
|
5040
|
+
function collectEnvironmentArtifacts(config, results, appOutDir) {
|
|
5041
|
+
const occupied = /* @__PURE__ */ new Set();
|
|
5042
|
+
for (const [environmentName, result] of Object.entries(results)) {
|
|
5043
|
+
const environment = config.environments[environmentName];
|
|
5044
|
+
if (!environment) continue;
|
|
5045
|
+
const environmentOutDir = import_node_path12.default.resolve(config.root, environment.build.outDir);
|
|
5046
|
+
for (const artifact of result.output) {
|
|
5047
|
+
const artifactPath = import_node_path12.default.resolve(
|
|
5048
|
+
environmentOutDir,
|
|
5049
|
+
...normalizeEnvironmentFileName(artifact.fileName).split("/")
|
|
5050
|
+
);
|
|
5051
|
+
const relative = import_node_path12.default.relative(appOutDir, artifactPath);
|
|
5052
|
+
if (!relative.startsWith("..") && !import_node_path12.default.isAbsolute(relative)) {
|
|
5053
|
+
occupied.add(artifactCollisionKey(relative));
|
|
5054
|
+
}
|
|
5055
|
+
}
|
|
5056
|
+
}
|
|
5057
|
+
return occupied;
|
|
5058
|
+
}
|
|
5059
|
+
function assertNoSymlinkComponents(outDir, fileName) {
|
|
5060
|
+
let current = outDir;
|
|
5061
|
+
for (const segment of fileName.split("/")) {
|
|
5062
|
+
current = import_node_path12.default.join(current, segment);
|
|
5063
|
+
let stats;
|
|
5064
|
+
try {
|
|
5065
|
+
stats = import_node_fs9.default.lstatSync(current);
|
|
5066
|
+
} catch (error) {
|
|
5067
|
+
if (error.code === "ENOENT") continue;
|
|
5068
|
+
throw error;
|
|
5069
|
+
}
|
|
5070
|
+
if (stats.isSymbolicLink()) {
|
|
5071
|
+
throw new Error(`[nasti] app artifact path cannot traverse a symlink: ${fileName}`);
|
|
5072
|
+
}
|
|
5073
|
+
}
|
|
5074
|
+
}
|
|
5075
|
+
function inferEnvironmentEntries(output) {
|
|
5076
|
+
const entries = {};
|
|
5077
|
+
for (const artifact of output) {
|
|
5078
|
+
if (artifact.type !== "chunk" || !artifact.isEntry || !artifact.name) continue;
|
|
5079
|
+
entries[artifact.name] = normalizeEnvironmentFileName(artifact.fileName);
|
|
5080
|
+
}
|
|
5081
|
+
return Object.keys(entries).length > 0 ? entries : void 0;
|
|
5082
|
+
}
|
|
5083
|
+
var import_node_fs9, import_node_path12;
|
|
5084
|
+
var init_build_app_context = __esm({
|
|
5085
|
+
"src/core/build-app-context.ts"() {
|
|
5086
|
+
"use strict";
|
|
5087
|
+
import_node_fs9 = __toESM(require("fs"), 1);
|
|
5088
|
+
import_node_path12 = __toESM(require("path"), 1);
|
|
5089
|
+
}
|
|
5090
|
+
});
|
|
5091
|
+
|
|
4086
5092
|
// src/build/index.ts
|
|
4087
5093
|
var build_exports = {};
|
|
4088
5094
|
__export(build_exports, {
|
|
@@ -4096,9 +5102,14 @@ function getRolldownOptions(environment, entryPoints, rolldownPlugins) {
|
|
|
4096
5102
|
const config = environment.config;
|
|
4097
5103
|
const envOptions = environment.options;
|
|
4098
5104
|
const isServer = environment.consumer === "server";
|
|
4099
|
-
const outDir =
|
|
5105
|
+
const outDir = import_node_path13.default.resolve(config.root, envOptions.build.outDir);
|
|
4100
5106
|
const assetsDir = envOptions.build.assetsDir;
|
|
4101
|
-
const {
|
|
5107
|
+
const {
|
|
5108
|
+
output: userOutput,
|
|
5109
|
+
transform: userTransform,
|
|
5110
|
+
resolve: userResolve,
|
|
5111
|
+
...restInputOptions
|
|
5112
|
+
} = envOptions.build.rolldownOptions;
|
|
4102
5113
|
const vueDefine = config.framework === "vue" ? {
|
|
4103
5114
|
__VUE_OPTIONS_API__: "true",
|
|
4104
5115
|
__VUE_PROD_DEVTOOLS__: "false",
|
|
@@ -4110,27 +5121,34 @@ function getRolldownOptions(environment, entryPoints, rolldownPlugins) {
|
|
|
4110
5121
|
const inputOptions = {
|
|
4111
5122
|
...restInputOptions,
|
|
4112
5123
|
input: entryPoints,
|
|
4113
|
-
transform: {
|
|
5124
|
+
transform: {
|
|
5125
|
+
...userTransform,
|
|
5126
|
+
target: userTransform?.target ?? envOptions.build.target,
|
|
5127
|
+
define: mergedDefine
|
|
5128
|
+
},
|
|
4114
5129
|
plugins: rolldownPlugins,
|
|
5130
|
+
// client/server consumer 都必须使用当前环境的 conditions/mainFields;Lynx
|
|
5131
|
+
// BG/MT 通常同为 client consumer,但仍可能声明不同的运行时条件。
|
|
5132
|
+
resolve: {
|
|
5133
|
+
...userResolve ?? {},
|
|
5134
|
+
// Environment API 是条件解析的唯一高层入口,优先于继承来的底层选项。
|
|
5135
|
+
conditionNames: envOptions.resolve.conditions,
|
|
5136
|
+
mainFields: envOptions.resolve.mainFields
|
|
5137
|
+
},
|
|
4115
5138
|
...isServer ? {
|
|
4116
5139
|
platform: restInputOptions.platform ?? "node",
|
|
4117
|
-
resolve: {
|
|
4118
|
-
conditionNames: envOptions.resolve.conditions,
|
|
4119
|
-
mainFields: envOptions.resolve.mainFields,
|
|
4120
|
-
...restInputOptions.resolve
|
|
4121
|
-
},
|
|
4122
5140
|
// server 产物:node 内建恒外部化;bare specifier 默认外部化
|
|
4123
5141
|
//(同 Vite ssr.external 默认 —— 依赖由 node_modules 运行时解析),
|
|
4124
5142
|
// 相对/绝对/虚拟模块照常打包。需要内联依赖时经 rolldownOptions.external 覆盖。
|
|
4125
5143
|
external: restInputOptions.external ?? ((id) => {
|
|
4126
5144
|
if (NODE_BUILTINS2.has(id)) return true;
|
|
4127
|
-
return !id.startsWith(".") && !
|
|
5145
|
+
return !id.startsWith(".") && !import_node_path13.default.isAbsolute(id) && !id.startsWith("\0");
|
|
4128
5146
|
})
|
|
4129
5147
|
} : {}
|
|
4130
5148
|
};
|
|
4131
5149
|
const outputOptions = isServer ? {
|
|
4132
5150
|
format: "esm",
|
|
4133
|
-
sourcemap:
|
|
5151
|
+
sourcemap: envOptions.build.sourcemap,
|
|
4134
5152
|
minify: !!envOptions.build.minify,
|
|
4135
5153
|
entryFileNames: "[name].js",
|
|
4136
5154
|
chunkFileNames: "chunks/[name]-[hash].js",
|
|
@@ -4139,7 +5157,7 @@ function getRolldownOptions(environment, entryPoints, rolldownPlugins) {
|
|
|
4139
5157
|
dir: outDir
|
|
4140
5158
|
} : {
|
|
4141
5159
|
format: "esm",
|
|
4142
|
-
sourcemap:
|
|
5160
|
+
sourcemap: envOptions.build.sourcemap,
|
|
4143
5161
|
minify: !!envOptions.build.minify,
|
|
4144
5162
|
entryFileNames: `${assetsDir}/[name].[hash].js`,
|
|
4145
5163
|
chunkFileNames: `${assetsDir}/[name].[hash].js`,
|
|
@@ -4151,27 +5169,177 @@ function getRolldownOptions(environment, entryPoints, rolldownPlugins) {
|
|
|
4151
5169
|
};
|
|
4152
5170
|
return { inputOptions, outputOptions, outDir };
|
|
4153
5171
|
}
|
|
4154
|
-
function toRolldownPlugins(plugins) {
|
|
5172
|
+
function toRolldownPlugins(plugins, environment) {
|
|
5173
|
+
const wrap = (hook) => {
|
|
5174
|
+
if (!hook) return hook;
|
|
5175
|
+
return function(...args) {
|
|
5176
|
+
return hook.apply(attachEnvironment(this, environment), args);
|
|
5177
|
+
};
|
|
5178
|
+
};
|
|
4155
5179
|
return plugins.map((p) => ({
|
|
4156
5180
|
name: p.name,
|
|
4157
|
-
resolveId: p.resolveId,
|
|
4158
|
-
load: p.load,
|
|
4159
|
-
transform: p.transform,
|
|
4160
|
-
buildStart: p.buildStart,
|
|
4161
|
-
buildEnd: p.buildEnd,
|
|
5181
|
+
resolveId: wrap(p.resolveId),
|
|
5182
|
+
load: wrap(p.load),
|
|
5183
|
+
transform: wrap(p.transform),
|
|
5184
|
+
buildStart: wrap(p.buildStart),
|
|
5185
|
+
buildEnd: wrap(p.buildEnd),
|
|
4162
5186
|
// closeBundle 在 bundle.close() 时触发 —— PWA manifest/SW 等终态产物依赖
|
|
4163
|
-
closeBundle: p.closeBundle,
|
|
4164
|
-
renderChunk: p.renderChunk,
|
|
4165
|
-
augmentChunkHash: p.augmentChunkHash,
|
|
4166
|
-
generateBundle: p.generateBundle
|
|
5187
|
+
closeBundle: wrap(p.closeBundle),
|
|
5188
|
+
renderChunk: wrap(p.renderChunk),
|
|
5189
|
+
augmentChunkHash: wrap(p.augmentChunkHash),
|
|
5190
|
+
generateBundle: wrap(p.generateBundle)
|
|
4167
5191
|
}));
|
|
4168
5192
|
}
|
|
5193
|
+
function attachEnvironment(context, environment) {
|
|
5194
|
+
if (context?.environment === environment) return context;
|
|
5195
|
+
try {
|
|
5196
|
+
Object.defineProperty(context, "environment", {
|
|
5197
|
+
configurable: true,
|
|
5198
|
+
enumerable: false,
|
|
5199
|
+
writable: false,
|
|
5200
|
+
value: environment
|
|
5201
|
+
});
|
|
5202
|
+
return context;
|
|
5203
|
+
} catch {
|
|
5204
|
+
return new Proxy(context, {
|
|
5205
|
+
get(target, property) {
|
|
5206
|
+
if (property === "environment") return environment;
|
|
5207
|
+
const value = Reflect.get(target, property, target);
|
|
5208
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
5209
|
+
},
|
|
5210
|
+
set(target, property, value) {
|
|
5211
|
+
return Reflect.set(target, property, value, target);
|
|
5212
|
+
}
|
|
5213
|
+
});
|
|
5214
|
+
}
|
|
5215
|
+
}
|
|
5216
|
+
function finalizeEnvironmentResult(environment, result) {
|
|
5217
|
+
const metadata = environment.getBuildMetadata();
|
|
5218
|
+
const inferredEntries = inferEnvironmentEntries(result.output);
|
|
5219
|
+
const entries = {
|
|
5220
|
+
...inferredEntries,
|
|
5221
|
+
...metadata.entries,
|
|
5222
|
+
...result.entries
|
|
5223
|
+
};
|
|
5224
|
+
const normalizedEntries = Object.fromEntries(
|
|
5225
|
+
Object.entries(entries).map(([name, fileName]) => {
|
|
5226
|
+
const normalized = normalizeEnvironmentFileName(fileName);
|
|
5227
|
+
if (isInvalidEnvironmentFileName(normalized)) {
|
|
5228
|
+
throw new Error(
|
|
5229
|
+
`[nasti] environment "${environment.name}" returned invalid entry "${name}": ${fileName}`
|
|
5230
|
+
);
|
|
5231
|
+
}
|
|
5232
|
+
return [name, normalized];
|
|
5233
|
+
})
|
|
5234
|
+
);
|
|
5235
|
+
const inferredMetadata = inferOutputMetadata(environment, result.output);
|
|
5236
|
+
return {
|
|
5237
|
+
publicPath: environment.config.base,
|
|
5238
|
+
...inferredMetadata,
|
|
5239
|
+
...metadata,
|
|
5240
|
+
...result,
|
|
5241
|
+
output: result.output,
|
|
5242
|
+
chunks: {
|
|
5243
|
+
...inferredMetadata.chunks,
|
|
5244
|
+
...metadata.chunks,
|
|
5245
|
+
...result.chunks
|
|
5246
|
+
},
|
|
5247
|
+
assets: {
|
|
5248
|
+
...inferredMetadata.assets,
|
|
5249
|
+
...metadata.assets,
|
|
5250
|
+
...result.assets
|
|
5251
|
+
},
|
|
5252
|
+
sourceMaps: {
|
|
5253
|
+
...inferredMetadata.sourceMaps,
|
|
5254
|
+
...metadata.sourceMaps,
|
|
5255
|
+
...result.sourceMaps
|
|
5256
|
+
},
|
|
5257
|
+
...Object.keys(normalizedEntries).length > 0 ? { entries: normalizedEntries } : {}
|
|
5258
|
+
};
|
|
5259
|
+
}
|
|
5260
|
+
function inferOutputMetadata(environment, output) {
|
|
5261
|
+
const chunks = {};
|
|
5262
|
+
const assets = {};
|
|
5263
|
+
const sourceMaps = {};
|
|
5264
|
+
const cssChunks = environment.getBuildMetadata().css?.chunks ?? {};
|
|
5265
|
+
const assetModules = environment.getAssetModules();
|
|
5266
|
+
const publicPath = environment.config.base;
|
|
5267
|
+
for (const artifact of output) {
|
|
5268
|
+
const fileName = normalizeEnvironmentFileName(artifact.fileName);
|
|
5269
|
+
if (artifact.map != null) sourceMaps[fileName] = artifact.map;
|
|
5270
|
+
if (artifact.type === "chunk") {
|
|
5271
|
+
const moduleIds = [...artifact.moduleIds ?? []];
|
|
5272
|
+
chunks[fileName] = {
|
|
5273
|
+
fileName,
|
|
5274
|
+
name: artifact.name ?? fileName,
|
|
5275
|
+
isEntry: !!artifact.isEntry,
|
|
5276
|
+
isDynamicEntry: !!artifact.isDynamicEntry,
|
|
5277
|
+
imports: [...artifact.imports ?? []],
|
|
5278
|
+
dynamicImports: [...artifact.dynamicImports ?? []],
|
|
5279
|
+
moduleIds,
|
|
5280
|
+
css: [...cssChunks[fileName]?.cssFileNames ?? []],
|
|
5281
|
+
assets: [
|
|
5282
|
+
...new Set(
|
|
5283
|
+
moduleIds.map((id) => assetModules[id]).filter((asset) => !!asset)
|
|
5284
|
+
)
|
|
5285
|
+
]
|
|
5286
|
+
};
|
|
5287
|
+
} else if (artifact.type === "asset") {
|
|
5288
|
+
assets[fileName] = {
|
|
5289
|
+
fileName,
|
|
5290
|
+
names: [...artifact.names ?? (artifact.name ? [artifact.name] : [])],
|
|
5291
|
+
publicPath: joinPublicPath(publicPath, fileName)
|
|
5292
|
+
};
|
|
5293
|
+
}
|
|
5294
|
+
}
|
|
5295
|
+
return { chunks, assets, sourceMaps };
|
|
5296
|
+
}
|
|
5297
|
+
function prepareBuildOutputDirectories(config, buildableNames) {
|
|
5298
|
+
const directories = /* @__PURE__ */ new Set();
|
|
5299
|
+
const protectedPaths = /* @__PURE__ */ new Set();
|
|
5300
|
+
const clientIsBuilt = buildableNames.includes("client");
|
|
5301
|
+
if (!clientIsBuilt && config.build.emptyOutDir) {
|
|
5302
|
+
directories.add(import_node_path13.default.resolve(config.root, config.build.outDir));
|
|
5303
|
+
}
|
|
5304
|
+
for (const name of buildableNames) {
|
|
5305
|
+
const environment = config.environments[name];
|
|
5306
|
+
const outDir = import_node_path13.default.resolve(config.root, environment.build.outDir);
|
|
5307
|
+
if (!environment.build.emptyOutDir) {
|
|
5308
|
+
protectedPaths.add(outDir);
|
|
5309
|
+
continue;
|
|
5310
|
+
}
|
|
5311
|
+
if (!environment.driver) directories.add(outDir);
|
|
5312
|
+
}
|
|
5313
|
+
const containsPath = (parent, child) => {
|
|
5314
|
+
const relative = import_node_path13.default.relative(parent, child);
|
|
5315
|
+
return relative === "" || !relative.startsWith("..") && !import_node_path13.default.isAbsolute(relative);
|
|
5316
|
+
};
|
|
5317
|
+
const roots = [...directories].filter(
|
|
5318
|
+
(directory) => ![...protectedPaths].some((protectedPath) => containsPath(directory, protectedPath))
|
|
5319
|
+
).sort((a, b) => a.length - b.length).filter(
|
|
5320
|
+
(directory, index2, all) => !all.slice(0, index2).some((parent) => containsPath(parent, directory))
|
|
5321
|
+
);
|
|
5322
|
+
for (const directory of roots) {
|
|
5323
|
+
if (import_node_fs10.default.existsSync(directory)) import_node_fs10.default.rmSync(directory, { recursive: true, force: true });
|
|
5324
|
+
}
|
|
5325
|
+
}
|
|
5326
|
+
function assertDriverBuildResult(environment, result) {
|
|
5327
|
+
const output = result != null && typeof result === "object" ? result.output : void 0;
|
|
5328
|
+
const hasValidOutput = Array.isArray(output) && output.every(
|
|
5329
|
+
(artifact) => artifact != null && typeof artifact === "object" && typeof artifact.fileName === "string" && typeof artifact.type === "string"
|
|
5330
|
+
);
|
|
5331
|
+
if (!hasValidOutput) {
|
|
5332
|
+
throw new Error(
|
|
5333
|
+
`[nasti] environment "${environment.name}" driver "${environment.driver?.name}" returned an invalid build result; expected { output: EnvironmentBuildOutput[] }`
|
|
5334
|
+
);
|
|
5335
|
+
}
|
|
5336
|
+
}
|
|
4169
5337
|
function resolveClientEntries(config, html) {
|
|
4170
5338
|
const configuredEntries = config.environments.client?.entry ?? [];
|
|
4171
5339
|
if (configuredEntries.length > 0) return configuredEntries;
|
|
4172
5340
|
const entryPoints = [];
|
|
4173
5341
|
const htmlFile = config.environments.client?.html;
|
|
4174
|
-
const htmlDir = htmlFile ?
|
|
5342
|
+
const htmlDir = htmlFile ? import_node_path13.default.dirname(htmlFile) : config.root;
|
|
4175
5343
|
if (html) {
|
|
4176
5344
|
const scriptMatches = html.matchAll(/<script[^>]+src=["']([^"']+)["'][^>]*>/gi);
|
|
4177
5345
|
for (const match of scriptMatches) {
|
|
@@ -4179,7 +5347,7 @@ function resolveClientEntries(config, html) {
|
|
|
4179
5347
|
if (src && !src.startsWith("http")) {
|
|
4180
5348
|
const cleanSrc = src.split(/[?#]/, 1)[0];
|
|
4181
5349
|
entryPoints.push(
|
|
4182
|
-
cleanSrc.startsWith("/") ?
|
|
5350
|
+
cleanSrc.startsWith("/") ? import_node_path13.default.resolve(config.root, cleanSrc.replace(/^\//, "")) : import_node_path13.default.resolve(htmlDir, cleanSrc)
|
|
4183
5351
|
);
|
|
4184
5352
|
}
|
|
4185
5353
|
}
|
|
@@ -4187,8 +5355,8 @@ function resolveClientEntries(config, html) {
|
|
|
4187
5355
|
if (entryPoints.length === 0) {
|
|
4188
5356
|
const fallbackEntries = ["src/main.ts", "src/main.tsx", "src/main.js", "src/index.ts", "src/index.tsx", "src/index.js"];
|
|
4189
5357
|
for (const entry of fallbackEntries) {
|
|
4190
|
-
const fullPath =
|
|
4191
|
-
if (
|
|
5358
|
+
const fullPath = import_node_path13.default.resolve(config.root, entry);
|
|
5359
|
+
if (import_node_fs10.default.existsSync(fullPath)) {
|
|
4192
5360
|
entryPoints.push(fullPath);
|
|
4193
5361
|
break;
|
|
4194
5362
|
}
|
|
@@ -4203,6 +5371,7 @@ function createOxcTransformPlugin(config, environment) {
|
|
|
4203
5371
|
if (!shouldTransform(id)) return null;
|
|
4204
5372
|
const result = transformCode(id, code, {
|
|
4205
5373
|
sourcemap: !!environment.options.build.sourcemap,
|
|
5374
|
+
target: environment.options.build.target,
|
|
4206
5375
|
jsxRuntime: "automatic",
|
|
4207
5376
|
jsxImportSource: config.framework === "vue" ? "vue" : "react"
|
|
4208
5377
|
});
|
|
@@ -4216,16 +5385,20 @@ async function build(inlineConfig = {}) {
|
|
|
4216
5385
|
const startTime = performance.now();
|
|
4217
5386
|
logger.info(
|
|
4218
5387
|
import_picocolors6.default.cyan(`
|
|
4219
|
-
nasti v${"2.
|
|
4220
|
-
);
|
|
4221
|
-
debug5?.(`root: ${config.root}`);
|
|
4222
|
-
const buildableNames = Object.keys(config.environments).filter(
|
|
4223
|
-
(name) => name === "client" || config.environments[name].entry.length > 0 || !!config.environments[name].driver
|
|
5388
|
+
nasti v${"2.4.1"} `) + import_picocolors6.default.green(`building for ${config.mode}...`)
|
|
4224
5389
|
);
|
|
5390
|
+
debug6?.(`root: ${config.root}`);
|
|
5391
|
+
const buildableNames = Object.keys(config.environments).filter((name) => {
|
|
5392
|
+
const environment = config.environments[name];
|
|
5393
|
+
if (!environment.buildEnabled) return false;
|
|
5394
|
+
return name === "client" || environment.entry.length > 0 || !!environment.driver;
|
|
5395
|
+
});
|
|
4225
5396
|
buildableNames.sort((a, b) => a === "client" ? -1 : b === "client" ? 1 : 0);
|
|
5397
|
+
prepareBuildOutputDirectories(config, buildableNames);
|
|
4226
5398
|
const environments = {};
|
|
4227
5399
|
const environmentResults = {};
|
|
4228
5400
|
const initializedEnvironments = [];
|
|
5401
|
+
const buildAppContext = createBuildAppContext(config, environmentResults);
|
|
4229
5402
|
let clientOutput = [];
|
|
4230
5403
|
let buildFailed = false;
|
|
4231
5404
|
try {
|
|
@@ -4236,12 +5409,12 @@ nasti v${"2.3.1"} `) + import_picocolors6.default.green(`building for ${config.m
|
|
|
4236
5409
|
environmentResults[name] = built.result;
|
|
4237
5410
|
if (name === "client") clientOutput = built.result.output;
|
|
4238
5411
|
if (buildableNames.length > 1) {
|
|
4239
|
-
|
|
5412
|
+
debug6?.(`environment "${name}" built (${built.result.output.length} files)`);
|
|
4240
5413
|
}
|
|
4241
5414
|
}
|
|
4242
5415
|
const pluginApi = getPluginApi(config);
|
|
4243
5416
|
for (const plugin of config.plugins) {
|
|
4244
|
-
await plugin.afterBuildApp?.(environmentResults, pluginApi);
|
|
5417
|
+
await plugin.afterBuildApp?.(environmentResults, pluginApi, buildAppContext);
|
|
4245
5418
|
}
|
|
4246
5419
|
} catch (error) {
|
|
4247
5420
|
buildFailed = true;
|
|
@@ -4268,22 +5441,31 @@ nasti v${"2.3.1"} `) + import_picocolors6.default.green(`building for ${config.m
|
|
|
4268
5441
|
}
|
|
4269
5442
|
}
|
|
4270
5443
|
const elapsed = ((performance.now() - startTime) / 1e3).toFixed(2);
|
|
4271
|
-
const
|
|
5444
|
+
const allOutput = [...Object.values(environments).flat(), ...buildAppContext.output];
|
|
5445
|
+
const totalSize = allOutput.reduce((sum, chunk) => {
|
|
4272
5446
|
const content = chunk.type === "chunk" ? chunk.code : chunk.source;
|
|
4273
5447
|
if (content == null) return sum;
|
|
4274
5448
|
return sum + (typeof content === "string" ? Buffer.byteLength(content) : content.byteLength);
|
|
4275
5449
|
}, 0);
|
|
4276
|
-
const fileCount =
|
|
5450
|
+
const fileCount = allOutput.length;
|
|
4277
5451
|
const envSuffix = buildableNames.length > 1 ? ` (${buildableNames.join(" + ")})` : "";
|
|
4278
5452
|
logger.info(import_picocolors6.default.green(`\u2713 built in ${elapsed}s`) + import_picocolors6.default.dim(envSuffix));
|
|
4279
5453
|
logger.info(import_picocolors6.default.dim(` ${fileCount} files, ${displaySize(totalSize)} total \u2192 ${config.build.outDir}/`));
|
|
4280
|
-
return {
|
|
5454
|
+
return {
|
|
5455
|
+
output: clientOutput,
|
|
5456
|
+
environments,
|
|
5457
|
+
environmentResults,
|
|
5458
|
+
appOutput: [...buildAppContext.output]
|
|
5459
|
+
};
|
|
4281
5460
|
}
|
|
4282
5461
|
async function buildClientEnvironment(config) {
|
|
4283
5462
|
const logger = config.logger;
|
|
4284
|
-
const outDir =
|
|
5463
|
+
const outDir = import_node_path13.default.resolve(config.root, config.build.outDir);
|
|
4285
5464
|
const cssEngine = createCssEngine();
|
|
4286
|
-
const pluginList = resolvePluginList(config, config.plugins, {
|
|
5465
|
+
const pluginList = resolvePluginList(config, config.plugins, {
|
|
5466
|
+
cssEngine,
|
|
5467
|
+
environmentName: "client"
|
|
5468
|
+
});
|
|
4287
5469
|
const clientEnv = new NastiEnvironment("client", config, {
|
|
4288
5470
|
mode: "build",
|
|
4289
5471
|
plugins: pluginList,
|
|
@@ -4298,13 +5480,11 @@ async function buildClientEnvironment(config) {
|
|
|
4298
5480
|
);
|
|
4299
5481
|
}
|
|
4300
5482
|
const result = await clientEnv.driver.build(clientEnv.getDriverContext());
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
if (config.build.emptyOutDir && import_node_fs9.default.existsSync(outDir)) {
|
|
4304
|
-
import_node_fs9.default.rmSync(outDir, { recursive: true, force: true });
|
|
5483
|
+
assertDriverBuildResult(clientEnv, result);
|
|
5484
|
+
return { environment: clientEnv, result: finalizeEnvironmentResult(clientEnv, result) };
|
|
4305
5485
|
}
|
|
4306
|
-
|
|
4307
|
-
const htmlFile = config.environments.client.html ??
|
|
5486
|
+
import_node_fs10.default.mkdirSync(outDir, { recursive: true });
|
|
5487
|
+
const htmlFile = config.environments.client.html ?? import_node_path13.default.resolve(config.root, "index.html");
|
|
4308
5488
|
const html = await readHtmlFile(config.root, htmlFile);
|
|
4309
5489
|
const entryPoints = resolveClientEntries(config, html);
|
|
4310
5490
|
if (entryPoints.length === 0) {
|
|
@@ -4314,7 +5494,7 @@ async function buildClientEnvironment(config) {
|
|
|
4314
5494
|
const nativeReporter = config.logLevel === "silent" ? null : await tryNativeReporterPlugin(config, logger);
|
|
4315
5495
|
const rolldownPlugins = [
|
|
4316
5496
|
createOxcTransformPlugin(config, clientEnv),
|
|
4317
|
-
...toRolldownPlugins(allPlugins),
|
|
5497
|
+
...toRolldownPlugins(allPlugins, clientEnv),
|
|
4318
5498
|
...nativeReporter ? [nativeReporter] : []
|
|
4319
5499
|
];
|
|
4320
5500
|
const { inputOptions, outputOptions } = getRolldownOptions(
|
|
@@ -4325,6 +5505,7 @@ async function buildClientEnvironment(config) {
|
|
|
4325
5505
|
const bundle2 = await (0, import_rolldown.rolldown)(inputOptions);
|
|
4326
5506
|
const { output } = await bundle2.write(outputOptions);
|
|
4327
5507
|
await bundle2.close();
|
|
5508
|
+
clientEnv.setBuildMetadata({ css: getCssMetadata(cssEngine) });
|
|
4328
5509
|
if (html) {
|
|
4329
5510
|
let processedHtml = html;
|
|
4330
5511
|
const htmlPlugins = [...allPlugins.filter((p) => p.transformIndexHtml), htmlPlugin(config)];
|
|
@@ -4338,7 +5519,9 @@ async function buildClientEnvironment(config) {
|
|
|
4338
5519
|
processedHtml = processHtml(processedHtml, result);
|
|
4339
5520
|
}
|
|
4340
5521
|
}
|
|
4341
|
-
|
|
5522
|
+
if (clientEnv.options.build.css.inject !== false) {
|
|
5523
|
+
processedHtml = injectCssLinks(processedHtml, cssEngine, config);
|
|
5524
|
+
}
|
|
4342
5525
|
for (const chunk of output) {
|
|
4343
5526
|
if (chunk.type === "chunk" && chunk.isEntry && chunk.facadeModuleId) {
|
|
4344
5527
|
processedHtml = replaceEntryScript(
|
|
@@ -4351,13 +5534,16 @@ async function buildClientEnvironment(config) {
|
|
|
4351
5534
|
);
|
|
4352
5535
|
}
|
|
4353
5536
|
}
|
|
4354
|
-
|
|
5537
|
+
import_node_fs10.default.writeFileSync(import_node_path13.default.resolve(outDir, "index.html"), processedHtml);
|
|
4355
5538
|
}
|
|
4356
5539
|
if (!nativeReporter && config.logLevel !== "silent") {
|
|
4357
5540
|
reportBuildOutput(output, config, logger);
|
|
4358
5541
|
}
|
|
4359
5542
|
warnLargeChunks(output, config, logger);
|
|
4360
|
-
return {
|
|
5543
|
+
return {
|
|
5544
|
+
environment: clientEnv,
|
|
5545
|
+
result: finalizeEnvironmentResult(clientEnv, { output })
|
|
5546
|
+
};
|
|
4361
5547
|
} catch (error) {
|
|
4362
5548
|
try {
|
|
4363
5549
|
await clientEnv.close();
|
|
@@ -4373,7 +5559,12 @@ async function buildClientEnvironment(config) {
|
|
|
4373
5559
|
async function buildServerEnvironment(config, name) {
|
|
4374
5560
|
const envOptions = config.environments[name];
|
|
4375
5561
|
const logger = config.logger;
|
|
4376
|
-
const
|
|
5562
|
+
const cssEngine = envOptions.consumer === "client" ? createCssEngine() : void 0;
|
|
5563
|
+
const pluginList = resolvePluginList(config, config.plugins, {
|
|
5564
|
+
consumer: envOptions.consumer,
|
|
5565
|
+
environmentName: name,
|
|
5566
|
+
cssEngine
|
|
5567
|
+
});
|
|
4377
5568
|
const environment = new NastiEnvironment(name, config, {
|
|
4378
5569
|
mode: "build",
|
|
4379
5570
|
plugins: pluginList,
|
|
@@ -4389,38 +5580,40 @@ async function buildServerEnvironment(config, name) {
|
|
|
4389
5580
|
}
|
|
4390
5581
|
try {
|
|
4391
5582
|
const result = await environment.driver.build(environment.getDriverContext());
|
|
4392
|
-
|
|
5583
|
+
assertDriverBuildResult(environment, result);
|
|
5584
|
+
return { environment, result: finalizeEnvironmentResult(environment, result) };
|
|
4393
5585
|
} catch (error) {
|
|
4394
5586
|
await environment.close();
|
|
4395
5587
|
throw error;
|
|
4396
5588
|
}
|
|
4397
5589
|
}
|
|
4398
5590
|
for (const entry of envOptions.entry) {
|
|
4399
|
-
if (!
|
|
5591
|
+
if (!import_node_fs10.default.existsSync(entry)) {
|
|
4400
5592
|
await environment.close();
|
|
4401
5593
|
throw new Error(`[nasti] environment "${name}" entry not found: ${entry}`);
|
|
4402
5594
|
}
|
|
4403
5595
|
}
|
|
4404
5596
|
const rolldownPlugins = [
|
|
4405
5597
|
createOxcTransformPlugin(config, environment),
|
|
4406
|
-
...toRolldownPlugins(environment.plugins)
|
|
5598
|
+
...toRolldownPlugins(environment.plugins, environment)
|
|
4407
5599
|
];
|
|
4408
5600
|
const { inputOptions, outputOptions, outDir } = getRolldownOptions(
|
|
4409
5601
|
environment,
|
|
4410
5602
|
envOptions.entry,
|
|
4411
5603
|
rolldownPlugins
|
|
4412
5604
|
);
|
|
4413
|
-
|
|
4414
|
-
import_node_fs9.default.rmSync(outDir, { recursive: true, force: true });
|
|
4415
|
-
}
|
|
4416
|
-
import_node_fs9.default.mkdirSync(outDir, { recursive: true });
|
|
5605
|
+
import_node_fs10.default.mkdirSync(outDir, { recursive: true });
|
|
4417
5606
|
const bundle2 = await (0, import_rolldown.rolldown)(inputOptions);
|
|
4418
5607
|
const { output } = await bundle2.write(outputOptions);
|
|
4419
5608
|
await bundle2.close();
|
|
5609
|
+
if (cssEngine) environment.setBuildMetadata({ css: getCssMetadata(cssEngine) });
|
|
4420
5610
|
logger.info(
|
|
4421
|
-
import_picocolors6.default.dim(` [${name}] `) + output.map((o) =>
|
|
5611
|
+
import_picocolors6.default.dim(` [${name}] `) + output.map((o) => import_node_path13.default.join(envOptions.build.outDir, o.fileName)).join(import_picocolors6.default.dim(", "))
|
|
4422
5612
|
);
|
|
4423
|
-
return {
|
|
5613
|
+
return {
|
|
5614
|
+
environment,
|
|
5615
|
+
result: finalizeEnvironmentResult(environment, { output })
|
|
5616
|
+
};
|
|
4424
5617
|
}
|
|
4425
5618
|
function injectCssLinks(html, cssEngine, config) {
|
|
4426
5619
|
const cssLinkTags = [];
|
|
@@ -4447,9 +5640,9 @@ function escapeRegExp(string) {
|
|
|
4447
5640
|
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4448
5641
|
}
|
|
4449
5642
|
function replaceEntryScript(html, facadeModuleId, fileName, config, htmlFile, urlPrefix) {
|
|
4450
|
-
const rootRelative =
|
|
4451
|
-
const resolvedHtmlFile =
|
|
4452
|
-
const htmlRelative =
|
|
5643
|
+
const rootRelative = import_node_path13.default.relative(config.root, facadeModuleId).split(import_node_path13.default.sep).join("/");
|
|
5644
|
+
const resolvedHtmlFile = import_node_path13.default.resolve(config.root, htmlFile);
|
|
5645
|
+
const htmlRelative = import_node_path13.default.relative(import_node_path13.default.dirname(resolvedHtmlFile), facadeModuleId).split(import_node_path13.default.sep).join("/");
|
|
4453
5646
|
const candidates = /* @__PURE__ */ new Set([
|
|
4454
5647
|
rootRelative,
|
|
4455
5648
|
`/${rootRelative}`,
|
|
@@ -4465,12 +5658,12 @@ function replaceEntryScript(html, facadeModuleId, fileName, config, htmlFile, ur
|
|
|
4465
5658
|
}
|
|
4466
5659
|
return processed;
|
|
4467
5660
|
}
|
|
4468
|
-
var
|
|
5661
|
+
var import_node_path13, import_node_fs10, import_node_module5, import_rolldown, import_picocolors6, debug6, NODE_BUILTINS2;
|
|
4469
5662
|
var init_build = __esm({
|
|
4470
5663
|
"src/build/index.ts"() {
|
|
4471
5664
|
"use strict";
|
|
4472
|
-
|
|
4473
|
-
|
|
5665
|
+
import_node_path13 = __toESM(require("path"), 1);
|
|
5666
|
+
import_node_fs10 = __toESM(require("fs"), 1);
|
|
4474
5667
|
import_node_module5 = require("module");
|
|
4475
5668
|
import_rolldown = require("rolldown");
|
|
4476
5669
|
init_config();
|
|
@@ -4483,8 +5676,9 @@ var init_build = __esm({
|
|
|
4483
5676
|
init_reporter();
|
|
4484
5677
|
init_debug();
|
|
4485
5678
|
init_plugin_api();
|
|
5679
|
+
init_build_app_context();
|
|
4486
5680
|
import_picocolors6 = __toESM(require("picocolors"), 1);
|
|
4487
|
-
|
|
5681
|
+
debug6 = createDebugger("nasti:build");
|
|
4488
5682
|
NODE_BUILTINS2 = /* @__PURE__ */ new Set([...import_node_module5.builtinModules, ...import_node_module5.builtinModules.map((m) => `node:${m}`)]);
|
|
4489
5683
|
}
|
|
4490
5684
|
});
|
|
@@ -4508,7 +5702,7 @@ async function createBundledDevServer(opts) {
|
|
|
4508
5702
|
}
|
|
4509
5703
|
} catch (err) {
|
|
4510
5704
|
throw new Error(
|
|
4511
|
-
`[nasti] experimental.bundledDev requires rolldown's experimental dev() API (locked
|
|
5705
|
+
`[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.`
|
|
4512
5706
|
);
|
|
4513
5707
|
}
|
|
4514
5708
|
const html = await readHtmlFile(config.root, config.environments.client?.html);
|
|
@@ -4526,7 +5720,7 @@ async function createBundledDevServer(opts) {
|
|
|
4526
5720
|
createReactRefreshRuntimePlugin(entryPoints),
|
|
4527
5721
|
createBundledOxcRefreshPlugin()
|
|
4528
5722
|
] : [],
|
|
4529
|
-
...stripCatchAllLoad(toRolldownPlugins(clientEnv.plugins)),
|
|
5723
|
+
...stripCatchAllLoad(toRolldownPlugins(clientEnv.plugins, clientEnv)),
|
|
4530
5724
|
...useReactRefresh ? [
|
|
4531
5725
|
refreshWrapperFn({
|
|
4532
5726
|
cwd: config.root,
|
|
@@ -4561,7 +5755,7 @@ async function createBundledDevServer(opts) {
|
|
|
4561
5755
|
for (const { clientId, update } of updates) {
|
|
4562
5756
|
if (update.type === "Noop") continue;
|
|
4563
5757
|
if (update.type === "FullReload") {
|
|
4564
|
-
|
|
5758
|
+
debug7?.(`full reload for ${clientId}: ${update.reason ?? ""}`);
|
|
4565
5759
|
needsLatestOutput = true;
|
|
4566
5760
|
continue;
|
|
4567
5761
|
}
|
|
@@ -4575,7 +5769,7 @@ async function createBundledDevServer(opts) {
|
|
|
4575
5769
|
}
|
|
4576
5770
|
const url = `/${patchPath}`;
|
|
4577
5771
|
logger.info(
|
|
4578
|
-
import_picocolors7.default.green("hmr update ") + import_picocolors7.default.dim(changedFiles.map((f) =>
|
|
5772
|
+
import_picocolors7.default.green("hmr update ") + import_picocolors7.default.dim(changedFiles.map((f) => import_node_path14.default.relative(config.root, f)).join(", ")),
|
|
4579
5773
|
{ timestamp: true }
|
|
4580
5774
|
);
|
|
4581
5775
|
sendTo(clientId, { type: "hmr:update", path: url, url });
|
|
@@ -4611,7 +5805,7 @@ async function createBundledDevServer(opts) {
|
|
|
4611
5805
|
},
|
|
4612
5806
|
{
|
|
4613
5807
|
watch: { skipWrite: true },
|
|
4614
|
-
rebuildStrategy: "
|
|
5808
|
+
rebuildStrategy: "never",
|
|
4615
5809
|
onOutput(result) {
|
|
4616
5810
|
if (result instanceof Error) {
|
|
4617
5811
|
logger.error(import_picocolors7.default.red(`[bundled] build error: ${result.message}`), { error: result });
|
|
@@ -4627,7 +5821,13 @@ async function createBundledDevServer(opts) {
|
|
|
4627
5821
|
memoryFiles.set(`${file.fileName}.map`, JSON.stringify(file.map));
|
|
4628
5822
|
}
|
|
4629
5823
|
}
|
|
4630
|
-
|
|
5824
|
+
debug7?.(`bundle output refreshed (${result.output.length} files)`);
|
|
5825
|
+
},
|
|
5826
|
+
onAdditionalAssets(result) {
|
|
5827
|
+
for (const file of result.output) {
|
|
5828
|
+
const content = file.type === "chunk" ? file.code : file.source;
|
|
5829
|
+
if (content != null) memoryFiles.set(file.fileName, content);
|
|
5830
|
+
}
|
|
4631
5831
|
},
|
|
4632
5832
|
async onHmrUpdates(result) {
|
|
4633
5833
|
if (result instanceof Error) {
|
|
@@ -4636,7 +5836,7 @@ async function createBundledDevServer(opts) {
|
|
|
4636
5836
|
return;
|
|
4637
5837
|
}
|
|
4638
5838
|
const { updates, changedFiles } = result;
|
|
4639
|
-
|
|
5839
|
+
debug7?.(
|
|
4640
5840
|
`onHmrUpdates(engine watcher): ${changedFiles.length} changed, ${updates.length} updates`
|
|
4641
5841
|
);
|
|
4642
5842
|
if (changedFiles.length === 0) return;
|
|
@@ -4655,24 +5855,29 @@ async function createBundledDevServer(opts) {
|
|
|
4655
5855
|
if (!clientId) return;
|
|
4656
5856
|
wss.handleUpgrade(req, socket, head, (ws) => {
|
|
4657
5857
|
bundledClients.set(clientId, ws);
|
|
4658
|
-
|
|
4659
|
-
|
|
5858
|
+
debug7?.(`bundled client connected: ${clientId}`);
|
|
5859
|
+
void engine.registerClient(clientId).then(async () => {
|
|
5860
|
+
for (const fileName of entryFileNames.values()) {
|
|
5861
|
+
await engine.notifyPayloadDelivered(fileName);
|
|
5862
|
+
}
|
|
5863
|
+
ws.send(JSON.stringify({ type: "connected" }));
|
|
5864
|
+
}).catch((err) => {
|
|
5865
|
+
debug7?.(`registerClient failed for ${clientId}: ${err?.message ?? err}`);
|
|
5866
|
+
ws.close();
|
|
5867
|
+
});
|
|
4660
5868
|
ws.on("message", async (raw) => {
|
|
4661
5869
|
try {
|
|
4662
5870
|
const msg = JSON.parse(String(raw));
|
|
4663
|
-
if (msg.type === "hmr:
|
|
4664
|
-
await engine.registerModules(clientId, msg.modules);
|
|
4665
|
-
debug6?.(`registered ${msg.modules.length} modules for ${clientId}`);
|
|
4666
|
-
} else if (msg.type === "hmr:invalidate") {
|
|
5871
|
+
if (msg.type === "hmr:invalidate") {
|
|
4667
5872
|
scheduleFullReload();
|
|
4668
5873
|
}
|
|
4669
5874
|
} catch (err) {
|
|
4670
|
-
|
|
5875
|
+
debug7?.(`bundled ws message error: ${err.message}`);
|
|
4671
5876
|
}
|
|
4672
5877
|
});
|
|
4673
5878
|
ws.on("close", () => {
|
|
4674
5879
|
bundledClients.delete(clientId);
|
|
4675
|
-
engine.removeClient(clientId).catch((err) =>
|
|
5880
|
+
engine.removeClient(clientId).catch((err) => debug7?.(`removeClient failed for ${clientId}: ${err?.message ?? err}`));
|
|
4676
5881
|
});
|
|
4677
5882
|
});
|
|
4678
5883
|
});
|
|
@@ -4689,10 +5894,18 @@ async function createBundledDevServer(opts) {
|
|
|
4689
5894
|
res.end("// [nasti] lazy endpoint requires id & clientId");
|
|
4690
5895
|
return;
|
|
4691
5896
|
}
|
|
4692
|
-
const
|
|
5897
|
+
const output = await engine.compileEntry(id, clientId);
|
|
5898
|
+
if (output.sourcemap && output.sourcemapFilename) {
|
|
5899
|
+
memoryFiles.set(output.sourcemapFilename, output.sourcemap);
|
|
5900
|
+
}
|
|
5901
|
+
res.once("finish", () => {
|
|
5902
|
+
void engine.notifyPayloadDelivered(output.filename).catch(
|
|
5903
|
+
(err) => debug7?.(`notifyPayloadDelivered failed: ${err?.message ?? err}`)
|
|
5904
|
+
);
|
|
5905
|
+
});
|
|
4693
5906
|
res.setHeader("Content-Type", "application/javascript");
|
|
4694
5907
|
res.setHeader("Cache-Control", "no-store");
|
|
4695
|
-
res.end(code + "\n;export {}");
|
|
5908
|
+
res.end(output.code + "\n;export {}");
|
|
4696
5909
|
return;
|
|
4697
5910
|
}
|
|
4698
5911
|
const patchHit = patches.get(pathname.replace(/^\//, ""));
|
|
@@ -4711,8 +5924,13 @@ async function createBundledDevServer(opts) {
|
|
|
4711
5924
|
return;
|
|
4712
5925
|
}
|
|
4713
5926
|
res.setHeader("ETag", hit.etag);
|
|
4714
|
-
res.setHeader("Content-Type", MIME_TYPES[
|
|
5927
|
+
res.setHeader("Content-Type", MIME_TYPES[import_node_path14.default.extname(fileName)] ?? "application/octet-stream");
|
|
4715
5928
|
res.setHeader("Cache-Control", "no-cache");
|
|
5929
|
+
res.once("finish", () => {
|
|
5930
|
+
void engine.notifyPayloadDelivered(fileName).catch(
|
|
5931
|
+
(err) => debug7?.(`notifyPayloadDelivered failed: ${err?.message ?? err}`)
|
|
5932
|
+
);
|
|
5933
|
+
});
|
|
4716
5934
|
res.end(hit.content);
|
|
4717
5935
|
return;
|
|
4718
5936
|
}
|
|
@@ -4747,7 +5965,7 @@ function stripCatchAllLoad(plugins) {
|
|
|
4747
5965
|
);
|
|
4748
5966
|
}
|
|
4749
5967
|
function createReactRefreshRuntimePlugin(entryPoints) {
|
|
4750
|
-
const entryIds = new Set(entryPoints.map((p) =>
|
|
5968
|
+
const entryIds = new Set(entryPoints.map((p) => import_node_path14.default.resolve(p)));
|
|
4751
5969
|
return {
|
|
4752
5970
|
name: "nasti:bundled-react-refresh",
|
|
4753
5971
|
resolveId(source) {
|
|
@@ -4765,7 +5983,7 @@ function createReactRefreshRuntimePlugin(entryPoints) {
|
|
|
4765
5983
|
return null;
|
|
4766
5984
|
},
|
|
4767
5985
|
transform(code, id) {
|
|
4768
|
-
if (!entryIds.has(
|
|
5986
|
+
if (!entryIds.has(import_node_path14.default.resolve(id.split("?")[0]))) return null;
|
|
4769
5987
|
return { code: `import ${JSON.stringify(PREAMBLE_SPEC)};
|
|
4770
5988
|
${code}`, map: null };
|
|
4771
5989
|
}
|
|
@@ -4812,11 +6030,11 @@ async function renderBundledIndexHtml(html, config, entryFileNames) {
|
|
|
4812
6030
|
}
|
|
4813
6031
|
return processed;
|
|
4814
6032
|
}
|
|
4815
|
-
var
|
|
6033
|
+
var import_node_path14, import_node_crypto3, import_ws2, import_picocolors7, debug7, MIME_TYPES, MemoryFiles, PREAMBLE_SPEC, RESOLVED_PREAMBLE_ID, REFRESH_RUNTIME_URL, BUNDLED_PREAMBLE_CODE, WRAPPER_RUNTIME_HELPERS;
|
|
4816
6034
|
var init_dev_engine = __esm({
|
|
4817
6035
|
"src/server/bundled/dev-engine.ts"() {
|
|
4818
6036
|
"use strict";
|
|
4819
|
-
|
|
6037
|
+
import_node_path14 = __toESM(require("path"), 1);
|
|
4820
6038
|
import_node_crypto3 = __toESM(require("crypto"), 1);
|
|
4821
6039
|
import_ws2 = require("ws");
|
|
4822
6040
|
import_picocolors7 = __toESM(require("picocolors"), 1);
|
|
@@ -4825,7 +6043,7 @@ var init_dev_engine = __esm({
|
|
|
4825
6043
|
init_transformer();
|
|
4826
6044
|
init_middleware();
|
|
4827
6045
|
init_debug();
|
|
4828
|
-
|
|
6046
|
+
debug7 = createDebugger("nasti:bundled");
|
|
4829
6047
|
MIME_TYPES = {
|
|
4830
6048
|
".js": "application/javascript",
|
|
4831
6049
|
".mjs": "application/javascript",
|
|
@@ -4943,14 +6161,16 @@ async function createServer(inlineConfig = {}) {
|
|
|
4943
6161
|
const startTime = performance.now();
|
|
4944
6162
|
const config = await resolveConfig(inlineConfig, "serve");
|
|
4945
6163
|
const logger = config.logger;
|
|
4946
|
-
const allPlugins = resolvePluginList(config, config.plugins
|
|
6164
|
+
const allPlugins = resolvePluginList(config, config.plugins, {
|
|
6165
|
+
environmentName: "client"
|
|
6166
|
+
});
|
|
4947
6167
|
const configWithPlugins = { ...config, plugins: allPlugins };
|
|
4948
6168
|
const app = (0, import_connect.default)();
|
|
4949
6169
|
const httpServer = import_node_http.default.createServer(app);
|
|
4950
6170
|
const ws = createWebSocketServer(httpServer);
|
|
4951
6171
|
const pluginApi = getPluginApi(config);
|
|
4952
6172
|
const clientEnv = new NastiEnvironment("client", config, {
|
|
4953
|
-
hot: createWsHotChannel(ws),
|
|
6173
|
+
hot: createWsHotChannel(ws, "client"),
|
|
4954
6174
|
mode: "dev",
|
|
4955
6175
|
plugins: allPlugins,
|
|
4956
6176
|
pluginApi
|
|
@@ -4960,15 +6180,45 @@ async function createServer(inlineConfig = {}) {
|
|
|
4960
6180
|
for (const name of Object.keys(config.environments)) {
|
|
4961
6181
|
if (name === "client") continue;
|
|
4962
6182
|
const consumer = config.environments[name].consumer;
|
|
4963
|
-
const envPlugins = resolvePluginList(config, config.plugins, {
|
|
6183
|
+
const envPlugins = resolvePluginList(config, config.plugins, {
|
|
6184
|
+
consumer,
|
|
6185
|
+
environmentName: name
|
|
6186
|
+
});
|
|
4964
6187
|
environments[name] = new NastiEnvironment(name, config, {
|
|
6188
|
+
hot: consumer === "client" ? createWsHotChannel(ws, name) : void 0,
|
|
4965
6189
|
mode: "dev",
|
|
4966
6190
|
plugins: envPlugins,
|
|
4967
6191
|
pluginApi
|
|
4968
6192
|
});
|
|
4969
6193
|
}
|
|
4970
6194
|
for (const [name, environment] of Object.entries(environments)) {
|
|
4971
|
-
if (name
|
|
6195
|
+
if (name === "client" || environment.consumer === "client" || environment.options.driver) {
|
|
6196
|
+
await environment.init();
|
|
6197
|
+
}
|
|
6198
|
+
}
|
|
6199
|
+
const transformContexts = /* @__PURE__ */ new Map();
|
|
6200
|
+
for (const environment of Object.values(environments)) {
|
|
6201
|
+
if (environment.consumer !== "client" || environment.driver) continue;
|
|
6202
|
+
const environmentConfig = {
|
|
6203
|
+
...configWithPlugins,
|
|
6204
|
+
resolve: environment.options.resolve,
|
|
6205
|
+
build: environment.options.build,
|
|
6206
|
+
plugins: environment.plugins
|
|
6207
|
+
};
|
|
6208
|
+
const context = {
|
|
6209
|
+
config: environmentConfig,
|
|
6210
|
+
pluginContainer: environment.pluginContainer,
|
|
6211
|
+
moduleGraph: environment.moduleGraph,
|
|
6212
|
+
environment,
|
|
6213
|
+
envDefine: buildEnvDefine(
|
|
6214
|
+
loadEnv(environmentConfig.mode, environmentConfig.root, environmentConfig.envPrefix),
|
|
6215
|
+
environmentConfig.mode,
|
|
6216
|
+
ssrDefineOverrides(environment.consumer)
|
|
6217
|
+
),
|
|
6218
|
+
onPrune: (paths) => environment.hot.send({ type: "prune", paths })
|
|
6219
|
+
};
|
|
6220
|
+
transformContexts.set(environment.name, context);
|
|
6221
|
+
environment.configureDevPipeline((url) => transformRequest(url, context));
|
|
4972
6222
|
}
|
|
4973
6223
|
let ssrRunner = null;
|
|
4974
6224
|
async function getSsrRunner() {
|
|
@@ -4983,7 +6233,6 @@ async function createServer(inlineConfig = {}) {
|
|
|
4983
6233
|
return ssrRunner;
|
|
4984
6234
|
}
|
|
4985
6235
|
const moduleGraph = clientEnv.moduleGraph;
|
|
4986
|
-
const pluginContainer = clientEnv.pluginContainer;
|
|
4987
6236
|
let bundledServer = null;
|
|
4988
6237
|
if (config.experimental.bundledDev) {
|
|
4989
6238
|
const { createBundledDevServer: createBundledDevServer2 } = await Promise.resolve().then(() => (init_dev_engine(), dev_engine_exports));
|
|
@@ -4995,14 +6244,14 @@ async function createServer(inlineConfig = {}) {
|
|
|
4995
6244
|
app.use(bundledServer.middleware);
|
|
4996
6245
|
}
|
|
4997
6246
|
const ignoredSegments = /* @__PURE__ */ new Set(["node_modules", ".git", ".nasti"]);
|
|
4998
|
-
const outDirAbs =
|
|
6247
|
+
const outDirAbs = import_node_path15.default.resolve(config.root, config.build.outDir);
|
|
4999
6248
|
const watcher = (0, import_chokidar.watch)(config.root, {
|
|
5000
6249
|
ignored: (filePath) => {
|
|
5001
6250
|
if (filePath === config.root) return false;
|
|
5002
|
-
if (filePath === outDirAbs || filePath.startsWith(outDirAbs +
|
|
5003
|
-
const rel =
|
|
5004
|
-
if (!rel || rel.startsWith("..") ||
|
|
5005
|
-
for (const seg of rel.split(
|
|
6251
|
+
if (filePath === outDirAbs || filePath.startsWith(outDirAbs + import_node_path15.default.sep)) return true;
|
|
6252
|
+
const rel = import_node_path15.default.relative(config.root, filePath);
|
|
6253
|
+
if (!rel || rel.startsWith("..") || import_node_path15.default.isAbsolute(rel)) return false;
|
|
6254
|
+
for (const seg of rel.split(import_node_path15.default.sep)) {
|
|
5006
6255
|
if (ignoredSegments.has(seg)) return true;
|
|
5007
6256
|
}
|
|
5008
6257
|
return false;
|
|
@@ -5012,6 +6261,15 @@ async function createServer(inlineConfig = {}) {
|
|
|
5012
6261
|
let server;
|
|
5013
6262
|
const environmentServices = {};
|
|
5014
6263
|
let environmentDriversStarted = false;
|
|
6264
|
+
let devPipelinesStarted = false;
|
|
6265
|
+
const startDevPipelines = async () => {
|
|
6266
|
+
if (devPipelinesStarted) return;
|
|
6267
|
+
devPipelinesStarted = true;
|
|
6268
|
+
for (const environment of Object.values(environments)) {
|
|
6269
|
+
if (!transformContexts.has(environment.name)) continue;
|
|
6270
|
+
await environment.pluginContainer.buildStart();
|
|
6271
|
+
}
|
|
6272
|
+
};
|
|
5015
6273
|
const logCloseError = (target, error) => {
|
|
5016
6274
|
const normalized = error instanceof Error ? error : new Error(String(error));
|
|
5017
6275
|
logger.error(`[nasti] failed to close ${target}`, { error: normalized });
|
|
@@ -5063,14 +6321,61 @@ async function createServer(inlineConfig = {}) {
|
|
|
5063
6321
|
});
|
|
5064
6322
|
}
|
|
5065
6323
|
};
|
|
6324
|
+
const updateClientEnvironments = async (file) => {
|
|
6325
|
+
const timestamp = Date.now();
|
|
6326
|
+
const results = {};
|
|
6327
|
+
for (const environment of Object.values(environments)) {
|
|
6328
|
+
if (environment.consumer !== "client" || environment.driver) continue;
|
|
6329
|
+
try {
|
|
6330
|
+
const result = await handleFileChange(file, server, environment.name, timestamp);
|
|
6331
|
+
if (result) results[environment.name] = result;
|
|
6332
|
+
} catch (error) {
|
|
6333
|
+
const normalized = error instanceof Error ? error : new Error(String(error));
|
|
6334
|
+
logger.error(
|
|
6335
|
+
`[nasti] HMR failed for environment "${environment.name}": ${normalized.message}`,
|
|
6336
|
+
{ error: normalized }
|
|
6337
|
+
);
|
|
6338
|
+
try {
|
|
6339
|
+
environment.hot.send({
|
|
6340
|
+
type: "error",
|
|
6341
|
+
err: { message: normalized.message, stack: normalized.stack }
|
|
6342
|
+
});
|
|
6343
|
+
} catch (channelError) {
|
|
6344
|
+
const channelFailure = channelError instanceof Error ? channelError : new Error(String(channelError));
|
|
6345
|
+
logger.error(
|
|
6346
|
+
`[nasti] failed to deliver HMR error to environment "${environment.name}"`,
|
|
6347
|
+
{ error: channelFailure }
|
|
6348
|
+
);
|
|
6349
|
+
}
|
|
6350
|
+
}
|
|
6351
|
+
}
|
|
6352
|
+
if (Object.keys(results).length === 0) return;
|
|
6353
|
+
const context = {
|
|
6354
|
+
file,
|
|
6355
|
+
timestamp,
|
|
6356
|
+
environments: Object.freeze({ ...results }),
|
|
6357
|
+
server
|
|
6358
|
+
};
|
|
6359
|
+
for (const plugin of config.plugins) {
|
|
6360
|
+
await plugin.handleHotUpdateApp?.(context);
|
|
6361
|
+
}
|
|
6362
|
+
};
|
|
6363
|
+
const queueClientEnvironmentUpdate = (file) => {
|
|
6364
|
+
void updateClientEnvironments(file).catch((error) => {
|
|
6365
|
+
const normalized = error instanceof Error ? error : new Error(String(error));
|
|
6366
|
+
logger.error(`[nasti] multi-environment HMR failed: ${normalized.message}`, {
|
|
6367
|
+
error: normalized
|
|
6368
|
+
});
|
|
6369
|
+
});
|
|
6370
|
+
};
|
|
5066
6371
|
watcher.on("change", (file) => {
|
|
5067
6372
|
ssrRunner?.invalidateFile(file);
|
|
5068
|
-
|
|
6373
|
+
queueClientEnvironmentUpdate(file);
|
|
5069
6374
|
notifyEnvironmentDrivers(file, "change");
|
|
5070
6375
|
});
|
|
5071
6376
|
watcher.on("add", (file) => {
|
|
5072
6377
|
ssrRunner?.invalidateFile(file);
|
|
5073
|
-
|
|
6378
|
+
queueClientEnvironmentUpdate(file);
|
|
5074
6379
|
notifyEnvironmentDrivers(file, "add");
|
|
5075
6380
|
});
|
|
5076
6381
|
watcher.on("unlink", (file) => {
|
|
@@ -5088,7 +6393,7 @@ async function createServer(inlineConfig = {}) {
|
|
|
5088
6393
|
async listen(port) {
|
|
5089
6394
|
const finalPort = port ?? config.server.port;
|
|
5090
6395
|
const host = config.server.host === true ? "0.0.0.0" : config.server.host;
|
|
5091
|
-
await
|
|
6396
|
+
await startDevPipelines();
|
|
5092
6397
|
await startEnvironmentDrivers();
|
|
5093
6398
|
return new Promise((resolve, reject) => {
|
|
5094
6399
|
let currentPort = finalPort;
|
|
@@ -5103,7 +6408,7 @@ async function createServer(inlineConfig = {}) {
|
|
|
5103
6408
|
const readyIn = Math.ceil(performance.now() - startTime);
|
|
5104
6409
|
logger.info(
|
|
5105
6410
|
`
|
|
5106
|
-
${import_picocolors8.default.cyan(import_picocolors8.default.bold("NASTI"))} ${import_picocolors8.default.cyan(`v${"2.
|
|
6411
|
+
${import_picocolors8.default.cyan(import_picocolors8.default.bold("NASTI"))} ${import_picocolors8.default.cyan(`v${"2.4.1"}`)} ${import_picocolors8.default.dim("ready in")} ${import_picocolors8.default.bold(readyIn)} ${import_picocolors8.default.dim("ms")}
|
|
5107
6412
|
`
|
|
5108
6413
|
);
|
|
5109
6414
|
printServerUrls(
|
|
@@ -5130,15 +6435,26 @@ async function createServer(inlineConfig = {}) {
|
|
|
5130
6435
|
});
|
|
5131
6436
|
},
|
|
5132
6437
|
async transformRequest(url) {
|
|
5133
|
-
|
|
5134
|
-
|
|
6438
|
+
return clientEnv.transformRequest(url);
|
|
6439
|
+
},
|
|
6440
|
+
async transformEnvironmentRequest(environmentName, url) {
|
|
6441
|
+
const environment = environments[environmentName];
|
|
6442
|
+
if (!environment) {
|
|
6443
|
+
throw new Error(`[nasti] unknown dev environment "${environmentName}"`);
|
|
6444
|
+
}
|
|
6445
|
+
return environment.transformRequest(url);
|
|
5135
6446
|
},
|
|
5136
6447
|
async ssrLoadModule(url) {
|
|
5137
6448
|
const runner = await getSsrRunner();
|
|
5138
6449
|
return runner.import(url);
|
|
5139
6450
|
},
|
|
5140
6451
|
async close() {
|
|
5141
|
-
|
|
6452
|
+
if (devPipelinesStarted) {
|
|
6453
|
+
for (const environment of Object.values(environments).reverse()) {
|
|
6454
|
+
if (!transformContexts.has(environment.name)) continue;
|
|
6455
|
+
await environment.pluginContainer.buildEnd();
|
|
6456
|
+
}
|
|
6457
|
+
}
|
|
5142
6458
|
await bundledServer?.close();
|
|
5143
6459
|
let environmentCloseFailed = false;
|
|
5144
6460
|
let firstEnvironmentCloseError;
|
|
@@ -5188,12 +6504,8 @@ async function createServer(inlineConfig = {}) {
|
|
|
5188
6504
|
}
|
|
5189
6505
|
throw error;
|
|
5190
6506
|
}
|
|
5191
|
-
app.use(transformMiddleware(
|
|
5192
|
-
|
|
5193
|
-
pluginContainer,
|
|
5194
|
-
moduleGraph
|
|
5195
|
-
}));
|
|
5196
|
-
const publicDir = import_node_path14.default.resolve(config.root, "public");
|
|
6507
|
+
app.use(transformMiddleware(transformContexts.get("client")));
|
|
6508
|
+
const publicDir = import_node_path15.default.resolve(config.root, "public");
|
|
5197
6509
|
app.use((0, import_sirv.default)(publicDir, { dev: true, etag: true }));
|
|
5198
6510
|
app.use((0, import_sirv.default)(config.root, { dev: true, etag: true }));
|
|
5199
6511
|
const postMiddlewares = [];
|
|
@@ -5219,12 +6531,12 @@ function getNetworkAddress() {
|
|
|
5219
6531
|
}
|
|
5220
6532
|
return "localhost";
|
|
5221
6533
|
}
|
|
5222
|
-
var import_node_http,
|
|
6534
|
+
var import_node_http, import_node_path15, import_node_os, import_connect, import_sirv, import_chokidar, import_picocolors8;
|
|
5223
6535
|
var init_server = __esm({
|
|
5224
6536
|
"src/server/index.ts"() {
|
|
5225
6537
|
"use strict";
|
|
5226
6538
|
import_node_http = __toESM(require("http"), 1);
|
|
5227
|
-
|
|
6539
|
+
import_node_path15 = __toESM(require("path"), 1);
|
|
5228
6540
|
import_node_os = __toESM(require("os"), 1);
|
|
5229
6541
|
import_connect = __toESM(require("connect"), 1);
|
|
5230
6542
|
import_sirv = __toESM(require("sirv"), 1);
|
|
@@ -5239,6 +6551,7 @@ var init_server = __esm({
|
|
|
5239
6551
|
init_hmr();
|
|
5240
6552
|
init_builtins();
|
|
5241
6553
|
init_plugin_api();
|
|
6554
|
+
init_env();
|
|
5242
6555
|
}
|
|
5243
6556
|
});
|
|
5244
6557
|
|
|
@@ -5293,16 +6606,16 @@ async function buildElectron(inlineConfig = {}) {
|
|
|
5293
6606
|
const config = await resolveConfig({ ...inlineConfig, target: "electron" }, "build");
|
|
5294
6607
|
const startTime = performance.now();
|
|
5295
6608
|
assertElectronVersion(config);
|
|
5296
|
-
console.log(import_picocolors9.default.cyan("\n\u26A1 nasti build (electron)") + import_picocolors9.default.dim(` v${"2.
|
|
6609
|
+
console.log(import_picocolors9.default.cyan("\n\u26A1 nasti build (electron)") + import_picocolors9.default.dim(` v${"2.4.1"}`));
|
|
5297
6610
|
console.log(import_picocolors9.default.dim(` root: ${config.root}`));
|
|
5298
6611
|
console.log(import_picocolors9.default.dim(` mode: ${config.mode}`));
|
|
5299
6612
|
console.log(import_picocolors9.default.dim(` target: electron (\u2265 ${config.electron.minVersion})`));
|
|
5300
|
-
const outDir =
|
|
5301
|
-
if (config.build.emptyOutDir &&
|
|
5302
|
-
|
|
6613
|
+
const outDir = import_node_path16.default.resolve(config.root, config.build.outDir);
|
|
6614
|
+
if (config.build.emptyOutDir && import_node_fs11.default.existsSync(outDir)) {
|
|
6615
|
+
import_node_fs11.default.rmSync(outDir, { recursive: true, force: true });
|
|
5303
6616
|
}
|
|
5304
|
-
|
|
5305
|
-
const rendererOutDir =
|
|
6617
|
+
import_node_fs11.default.mkdirSync(outDir, { recursive: true });
|
|
6618
|
+
const rendererOutDir = import_node_path16.default.join(outDir, "renderer");
|
|
5306
6619
|
const { build: build2 } = await Promise.resolve().then(() => (init_build(), build_exports));
|
|
5307
6620
|
await build2(createElectronRendererConfig(config, inlineConfig, {
|
|
5308
6621
|
build: {
|
|
@@ -5311,8 +6624,8 @@ async function buildElectron(inlineConfig = {}) {
|
|
|
5311
6624
|
emptyOutDir: false
|
|
5312
6625
|
}
|
|
5313
6626
|
}));
|
|
5314
|
-
const mainEntry =
|
|
5315
|
-
if (!
|
|
6627
|
+
const mainEntry = import_node_path16.default.resolve(config.root, config.electron.main);
|
|
6628
|
+
if (!import_node_fs11.default.existsSync(mainEntry)) {
|
|
5316
6629
|
throw new Error(
|
|
5317
6630
|
`Electron main entry not found: ${config.electron.main}
|
|
5318
6631
|
\u5728 nasti.config.ts \u7684 electron.main \u6307\u5B9A\u4E3B\u8FDB\u7A0B\u5165\u53E3\u6587\u4EF6\u3002`
|
|
@@ -5326,11 +6639,11 @@ async function buildElectron(inlineConfig = {}) {
|
|
|
5326
6639
|
const preloadEntries = normalizePreload(config.electron.preload, config.root);
|
|
5327
6640
|
const preloadFiles = [];
|
|
5328
6641
|
for (const entry of preloadEntries) {
|
|
5329
|
-
if (!
|
|
6642
|
+
if (!import_node_fs11.default.existsSync(entry)) {
|
|
5330
6643
|
console.warn(import_picocolors9.default.yellow(` \u26A0 preload entry not found, skipped: ${entry}`));
|
|
5331
6644
|
continue;
|
|
5332
6645
|
}
|
|
5333
|
-
const base =
|
|
6646
|
+
const base = import_node_path16.default.basename(entry).replace(/\.[^.]+$/, "");
|
|
5334
6647
|
const out = outFileName(outDir, base, config.electron.preloadFormat);
|
|
5335
6648
|
await bundleNode(config, entry, {
|
|
5336
6649
|
outFile: out,
|
|
@@ -5342,10 +6655,10 @@ async function buildElectron(inlineConfig = {}) {
|
|
|
5342
6655
|
const elapsed = ((performance.now() - startTime) / 1e3).toFixed(2);
|
|
5343
6656
|
console.log(import_picocolors9.default.green(`
|
|
5344
6657
|
\u2713 Electron build complete in ${elapsed}s`));
|
|
5345
|
-
console.log(import_picocolors9.default.dim(` renderer: ${
|
|
5346
|
-
console.log(import_picocolors9.default.dim(` main: ${
|
|
6658
|
+
console.log(import_picocolors9.default.dim(` renderer: ${import_node_path16.default.relative(config.root, rendererOutDir)}/`));
|
|
6659
|
+
console.log(import_picocolors9.default.dim(` main: ${import_node_path16.default.relative(config.root, mainFile)}`));
|
|
5347
6660
|
for (const pf of preloadFiles) {
|
|
5348
|
-
console.log(import_picocolors9.default.dim(` preload: ${
|
|
6661
|
+
console.log(import_picocolors9.default.dim(` preload: ${import_node_path16.default.relative(config.root, pf)}`));
|
|
5349
6662
|
}
|
|
5350
6663
|
console.log();
|
|
5351
6664
|
return { rendererOutDir, mainFile, preloadFiles };
|
|
@@ -5383,7 +6696,7 @@ async function bundleNode(config, entry, opts) {
|
|
|
5383
6696
|
},
|
|
5384
6697
|
plugins: [oxcTransformPlugin, electronPlugin(config), resolvePlugin(config)]
|
|
5385
6698
|
});
|
|
5386
|
-
|
|
6699
|
+
import_node_fs11.default.mkdirSync(import_node_path16.default.dirname(opts.outFile), { recursive: true });
|
|
5387
6700
|
await bundle2.write({
|
|
5388
6701
|
sourcemap: !!config.build.sourcemap,
|
|
5389
6702
|
minify: !!config.build.minify,
|
|
@@ -5394,7 +6707,7 @@ async function bundleNode(config, entry, opts) {
|
|
|
5394
6707
|
codeSplitting: false
|
|
5395
6708
|
});
|
|
5396
6709
|
await bundle2.close();
|
|
5397
|
-
console.log(import_picocolors9.default.dim(` \u2713 ${opts.label} \u2192 ${
|
|
6710
|
+
console.log(import_picocolors9.default.dim(` \u2713 ${opts.label} \u2192 ${import_node_path16.default.relative(config.root, opts.outFile)}`));
|
|
5398
6711
|
return opts.outFile;
|
|
5399
6712
|
}
|
|
5400
6713
|
function createElectronRendererConfig(config, inlineConfig = {}, overrides = {}) {
|
|
@@ -5418,11 +6731,11 @@ function createElectronRendererConfig(config, inlineConfig = {}, overrides = {})
|
|
|
5418
6731
|
}
|
|
5419
6732
|
function outFileName(outDir, base, format) {
|
|
5420
6733
|
const ext = format === "cjs" ? ".cjs" : ".mjs";
|
|
5421
|
-
return
|
|
6734
|
+
return import_node_path16.default.join(outDir, base + ext);
|
|
5422
6735
|
}
|
|
5423
6736
|
function normalizePreload(preload, root) {
|
|
5424
6737
|
const list = Array.isArray(preload) ? preload : preload ? [preload] : [];
|
|
5425
|
-
return list.map((p) =>
|
|
6738
|
+
return list.map((p) => import_node_path16.default.resolve(root, p));
|
|
5426
6739
|
}
|
|
5427
6740
|
function assertElectronVersion(config) {
|
|
5428
6741
|
const min = config.electron.minVersion;
|
|
@@ -5437,21 +6750,21 @@ function assertElectronVersion(config) {
|
|
|
5437
6750
|
}
|
|
5438
6751
|
function detectInstalledElectron(root) {
|
|
5439
6752
|
try {
|
|
5440
|
-
const pkgPath =
|
|
5441
|
-
if (!
|
|
5442
|
-
const pkg = JSON.parse(
|
|
6753
|
+
const pkgPath = import_node_path16.default.resolve(root, "node_modules/electron/package.json");
|
|
6754
|
+
if (!import_node_fs11.default.existsSync(pkgPath)) return null;
|
|
6755
|
+
const pkg = JSON.parse(import_node_fs11.default.readFileSync(pkgPath, "utf-8"));
|
|
5443
6756
|
const major = parseInt(String(pkg.version).split(".")[0], 10);
|
|
5444
6757
|
return Number.isFinite(major) ? major : null;
|
|
5445
6758
|
} catch {
|
|
5446
6759
|
return null;
|
|
5447
6760
|
}
|
|
5448
6761
|
}
|
|
5449
|
-
var
|
|
6762
|
+
var import_node_path16, import_node_fs11, import_rolldown2, import_picocolors9;
|
|
5450
6763
|
var init_electron2 = __esm({
|
|
5451
6764
|
"src/build/electron.ts"() {
|
|
5452
6765
|
"use strict";
|
|
5453
|
-
|
|
5454
|
-
|
|
6766
|
+
import_node_path16 = __toESM(require("path"), 1);
|
|
6767
|
+
import_node_fs11 = __toESM(require("fs"), 1);
|
|
5455
6768
|
import_rolldown2 = require("rolldown");
|
|
5456
6769
|
import_picocolors9 = __toESM(require("picocolors"), 1);
|
|
5457
6770
|
init_config();
|
|
@@ -5472,7 +6785,7 @@ async function startElectronDev(inlineConfig = {}) {
|
|
|
5472
6785
|
const { noSpawn, ...rest } = inlineConfig;
|
|
5473
6786
|
const config = await resolveConfig({ ...rest, target: "electron" }, "serve");
|
|
5474
6787
|
warnElectronVersion(config);
|
|
5475
|
-
console.log(import_picocolors10.default.cyan("\n\u26A1 nasti electron dev") + import_picocolors10.default.dim(` v${"2.
|
|
6788
|
+
console.log(import_picocolors10.default.cyan("\n\u26A1 nasti electron dev") + import_picocolors10.default.dim(` v${"2.4.1"}`));
|
|
5476
6789
|
const { createServer: createServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
|
|
5477
6790
|
const server = await createServer2({
|
|
5478
6791
|
...rest,
|
|
@@ -5482,11 +6795,11 @@ async function startElectronDev(inlineConfig = {}) {
|
|
|
5482
6795
|
await server.listen();
|
|
5483
6796
|
const devUrl = `http://localhost:${server.config.server.port}` + electronRendererDevPath(config.electron.renderer);
|
|
5484
6797
|
console.log(import_picocolors10.default.dim(` renderer: ${devUrl}`));
|
|
5485
|
-
const stageDir =
|
|
5486
|
-
|
|
5487
|
-
const mainEntry =
|
|
6798
|
+
const stageDir = import_node_path17.default.resolve(config.root, ".nasti");
|
|
6799
|
+
import_node_fs12.default.mkdirSync(stageDir, { recursive: true });
|
|
6800
|
+
const mainEntry = import_node_path17.default.resolve(config.root, config.electron.main);
|
|
5488
6801
|
const preloadEntries = normalizePreload(config.electron.preload, config.root);
|
|
5489
|
-
const builtMainFile =
|
|
6802
|
+
const builtMainFile = import_node_path17.default.join(stageDir, "main" + extFor(config.electron.mainFormat));
|
|
5490
6803
|
const builtPreloadFiles = [];
|
|
5491
6804
|
const compileAll = async () => {
|
|
5492
6805
|
await compileNode(config, mainEntry, {
|
|
@@ -5496,9 +6809,9 @@ async function startElectronDev(inlineConfig = {}) {
|
|
|
5496
6809
|
});
|
|
5497
6810
|
builtPreloadFiles.length = 0;
|
|
5498
6811
|
for (const entry of preloadEntries) {
|
|
5499
|
-
if (!
|
|
5500
|
-
const base =
|
|
5501
|
-
const out =
|
|
6812
|
+
if (!import_node_fs12.default.existsSync(entry)) continue;
|
|
6813
|
+
const base = import_node_path17.default.basename(entry).replace(/\.[^.]+$/, "");
|
|
6814
|
+
const out = import_node_path17.default.join(stageDir, base + extFor(config.electron.preloadFormat));
|
|
5502
6815
|
await compileNode(config, entry, {
|
|
5503
6816
|
outFile: out,
|
|
5504
6817
|
format: config.electron.preloadFormat,
|
|
@@ -5537,7 +6850,7 @@ async function startElectronDev(inlineConfig = {}) {
|
|
|
5537
6850
|
};
|
|
5538
6851
|
spawnElectron();
|
|
5539
6852
|
if (config.electron.autoRestart) {
|
|
5540
|
-
const watchTargets = [mainEntry, ...preloadEntries].filter(
|
|
6853
|
+
const watchTargets = [mainEntry, ...preloadEntries].filter(import_node_fs12.default.existsSync);
|
|
5541
6854
|
const watcher = import_chokidar2.default.watch(watchTargets, { ignoreInitial: true });
|
|
5542
6855
|
let restarting = null;
|
|
5543
6856
|
let pending = false;
|
|
@@ -5617,7 +6930,7 @@ async function compileNode(config, entry, opts) {
|
|
|
5617
6930
|
platform: "node",
|
|
5618
6931
|
plugins: [oxcTransformPlugin, electronPlugin(config), resolvePlugin(config)]
|
|
5619
6932
|
});
|
|
5620
|
-
|
|
6933
|
+
import_node_fs12.default.mkdirSync(import_node_path17.default.dirname(opts.outFile), { recursive: true });
|
|
5621
6934
|
await bundle2.write({
|
|
5622
6935
|
file: opts.outFile,
|
|
5623
6936
|
format: opts.format === "cjs" ? "cjs" : "esm",
|
|
@@ -5630,18 +6943,18 @@ async function compileNode(config, entry, opts) {
|
|
|
5630
6943
|
await bundle2.close();
|
|
5631
6944
|
}
|
|
5632
6945
|
function electronRendererDevPath(renderer) {
|
|
5633
|
-
const normalized = renderer.split(
|
|
6946
|
+
const normalized = renderer.split(import_node_path17.default.sep).join("/").replace(/^\.?\//, "");
|
|
5634
6947
|
return normalized === "index.html" ? "/" : `/${normalized}`;
|
|
5635
6948
|
}
|
|
5636
6949
|
function resolveElectronBinary(config) {
|
|
5637
|
-
if (config.electron.electronPath &&
|
|
6950
|
+
if (config.electron.electronPath && import_node_fs12.default.existsSync(config.electron.electronPath)) {
|
|
5638
6951
|
return config.electron.electronPath;
|
|
5639
6952
|
}
|
|
5640
6953
|
try {
|
|
5641
|
-
const require2 = (0, import_node_module7.createRequire)(
|
|
6954
|
+
const require2 = (0, import_node_module7.createRequire)(import_node_path17.default.resolve(config.root, "package.json"));
|
|
5642
6955
|
const pathFile = require2.resolve("electron");
|
|
5643
6956
|
const electronModule = require2(pathFile);
|
|
5644
|
-
if (typeof electronModule === "string" &&
|
|
6957
|
+
if (typeof electronModule === "string" && import_node_fs12.default.existsSync(electronModule)) {
|
|
5645
6958
|
return electronModule;
|
|
5646
6959
|
}
|
|
5647
6960
|
} catch {
|
|
@@ -5666,12 +6979,12 @@ function warnElectronVersion(config) {
|
|
|
5666
6979
|
);
|
|
5667
6980
|
}
|
|
5668
6981
|
}
|
|
5669
|
-
var
|
|
6982
|
+
var import_node_path17, import_node_fs12, import_node_module7, import_node_child_process, import_chokidar2, import_picocolors10, import_rolldown3;
|
|
5670
6983
|
var init_electron_dev = __esm({
|
|
5671
6984
|
"src/server/electron-dev.ts"() {
|
|
5672
6985
|
"use strict";
|
|
5673
|
-
|
|
5674
|
-
|
|
6986
|
+
import_node_path17 = __toESM(require("path"), 1);
|
|
6987
|
+
import_node_fs12 = __toESM(require("fs"), 1);
|
|
5675
6988
|
import_node_module7 = require("module");
|
|
5676
6989
|
import_node_child_process = require("child_process");
|
|
5677
6990
|
import_chokidar2 = __toESM(require("chokidar"), 1);
|
|
@@ -5824,20 +7137,20 @@ cli.command("preview [root]", "Preview production build").option("--port <port>"
|
|
|
5824
7137
|
const logger = createCliLogger(options);
|
|
5825
7138
|
try {
|
|
5826
7139
|
const http2 = await import("http");
|
|
5827
|
-
const
|
|
7140
|
+
const path18 = await import("path");
|
|
5828
7141
|
const os2 = await import("os");
|
|
5829
7142
|
const sirv2 = (await import("sirv")).default;
|
|
5830
7143
|
const connect2 = (await import("connect")).default;
|
|
5831
7144
|
const { printServerUrls: printServerUrls2 } = await Promise.resolve().then(() => (init_logger(), logger_exports));
|
|
5832
|
-
const resolvedRoot =
|
|
5833
|
-
const outDir =
|
|
7145
|
+
const resolvedRoot = path18.resolve(root ?? ".");
|
|
7146
|
+
const outDir = path18.resolve(resolvedRoot, options.outDir);
|
|
5834
7147
|
const app = connect2();
|
|
5835
7148
|
app.use(sirv2(outDir, { single: true, etag: true, gzip: true, brotli: true }));
|
|
5836
7149
|
const port = options.port;
|
|
5837
7150
|
const host = options.host === true ? "0.0.0.0" : options.host ?? "localhost";
|
|
5838
7151
|
http2.createServer(app).listen(port, host, () => {
|
|
5839
7152
|
logger.info(`
|
|
5840
|
-
${import_picocolors11.default.cyan(import_picocolors11.default.bold("NASTI"))} ${import_picocolors11.default.cyan(`v${"2.
|
|
7153
|
+
${import_picocolors11.default.cyan(import_picocolors11.default.bold("NASTI"))} ${import_picocolors11.default.cyan(`v${"2.4.1"}`)} ${import_picocolors11.default.dim("preview")}
|
|
5841
7154
|
`);
|
|
5842
7155
|
printServerUrls2(
|
|
5843
7156
|
{
|
|
@@ -5854,6 +7167,6 @@ cli.command("preview [root]", "Preview production build").option("--port <port>"
|
|
|
5854
7167
|
}
|
|
5855
7168
|
});
|
|
5856
7169
|
cli.help();
|
|
5857
|
-
cli.version("2.
|
|
7170
|
+
cli.version("2.4.1");
|
|
5858
7171
|
cli.parse();
|
|
5859
7172
|
//# sourceMappingURL=cli.cjs.map
|