@nasti-toolchain/nasti 2.3.1 → 2.4.0
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 +64 -1
- package/bin/nasti.js +0 -0
- package/client/hmr.ts +4 -3
- package/dist/cli.cjs +957 -269
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +951 -264
- 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 +1054 -366
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +64 -8
- package/dist/index.d.ts +64 -8
- package/dist/index.js +1048 -361
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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;
|
|
@@ -476,6 +476,7 @@ async function resolveConfig(inlineConfig = {}, command) {
|
|
|
476
476
|
if (envOptions.build) Object.assign(resolved.build, envOptions.build);
|
|
477
477
|
resolved.environments.client = {
|
|
478
478
|
consumer,
|
|
479
|
+
buildEnabled: envOptions.buildEnabled ?? true,
|
|
479
480
|
entry: normalizeEnvironmentEntries(envOptions.entry, root),
|
|
480
481
|
html: import_node_path.default.resolve(
|
|
481
482
|
root,
|
|
@@ -490,6 +491,7 @@ async function resolveConfig(inlineConfig = {}, command) {
|
|
|
490
491
|
}
|
|
491
492
|
resolved.environments[name] = {
|
|
492
493
|
consumer,
|
|
494
|
+
buildEnabled: envOptions.buildEnabled ?? true,
|
|
493
495
|
entry: normalizeEnvironmentEntries(envOptions.entry, root),
|
|
494
496
|
html: envOptions.consumer === "client" && envOptions.html ? import_node_path.default.resolve(root, envOptions.html) : void 0,
|
|
495
497
|
driver: envOptions.driver,
|
|
@@ -782,17 +784,35 @@ var init_plugin_container = __esm({
|
|
|
782
784
|
}
|
|
783
785
|
});
|
|
784
786
|
|
|
787
|
+
// src/core/url.ts
|
|
788
|
+
function removeTimestampQuery(url) {
|
|
789
|
+
const hashIndex = url.indexOf("#");
|
|
790
|
+
const hash = hashIndex >= 0 ? url.slice(hashIndex) : "";
|
|
791
|
+
const withoutHash = hashIndex >= 0 ? url.slice(0, hashIndex) : url;
|
|
792
|
+
const queryIndex = withoutHash.indexOf("?");
|
|
793
|
+
if (queryIndex < 0) return url;
|
|
794
|
+
const pathname = withoutHash.slice(0, queryIndex);
|
|
795
|
+
const query = withoutHash.slice(queryIndex + 1).split("&").filter((part) => !/^t=\d+$/.test(part)).join("&");
|
|
796
|
+
return pathname + (query ? `?${query}` : "") + hash;
|
|
797
|
+
}
|
|
798
|
+
var init_url = __esm({
|
|
799
|
+
"src/core/url.ts"() {
|
|
800
|
+
"use strict";
|
|
801
|
+
}
|
|
802
|
+
});
|
|
803
|
+
|
|
785
804
|
// src/core/module-graph.ts
|
|
786
805
|
var ModuleGraph;
|
|
787
806
|
var init_module_graph = __esm({
|
|
788
807
|
"src/core/module-graph.ts"() {
|
|
789
808
|
"use strict";
|
|
809
|
+
init_url();
|
|
790
810
|
ModuleGraph = class {
|
|
791
811
|
urlToModuleMap = /* @__PURE__ */ new Map();
|
|
792
812
|
idToModuleMap = /* @__PURE__ */ new Map();
|
|
793
813
|
fileToModulesMap = /* @__PURE__ */ new Map();
|
|
794
814
|
getModuleByUrl(url) {
|
|
795
|
-
return this.urlToModuleMap.get(url);
|
|
815
|
+
return this.urlToModuleMap.get(removeTimestampQuery(url));
|
|
796
816
|
}
|
|
797
817
|
getModuleById(id) {
|
|
798
818
|
return this.idToModuleMap.get(id);
|
|
@@ -801,10 +821,11 @@ var init_module_graph = __esm({
|
|
|
801
821
|
return this.fileToModulesMap.get(file);
|
|
802
822
|
}
|
|
803
823
|
async ensureEntryFromUrl(url) {
|
|
804
|
-
|
|
824
|
+
const normalizedUrl = removeTimestampQuery(url);
|
|
825
|
+
let mod = this.urlToModuleMap.get(normalizedUrl);
|
|
805
826
|
if (mod) return mod;
|
|
806
|
-
mod = this.createModule(
|
|
807
|
-
this.urlToModuleMap.set(
|
|
827
|
+
mod = this.createModule(normalizedUrl);
|
|
828
|
+
this.urlToModuleMap.set(normalizedUrl, mod);
|
|
808
829
|
return mod;
|
|
809
830
|
}
|
|
810
831
|
createModule(url, id) {
|
|
@@ -818,6 +839,7 @@ var init_module_graph = __esm({
|
|
|
818
839
|
acceptedHmrDeps: /* @__PURE__ */ new Set(),
|
|
819
840
|
transformResult: null,
|
|
820
841
|
lastHMRTimestamp: 0,
|
|
842
|
+
invalidationVersion: 0,
|
|
821
843
|
isSelfAccepting: false
|
|
822
844
|
};
|
|
823
845
|
this.idToModuleMap.set(mod.id, mod);
|
|
@@ -860,10 +882,64 @@ var init_module_graph = __esm({
|
|
|
860
882
|
}
|
|
861
883
|
}
|
|
862
884
|
}
|
|
885
|
+
/**
|
|
886
|
+
* 用一次转换得到的信息原子更新 import 与 HMR accept 关系。
|
|
887
|
+
* 依赖节点会在真正被浏览器请求前预先创建,这样入口模块先转换时也能建立完整图。
|
|
888
|
+
*/
|
|
889
|
+
async updateModuleInfo(mod, importedUrls, acceptedUrls, isSelfAccepting, expectedInvalidationVersion) {
|
|
890
|
+
const importedModules = await Promise.all(
|
|
891
|
+
[...importedUrls].map((url) => this.ensureEntryFromUrl(url))
|
|
892
|
+
);
|
|
893
|
+
const acceptedModules = await Promise.all(
|
|
894
|
+
[...acceptedUrls].map((url) => this.ensureEntryFromUrl(url))
|
|
895
|
+
);
|
|
896
|
+
if (expectedInvalidationVersion !== void 0 && mod.invalidationVersion !== expectedInvalidationVersion) {
|
|
897
|
+
return null;
|
|
898
|
+
}
|
|
899
|
+
const previousImports = new Set(mod.importedModules);
|
|
900
|
+
for (const imported of previousImports) {
|
|
901
|
+
imported.importers.delete(mod);
|
|
902
|
+
}
|
|
903
|
+
mod.importedModules.clear();
|
|
904
|
+
mod.acceptedHmrDeps.clear();
|
|
905
|
+
for (const imported of importedModules) {
|
|
906
|
+
mod.importedModules.add(imported);
|
|
907
|
+
imported.importers.add(mod);
|
|
908
|
+
}
|
|
909
|
+
for (const accepted of acceptedModules) {
|
|
910
|
+
mod.acceptedHmrDeps.add(accepted);
|
|
911
|
+
}
|
|
912
|
+
mod.isSelfAccepting = isSelfAccepting;
|
|
913
|
+
const pruned = /* @__PURE__ */ new Set();
|
|
914
|
+
for (const imported of previousImports) {
|
|
915
|
+
if (!mod.importedModules.has(imported) && imported.importers.size === 0) {
|
|
916
|
+
pruned.add(imported);
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
return pruned;
|
|
920
|
+
}
|
|
863
921
|
/** 使模块的转换缓存失效 */
|
|
864
|
-
invalidateModule(mod) {
|
|
922
|
+
invalidateModule(mod, timestamp = Date.now()) {
|
|
865
923
|
mod.transformResult = null;
|
|
866
|
-
mod.lastHMRTimestamp =
|
|
924
|
+
mod.lastHMRTimestamp = timestamp;
|
|
925
|
+
mod.invalidationVersion++;
|
|
926
|
+
}
|
|
927
|
+
/**
|
|
928
|
+
* 仅失效到 HMR 边界:显式接受依赖的模块本身不会重执行;自接受模块需要失效,
|
|
929
|
+
* 但不再继续影响其 importer。这样既能传播依赖时间戳,也不会隐式重复副作用。
|
|
930
|
+
*/
|
|
931
|
+
invalidateModuleAndImporters(mod, timestamp = Date.now(), seen = /* @__PURE__ */ new Set()) {
|
|
932
|
+
if (seen.has(mod)) return;
|
|
933
|
+
seen.add(mod);
|
|
934
|
+
this.invalidateModule(mod, timestamp);
|
|
935
|
+
for (const importer of mod.importers) {
|
|
936
|
+
if (importer.acceptedHmrDeps.has(mod)) continue;
|
|
937
|
+
if (importer.isSelfAccepting) {
|
|
938
|
+
this.invalidateModule(importer, timestamp);
|
|
939
|
+
continue;
|
|
940
|
+
}
|
|
941
|
+
this.invalidateModuleAndImporters(importer, timestamp, seen);
|
|
942
|
+
}
|
|
867
943
|
}
|
|
868
944
|
/** 使所有模块缓存失效 */
|
|
869
945
|
invalidateAll() {
|
|
@@ -874,34 +950,32 @@ var init_module_graph = __esm({
|
|
|
874
950
|
/** 获取 HMR 传播边界 - 从变更模块向上遍历找到接受更新的边界 */
|
|
875
951
|
getHmrBoundaries(mod) {
|
|
876
952
|
const boundaries = [];
|
|
877
|
-
const
|
|
878
|
-
const
|
|
879
|
-
if (
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
boundaries.push({ boundary
|
|
883
|
-
return true;
|
|
953
|
+
const traversed = /* @__PURE__ */ new Set();
|
|
954
|
+
const addBoundary = (boundary, acceptedVia) => {
|
|
955
|
+
if (!boundaries.some(
|
|
956
|
+
(item) => item.boundary === boundary && item.acceptedVia === acceptedVia
|
|
957
|
+
)) {
|
|
958
|
+
boundaries.push({ boundary, acceptedVia });
|
|
884
959
|
}
|
|
885
|
-
|
|
886
|
-
|
|
960
|
+
};
|
|
961
|
+
const propagate = (node) => {
|
|
962
|
+
if (traversed.has(node)) return true;
|
|
963
|
+
traversed.add(node);
|
|
964
|
+
if (node.isSelfAccepting) {
|
|
965
|
+
addBoundary(node, node);
|
|
887
966
|
return true;
|
|
888
967
|
}
|
|
889
968
|
if (node.importers.size === 0) return false;
|
|
890
969
|
for (const importer of node.importers) {
|
|
891
|
-
if (
|
|
970
|
+
if (importer.acceptedHmrDeps.has(node)) {
|
|
971
|
+
addBoundary(importer, node);
|
|
972
|
+
continue;
|
|
973
|
+
}
|
|
974
|
+
if (!propagate(importer)) return false;
|
|
892
975
|
}
|
|
893
976
|
return true;
|
|
894
977
|
};
|
|
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;
|
|
978
|
+
return propagate(mod) ? boundaries : [];
|
|
905
979
|
}
|
|
906
980
|
};
|
|
907
981
|
}
|
|
@@ -1040,6 +1114,7 @@ var init_environment = __esm({
|
|
|
1040
1114
|
moduleGraph;
|
|
1041
1115
|
candidatePlugins;
|
|
1042
1116
|
pluginApi;
|
|
1117
|
+
buildMetadata = {};
|
|
1043
1118
|
initialized = false;
|
|
1044
1119
|
constructor(name, config, init = {}) {
|
|
1045
1120
|
const options = config.environments[name];
|
|
@@ -1096,6 +1171,22 @@ var init_environment = __esm({
|
|
|
1096
1171
|
logger: this.config.logger
|
|
1097
1172
|
};
|
|
1098
1173
|
}
|
|
1174
|
+
setBuildMetadata(metadata) {
|
|
1175
|
+
const { entries: currentEntries, ...currentMetadata } = this.buildMetadata;
|
|
1176
|
+
const { entries, ...nextMetadata } = metadata;
|
|
1177
|
+
this.buildMetadata = {
|
|
1178
|
+
...currentMetadata,
|
|
1179
|
+
...nextMetadata,
|
|
1180
|
+
...currentEntries || entries ? { entries: { ...currentEntries, ...entries } } : {}
|
|
1181
|
+
};
|
|
1182
|
+
}
|
|
1183
|
+
getBuildMetadata() {
|
|
1184
|
+
const { entries, ...metadata } = this.buildMetadata;
|
|
1185
|
+
return {
|
|
1186
|
+
...metadata,
|
|
1187
|
+
...entries ? { entries: { ...entries } } : {}
|
|
1188
|
+
};
|
|
1189
|
+
}
|
|
1099
1190
|
async close() {
|
|
1100
1191
|
try {
|
|
1101
1192
|
await this.driver?.close?.(this.getDriverContext());
|
|
@@ -1346,8 +1437,10 @@ __export(middleware_exports, {
|
|
|
1346
1437
|
transformMiddleware: () => transformMiddleware,
|
|
1347
1438
|
transformRequest: () => transformRequest
|
|
1348
1439
|
});
|
|
1349
|
-
function getReactRefreshRuntimeEsm() {
|
|
1350
|
-
if (__refreshRuntimeCache)
|
|
1440
|
+
function getReactRefreshRuntimeEsm(includeBoundaryHelpers = false) {
|
|
1441
|
+
if (__refreshRuntimeCache) {
|
|
1442
|
+
return includeBoundaryHelpers ? __refreshRuntimeCache + REACT_REFRESH_BOUNDARY_HELPERS : __refreshRuntimeCache;
|
|
1443
|
+
}
|
|
1351
1444
|
let cjsPath;
|
|
1352
1445
|
try {
|
|
1353
1446
|
const pkgPath = __require.resolve("react-refresh/package.json");
|
|
@@ -1382,7 +1475,7 @@ export const findAffectedHostInstances = __rt.findAffectedHostInstances;
|
|
|
1382
1475
|
export const collectCustomHooksForSignature = __rt.collectCustomHooksForSignature;
|
|
1383
1476
|
export default __rt;
|
|
1384
1477
|
`;
|
|
1385
|
-
return __refreshRuntimeCache;
|
|
1478
|
+
return includeBoundaryHelpers ? __refreshRuntimeCache + REACT_REFRESH_BOUNDARY_HELPERS : __refreshRuntimeCache;
|
|
1386
1479
|
}
|
|
1387
1480
|
function buildReactRefreshWrapper(moduleUrl, transformedCode) {
|
|
1388
1481
|
const urlLit = JSON.stringify(moduleUrl);
|
|
@@ -1408,22 +1501,40 @@ window.$RefreshReg$ = prevRefreshReg;
|
|
|
1408
1501
|
window.$RefreshSig$ = prevRefreshSig;
|
|
1409
1502
|
|
|
1410
1503
|
if (__nasti_hot__) {
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1504
|
+
let __nasti_current_exports__;
|
|
1505
|
+
__nasti_hot__.accept((nextExports) => {
|
|
1506
|
+
if (!nextExports) return;
|
|
1507
|
+
if (!__nasti_current_exports__) {
|
|
1508
|
+
__nasti_hot__.invalidate('Could not Fast Refresh (previous exports unavailable)');
|
|
1509
|
+
return;
|
|
1510
|
+
}
|
|
1511
|
+
const invalidateMessage = RefreshRuntime.validateRefreshBoundaryAndEnqueueUpdate(
|
|
1512
|
+
${urlLit},
|
|
1513
|
+
__nasti_current_exports__,
|
|
1514
|
+
nextExports,
|
|
1515
|
+
);
|
|
1516
|
+
if (invalidateMessage) __nasti_hot__.invalidate(invalidateMessage);
|
|
1517
|
+
});
|
|
1518
|
+
RefreshRuntime.__hmr_import(import.meta.url).then((currentExports) => {
|
|
1519
|
+
__nasti_current_exports__ = currentExports;
|
|
1520
|
+
RefreshRuntime.registerExportsForReactRefresh(${urlLit}, currentExports);
|
|
1416
1521
|
});
|
|
1417
1522
|
}
|
|
1418
1523
|
`;
|
|
1419
1524
|
}
|
|
1420
1525
|
function injectImportMetaHot(code, moduleUrl) {
|
|
1421
|
-
|
|
1526
|
+
const hotRE = /\bimport\.meta\.hot\b/g;
|
|
1527
|
+
const matches = [...maskStringsAndComments(code).matchAll(hotRE)];
|
|
1528
|
+
if (matches.length === 0) return code;
|
|
1529
|
+
for (const match of matches.reverse()) {
|
|
1530
|
+
const start = match.index;
|
|
1531
|
+
code = code.slice(0, start) + "__nasti_hot__" + code.slice(start + match[0].length);
|
|
1532
|
+
}
|
|
1422
1533
|
const urlLit = JSON.stringify(moduleUrl);
|
|
1423
1534
|
const header = `import { createHotContext as __nasti_createHotContext__ } from "/@nasti/client";
|
|
1424
1535
|
const __nasti_hot__ = __nasti_createHotContext__(${urlLit});
|
|
1425
1536
|
`;
|
|
1426
|
-
return header + code
|
|
1537
|
+
return header + code;
|
|
1427
1538
|
}
|
|
1428
1539
|
function transformMiddleware(ctx) {
|
|
1429
1540
|
ctx.envDefine = buildEnvDefine(
|
|
@@ -1499,13 +1610,14 @@ function transformMiddleware(ctx) {
|
|
|
1499
1610
|
}
|
|
1500
1611
|
async function transformRequest(url, ctx) {
|
|
1501
1612
|
const { config, pluginContainer, moduleGraph } = ctx;
|
|
1613
|
+
url = removeTimestampQuery(url);
|
|
1502
1614
|
const cleanReqUrl = url.split("?")[0];
|
|
1503
1615
|
const cached2 = moduleGraph.getModuleByUrl(url);
|
|
1504
1616
|
if (cached2?.transformResult) {
|
|
1505
1617
|
return cached2.transformResult;
|
|
1506
1618
|
}
|
|
1507
1619
|
if (cleanReqUrl === "/@react-refresh") {
|
|
1508
|
-
return { code: getReactRefreshRuntimeEsm() };
|
|
1620
|
+
return { code: getReactRefreshRuntimeEsm(true) };
|
|
1509
1621
|
}
|
|
1510
1622
|
if (cleanReqUrl.startsWith("/@modules/") && url.includes("?")) {
|
|
1511
1623
|
const idParam = new URLSearchParams(url.slice(url.indexOf("?") + 1)).get("id");
|
|
@@ -1541,6 +1653,8 @@ async function transformRequest(url, ctx) {
|
|
|
1541
1653
|
}
|
|
1542
1654
|
const rawQuery = url.includes("?") ? url.slice(url.indexOf("?") + 1) : "";
|
|
1543
1655
|
if (rawQuery && !/^t=\d+$/.test(rawQuery)) {
|
|
1656
|
+
const mod2 = await moduleGraph.ensureEntryFromUrl(url);
|
|
1657
|
+
const transformVersion2 = mod2.invalidationVersion;
|
|
1544
1658
|
const loaded = await pluginContainer.load(url);
|
|
1545
1659
|
if (loaded != null) {
|
|
1546
1660
|
let code2 = typeof loaded === "string" ? loaded : loaded.code;
|
|
@@ -1548,16 +1662,28 @@ async function transformRequest(url, ctx) {
|
|
|
1548
1662
|
if (transformed != null) {
|
|
1549
1663
|
code2 = typeof transformed === "string" ? transformed : transformed.code;
|
|
1550
1664
|
}
|
|
1551
|
-
const
|
|
1552
|
-
moduleGraph.registerModule(mod2,
|
|
1553
|
-
|
|
1665
|
+
const parentFile = resolveUrlToFile(cleanReqUrl, config.root) ?? cleanReqUrl;
|
|
1666
|
+
moduleGraph.registerModule(mod2, parentFile);
|
|
1667
|
+
const hotInfo2 = rewriteHotAcceptDeps(code2, config, parentFile);
|
|
1668
|
+
code2 = injectImportMetaHot(hotInfo2.code, url);
|
|
1554
1669
|
code2 = replaceEnvInCode(code2, ctx.envDefine ?? buildEnvDefine(
|
|
1555
1670
|
loadEnv(config.mode, config.root, config.envPrefix),
|
|
1556
1671
|
config.mode
|
|
1557
1672
|
));
|
|
1558
|
-
|
|
1673
|
+
const importedUrls2 = /* @__PURE__ */ new Set();
|
|
1674
|
+
code2 = rewriteImports(code2, config, parentFile, importedUrls2, moduleGraph);
|
|
1675
|
+
const pruned2 = await moduleGraph.updateModuleInfo(
|
|
1676
|
+
mod2,
|
|
1677
|
+
importedUrls2,
|
|
1678
|
+
hotInfo2.acceptedUrls,
|
|
1679
|
+
hotInfo2.isSelfAccepting,
|
|
1680
|
+
transformVersion2
|
|
1681
|
+
);
|
|
1559
1682
|
const transformResult2 = { code: code2 };
|
|
1560
|
-
|
|
1683
|
+
if (pruned2) {
|
|
1684
|
+
if (pruned2.size > 0) ctx.onPrune?.([...pruned2].map((item) => item.url));
|
|
1685
|
+
mod2.transformResult = transformResult2;
|
|
1686
|
+
}
|
|
1561
1687
|
return transformResult2;
|
|
1562
1688
|
}
|
|
1563
1689
|
}
|
|
@@ -1565,6 +1691,7 @@ async function transformRequest(url, ctx) {
|
|
|
1565
1691
|
if (!filePath || !import_node_fs4.default.existsSync(filePath)) return null;
|
|
1566
1692
|
const mod = await moduleGraph.ensureEntryFromUrl(url);
|
|
1567
1693
|
moduleGraph.registerModule(mod, filePath);
|
|
1694
|
+
const transformVersion = mod.invalidationVersion;
|
|
1568
1695
|
if (cleanReqUrl.startsWith("/@modules/")) {
|
|
1569
1696
|
const code2 = await bundlePackageAsEsm(filePath, config.root);
|
|
1570
1697
|
const transformResult2 = { code: code2 };
|
|
@@ -1591,9 +1718,10 @@ async function transformRequest(url, ctx) {
|
|
|
1591
1718
|
if (useRefresh) {
|
|
1592
1719
|
code = buildReactRefreshWrapper(stableUrl, code);
|
|
1593
1720
|
wrappedWithRefresh = true;
|
|
1594
|
-
mod.isSelfAccepting = true;
|
|
1595
1721
|
}
|
|
1596
1722
|
}
|
|
1723
|
+
const hotInfo = rewriteHotAcceptDeps(code, config, filePath);
|
|
1724
|
+
code = hotInfo.code;
|
|
1597
1725
|
if (!wrappedWithRefresh) {
|
|
1598
1726
|
code = injectImportMetaHot(code, stableUrl);
|
|
1599
1727
|
}
|
|
@@ -1602,9 +1730,20 @@ async function transformRequest(url, ctx) {
|
|
|
1602
1730
|
config.mode
|
|
1603
1731
|
);
|
|
1604
1732
|
code = replaceEnvInCode(code, envDefine);
|
|
1605
|
-
|
|
1733
|
+
const importedUrls = /* @__PURE__ */ new Set();
|
|
1734
|
+
code = rewriteImports(code, config, filePath, importedUrls, moduleGraph);
|
|
1735
|
+
const pruned = await moduleGraph.updateModuleInfo(
|
|
1736
|
+
mod,
|
|
1737
|
+
importedUrls,
|
|
1738
|
+
hotInfo.acceptedUrls,
|
|
1739
|
+
wrappedWithRefresh || hotInfo.isSelfAccepting,
|
|
1740
|
+
transformVersion
|
|
1741
|
+
);
|
|
1606
1742
|
const transformResult = { code };
|
|
1607
|
-
|
|
1743
|
+
if (pruned) {
|
|
1744
|
+
if (pruned.size > 0) ctx.onPrune?.([...pruned].map((item) => item.url));
|
|
1745
|
+
mod.transformResult = transformResult;
|
|
1746
|
+
}
|
|
1608
1747
|
return transformResult;
|
|
1609
1748
|
}
|
|
1610
1749
|
async function loadVirtualModule(spec, ctx) {
|
|
@@ -1809,49 +1948,202 @@ async function injectCjsNamedExports(code, entryFile) {
|
|
|
1809
1948
|
return code;
|
|
1810
1949
|
}
|
|
1811
1950
|
}
|
|
1812
|
-
function rewriteImports(code, config, filePath) {
|
|
1951
|
+
function rewriteImports(code, config, filePath, importedUrls, moduleGraph) {
|
|
1952
|
+
const resolveSpec = createModuleSpecifierResolver(config, filePath);
|
|
1953
|
+
const transformSpec = (spec) => {
|
|
1954
|
+
const resolved = removeTimestampQuery(resolveSpec(spec));
|
|
1955
|
+
importedUrls?.add(resolved);
|
|
1956
|
+
const timestamp = moduleGraph?.getModuleByUrl(resolved)?.lastHMRTimestamp ?? 0;
|
|
1957
|
+
return timestamp > 0 ? appendTimestampQuery(resolved, timestamp) : resolved;
|
|
1958
|
+
};
|
|
1959
|
+
return code.replace(
|
|
1960
|
+
/\bfrom\s+(['"])([^'"]+)\1/g,
|
|
1961
|
+
(_m, q, s) => `from ${q}${transformSpec(s)}${q}`
|
|
1962
|
+
).replace(
|
|
1963
|
+
/\bimport\s+(['"])([^'"]+)\1/g,
|
|
1964
|
+
(_m, q, s) => `import ${q}${transformSpec(s)}${q}`
|
|
1965
|
+
).replace(
|
|
1966
|
+
/\bimport\s*\(\s*(['"])([^'"]+)\1\s*\)/g,
|
|
1967
|
+
(_m, q, s) => `import(${q}${transformSpec(s)}${q})`
|
|
1968
|
+
);
|
|
1969
|
+
}
|
|
1970
|
+
function createModuleSpecifierResolver(config, filePath) {
|
|
1813
1971
|
const root = config.root;
|
|
1814
1972
|
const fileDir = import_node_path4.default.dirname(filePath);
|
|
1815
1973
|
const aliasEntries = Object.entries(config.resolve.alias).sort(
|
|
1816
1974
|
([a], [b]) => b.length - a.length
|
|
1817
1975
|
);
|
|
1818
1976
|
const toRootUrl = (abs) => "/" + import_node_path4.default.relative(root, abs).replace(/\\/g, "/");
|
|
1819
|
-
|
|
1820
|
-
const suffixMatch =
|
|
1977
|
+
return (specifier) => {
|
|
1978
|
+
const suffixMatch = specifier.match(/[?#].*$/);
|
|
1821
1979
|
const suffix = suffixMatch ? suffixMatch[0] : "";
|
|
1822
|
-
const baseSpec = suffix ?
|
|
1980
|
+
const baseSpec = suffix ? specifier.slice(0, -suffix.length) : specifier;
|
|
1823
1981
|
for (const [key, value] of aliasEntries) {
|
|
1824
1982
|
if (baseSpec === key || baseSpec.startsWith(key + "/")) {
|
|
1825
1983
|
const aliasBase = resolveAliasTarget(value, root);
|
|
1826
1984
|
const sub = baseSpec.slice(key.length).replace(/^\//, "");
|
|
1827
1985
|
const target = sub ? import_node_path4.default.join(aliasBase, sub) : aliasBase;
|
|
1828
1986
|
const resolved = tryResolveDiskPath(target);
|
|
1829
|
-
return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix :
|
|
1987
|
+
return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix : specifier;
|
|
1830
1988
|
}
|
|
1831
1989
|
}
|
|
1832
1990
|
if (baseSpec.startsWith("./") || baseSpec.startsWith("../")) {
|
|
1833
|
-
const
|
|
1834
|
-
|
|
1835
|
-
return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix : spec;
|
|
1991
|
+
const resolved = tryResolveDiskPath(import_node_path4.default.resolve(fileDir, baseSpec));
|
|
1992
|
+
return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix : specifier;
|
|
1836
1993
|
}
|
|
1837
1994
|
if (baseSpec.startsWith("/") && !baseSpec.startsWith("/@")) {
|
|
1838
|
-
const
|
|
1839
|
-
|
|
1840
|
-
return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix : spec;
|
|
1995
|
+
const resolved = tryResolveDiskPath(import_node_path4.default.join(root, baseSpec.replace(/^\//, "")));
|
|
1996
|
+
return resolved && isUnderRoot(resolved, root) ? toRootUrl(resolved) + suffix : specifier;
|
|
1841
1997
|
}
|
|
1842
|
-
if (baseSpec.startsWith("/")) return
|
|
1843
|
-
return `/@modules/${
|
|
1998
|
+
if (baseSpec.startsWith("/")) return specifier;
|
|
1999
|
+
return `/@modules/${specifier}`;
|
|
1844
2000
|
};
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
)
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
)
|
|
2001
|
+
}
|
|
2002
|
+
function rewriteHotAcceptDeps(code, config, filePath) {
|
|
2003
|
+
const acceptedUrls = /* @__PURE__ */ new Set();
|
|
2004
|
+
const edits = [];
|
|
2005
|
+
const resolveSpec = createModuleSpecifierResolver(config, filePath);
|
|
2006
|
+
const acceptRE = /(?:\bimport\.meta\.hot|\b__nasti_hot__)(?:(?:\?\.)|\.)accept\s*\(/g;
|
|
2007
|
+
const searchableCode = maskStringsAndComments(code);
|
|
2008
|
+
let isSelfAccepting = false;
|
|
2009
|
+
let match;
|
|
2010
|
+
while (match = acceptRE.exec(searchableCode)) {
|
|
2011
|
+
let cursor = match.index + match[0].length;
|
|
2012
|
+
const skipTrivia = () => {
|
|
2013
|
+
while (cursor < code.length) {
|
|
2014
|
+
if (/\s/.test(code[cursor])) {
|
|
2015
|
+
cursor++;
|
|
2016
|
+
continue;
|
|
2017
|
+
}
|
|
2018
|
+
if (code[cursor] === "/" && code[cursor + 1] === "/") {
|
|
2019
|
+
cursor += 2;
|
|
2020
|
+
while (cursor < code.length && code[cursor] !== "\n") cursor++;
|
|
2021
|
+
continue;
|
|
2022
|
+
}
|
|
2023
|
+
if (code[cursor] === "/" && code[cursor + 1] === "*") {
|
|
2024
|
+
cursor += 2;
|
|
2025
|
+
while (cursor < code.length && !(code[cursor] === "*" && code[cursor + 1] === "/")) cursor++;
|
|
2026
|
+
cursor += 2;
|
|
2027
|
+
continue;
|
|
2028
|
+
}
|
|
2029
|
+
break;
|
|
2030
|
+
}
|
|
2031
|
+
};
|
|
2032
|
+
skipTrivia();
|
|
2033
|
+
const first = code[cursor];
|
|
2034
|
+
if (!first || first === ")" || first !== "[" && first !== "'" && first !== '"' && first !== "`") {
|
|
2035
|
+
isSelfAccepting = true;
|
|
2036
|
+
continue;
|
|
2037
|
+
}
|
|
2038
|
+
const readLiteral = () => {
|
|
2039
|
+
const quote = code[cursor];
|
|
2040
|
+
if (quote !== "'" && quote !== '"' && quote !== "`") return;
|
|
2041
|
+
const start = cursor;
|
|
2042
|
+
cursor++;
|
|
2043
|
+
let raw = "";
|
|
2044
|
+
while (cursor < code.length) {
|
|
2045
|
+
const char = code[cursor];
|
|
2046
|
+
if (char === "\\") {
|
|
2047
|
+
raw += code[cursor + 1] ?? "";
|
|
2048
|
+
cursor += 2;
|
|
2049
|
+
continue;
|
|
2050
|
+
}
|
|
2051
|
+
if (char === quote) {
|
|
2052
|
+
cursor++;
|
|
2053
|
+
const resolved = removeTimestampQuery(resolveSpec(raw));
|
|
2054
|
+
acceptedUrls.add(resolved);
|
|
2055
|
+
edits.push({ start, end: cursor, value: JSON.stringify(resolved) });
|
|
2056
|
+
return;
|
|
2057
|
+
}
|
|
2058
|
+
if (quote === "`" && char === "$" && code[cursor + 1] === "{") return;
|
|
2059
|
+
raw += char;
|
|
2060
|
+
cursor++;
|
|
2061
|
+
}
|
|
2062
|
+
};
|
|
2063
|
+
if (first === "[") {
|
|
2064
|
+
cursor++;
|
|
2065
|
+
while (cursor < code.length) {
|
|
2066
|
+
skipTrivia();
|
|
2067
|
+
if (code[cursor] === ",") {
|
|
2068
|
+
cursor++;
|
|
2069
|
+
skipTrivia();
|
|
2070
|
+
}
|
|
2071
|
+
if (code[cursor] === "]") break;
|
|
2072
|
+
const before = cursor;
|
|
2073
|
+
readLiteral();
|
|
2074
|
+
if (cursor === before) break;
|
|
2075
|
+
}
|
|
2076
|
+
} else {
|
|
2077
|
+
readLiteral();
|
|
2078
|
+
}
|
|
2079
|
+
}
|
|
2080
|
+
for (const edit of edits.sort((a, b) => b.start - a.start)) {
|
|
2081
|
+
code = code.slice(0, edit.start) + edit.value + code.slice(edit.end);
|
|
2082
|
+
}
|
|
2083
|
+
return { code, acceptedUrls, isSelfAccepting };
|
|
2084
|
+
}
|
|
2085
|
+
function maskStringsAndComments(code) {
|
|
2086
|
+
const masked = code.split("");
|
|
2087
|
+
let state = "code";
|
|
2088
|
+
const isRegexStart = (index2) => {
|
|
2089
|
+
let previous = index2 - 1;
|
|
2090
|
+
while (previous >= 0 && /\s/.test(code[previous])) previous--;
|
|
2091
|
+
return previous < 0 || "=(:,!&|?{};[]+-*%^~<>".includes(code[previous]);
|
|
2092
|
+
};
|
|
2093
|
+
for (let i = 0; i < code.length; i++) {
|
|
2094
|
+
const char = code[i];
|
|
2095
|
+
const next = code[i + 1];
|
|
2096
|
+
if (state === "code") {
|
|
2097
|
+
if (char === "'") state = "single";
|
|
2098
|
+
else if (char === '"') state = "double";
|
|
2099
|
+
else if (char === "`") state = "template";
|
|
2100
|
+
else if (char === "/" && next === "/") state = "line-comment";
|
|
2101
|
+
else if (char === "/" && next === "*") state = "block-comment";
|
|
2102
|
+
else if (char === "/" && isRegexStart(i)) state = "regex";
|
|
2103
|
+
else continue;
|
|
2104
|
+
masked[i] = " ";
|
|
2105
|
+
continue;
|
|
2106
|
+
}
|
|
2107
|
+
if (state === "line-comment") {
|
|
2108
|
+
if (char === "\n") {
|
|
2109
|
+
state = "code";
|
|
2110
|
+
} else {
|
|
2111
|
+
masked[i] = " ";
|
|
2112
|
+
}
|
|
2113
|
+
continue;
|
|
2114
|
+
}
|
|
2115
|
+
if (state === "block-comment") {
|
|
2116
|
+
masked[i] = char === "\n" ? "\n" : " ";
|
|
2117
|
+
if (char === "*" && next === "/") {
|
|
2118
|
+
masked[i + 1] = " ";
|
|
2119
|
+
i++;
|
|
2120
|
+
state = "code";
|
|
2121
|
+
}
|
|
2122
|
+
continue;
|
|
2123
|
+
}
|
|
2124
|
+
if (state === "regex" || state === "regex-class") {
|
|
2125
|
+
masked[i] = char === "\n" ? "\n" : " ";
|
|
2126
|
+
if (char === "\\") {
|
|
2127
|
+
if (i + 1 < code.length) masked[++i] = " ";
|
|
2128
|
+
} else if (state === "regex" && char === "[") {
|
|
2129
|
+
state = "regex-class";
|
|
2130
|
+
} else if (state === "regex-class" && char === "]") {
|
|
2131
|
+
state = "regex";
|
|
2132
|
+
} else if (state === "regex" && char === "/") {
|
|
2133
|
+
state = "code";
|
|
2134
|
+
}
|
|
2135
|
+
continue;
|
|
2136
|
+
}
|
|
2137
|
+
masked[i] = char === "\n" ? "\n" : " ";
|
|
2138
|
+
if (char === "\\") {
|
|
2139
|
+
if (i + 1 < code.length) masked[++i] = " ";
|
|
2140
|
+
continue;
|
|
2141
|
+
}
|
|
2142
|
+
if (state === "single" && char === "'" || state === "double" && char === '"' || state === "template" && char === "`") {
|
|
2143
|
+
state = "code";
|
|
2144
|
+
}
|
|
2145
|
+
}
|
|
2146
|
+
return masked.join("");
|
|
1855
2147
|
}
|
|
1856
2148
|
function resolveAliasTarget(value, root) {
|
|
1857
2149
|
if (import_node_path4.default.isAbsolute(value) && import_node_fs4.default.existsSync(value)) return value;
|
|
@@ -1876,6 +2168,12 @@ function isUnderRoot(abs, root) {
|
|
|
1876
2168
|
const rel = import_node_path4.default.relative(root, abs);
|
|
1877
2169
|
return !!rel && !rel.startsWith("..") && !import_node_path4.default.isAbsolute(rel);
|
|
1878
2170
|
}
|
|
2171
|
+
function appendTimestampQuery(url, timestamp) {
|
|
2172
|
+
const hashIndex = url.indexOf("#");
|
|
2173
|
+
const hash = hashIndex >= 0 ? url.slice(hashIndex) : "";
|
|
2174
|
+
const withoutHash = hashIndex >= 0 ? url.slice(0, hashIndex) : url;
|
|
2175
|
+
return `${withoutHash}${withoutHash.includes("?") ? "&" : "?"}t=${timestamp}${hash}`;
|
|
2176
|
+
}
|
|
1879
2177
|
function externalSpecToModuleUrl(spec, baseDir, root) {
|
|
1880
2178
|
const resolved = resolveNodeModule(baseDir, spec);
|
|
1881
2179
|
if (!resolved) return `/@modules/${spec}`;
|
|
@@ -2019,30 +2317,29 @@ function isModuleRequest(url) {
|
|
|
2019
2317
|
function getHmrClientCode() {
|
|
2020
2318
|
return `
|
|
2021
2319
|
// Nasti HMR Client
|
|
2022
|
-
const
|
|
2320
|
+
const socketProtocol = location.protocol === 'https:' ? 'wss' : 'ws';
|
|
2321
|
+
const socket = new WebSocket(socketProtocol + '://' + location.host, 'nasti-hmr');
|
|
2023
2322
|
const hotModulesMap = new Map();
|
|
2024
2323
|
const disposeMap = new Map();
|
|
2025
2324
|
const pruneMap = new Map();
|
|
2325
|
+
const dataMap = new Map();
|
|
2326
|
+
let updateQueue = [];
|
|
2327
|
+
let pendingUpdateQueue = false;
|
|
2026
2328
|
|
|
2027
2329
|
socket.addEventListener('message', async ({ data }) => {
|
|
2028
2330
|
const payload = JSON.parse(data);
|
|
2029
2331
|
switch (payload.type) {
|
|
2030
2332
|
case 'connected':
|
|
2031
|
-
console.
|
|
2333
|
+
console.debug('[nasti] connected.');
|
|
2032
2334
|
clearErrorOverlay();
|
|
2033
2335
|
break;
|
|
2034
2336
|
case 'update':
|
|
2035
2337
|
try {
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
} else if (update.type === 'css-update') {
|
|
2040
|
-
return updateCss(update.path);
|
|
2041
|
-
}
|
|
2042
|
-
}));
|
|
2338
|
+
// CSS \u5728 unbundled \u6A21\u5F0F\u4E0B\u4E5F\u662F\u4F1A\u6CE8\u5165 <style> \u7684 JS \u6A21\u5757\uFF0C\u548C\u666E\u901A JS
|
|
2339
|
+
// \u4E00\u6837\u91CD\u65B0 import \u624D\u80FD\u6267\u884C dispose/accept \u5E76\u4FDD\u6301\u9875\u9762\u72B6\u6001\u3002
|
|
2340
|
+
await Promise.all(payload.updates.map(queueUpdate));
|
|
2043
2341
|
clearErrorOverlay();
|
|
2044
|
-
console.
|
|
2045
|
-
location.reload();
|
|
2342
|
+
console.debug('[nasti] HMR update complete.');
|
|
2046
2343
|
} catch (err) {
|
|
2047
2344
|
console.error('[nasti] HMR update failed:', err);
|
|
2048
2345
|
showErrorOverlay(err);
|
|
@@ -2053,10 +2350,17 @@ socket.addEventListener('message', async ({ data }) => {
|
|
|
2053
2350
|
location.reload();
|
|
2054
2351
|
break;
|
|
2055
2352
|
case 'prune':
|
|
2056
|
-
payload.paths.
|
|
2057
|
-
const
|
|
2058
|
-
|
|
2059
|
-
|
|
2353
|
+
await Promise.all(payload.paths.map(async (path) => {
|
|
2354
|
+
const data = dataMap.get(path);
|
|
2355
|
+
const dispose = disposeMap.get(path);
|
|
2356
|
+
const prune = pruneMap.get(path);
|
|
2357
|
+
if (dispose) await dispose(data);
|
|
2358
|
+
if (prune) await prune(data);
|
|
2359
|
+
hotModulesMap.delete(path);
|
|
2360
|
+
disposeMap.delete(path);
|
|
2361
|
+
pruneMap.delete(path);
|
|
2362
|
+
dataMap.delete(path);
|
|
2363
|
+
}));
|
|
2060
2364
|
break;
|
|
2061
2365
|
case 'error':
|
|
2062
2366
|
console.error('[nasti] error:', payload.err.message);
|
|
@@ -2065,33 +2369,64 @@ socket.addEventListener('message', async ({ data }) => {
|
|
|
2065
2369
|
}
|
|
2066
2370
|
});
|
|
2067
2371
|
|
|
2068
|
-
// \
|
|
2372
|
+
// \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
2373
|
let reconnectTimer = 0;
|
|
2070
2374
|
socket.addEventListener('close', () => {
|
|
2071
2375
|
clearTimeout(reconnectTimer);
|
|
2072
2376
|
reconnectTimer = setTimeout(() => location.reload(), 1000);
|
|
2073
2377
|
});
|
|
2074
2378
|
|
|
2379
|
+
/**
|
|
2380
|
+
* \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
|
|
2381
|
+
* \u6539\u53D8\u6A21\u5757\u5E94\u7528\u987A\u5E8F\u3002\u8FD9\u4E0E Vite HMRClient \u7684 fetch/apply \u4E24\u9636\u6BB5\u4E00\u81F4\u3002
|
|
2382
|
+
*/
|
|
2383
|
+
async function queueUpdate(update) {
|
|
2384
|
+
updateQueue.push(fetchUpdate(update));
|
|
2385
|
+
if (pendingUpdateQueue) return;
|
|
2386
|
+
|
|
2387
|
+
pendingUpdateQueue = true;
|
|
2388
|
+
await Promise.resolve();
|
|
2389
|
+
pendingUpdateQueue = false;
|
|
2390
|
+
const loading = updateQueue;
|
|
2391
|
+
updateQueue = [];
|
|
2392
|
+
const applyUpdates = await Promise.all(loading);
|
|
2393
|
+
for (const apply of applyUpdates) {
|
|
2394
|
+
if (apply) apply();
|
|
2395
|
+
}
|
|
2396
|
+
}
|
|
2397
|
+
|
|
2075
2398
|
async function fetchUpdate(update) {
|
|
2076
2399
|
const mod = hotModulesMap.get(update.path);
|
|
2077
|
-
// \
|
|
2078
|
-
|
|
2079
|
-
if (dispose) dispose();
|
|
2400
|
+
// \u5C1A\u672A\u5728\u5F53\u524D\u9875\u9762\u52A0\u8F7D\u7684\u52A8\u6001\u6A21\u5757\u4E0D\u9700\u8981\u66F4\u65B0\u3002
|
|
2401
|
+
if (!mod) return;
|
|
2080
2402
|
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2403
|
+
// \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
|
|
2404
|
+
const qualifiedCallbacks = mod.callbacks.filter(({ deps }) =>
|
|
2405
|
+
deps.includes(update.acceptedPath)
|
|
2406
|
+
);
|
|
2407
|
+
const isSelfUpdate = update.path === update.acceptedPath;
|
|
2408
|
+
if (!isSelfUpdate && qualifiedCallbacks.length === 0) return;
|
|
2409
|
+
|
|
2410
|
+
const dispose = disposeMap.get(update.acceptedPath);
|
|
2411
|
+
if (dispose) await dispose(dataMap.get(update.acceptedPath));
|
|
2412
|
+
const newMod = await import(appendTimestampQuery(update.acceptedPath, update.timestamp));
|
|
2413
|
+
|
|
2414
|
+
return () => {
|
|
2415
|
+
for (const { deps, fn } of qualifiedCallbacks) {
|
|
2416
|
+
fn(deps.map((dep) => dep === update.acceptedPath ? newMod : undefined));
|
|
2417
|
+
}
|
|
2418
|
+
const detail = isSelfUpdate
|
|
2419
|
+
? update.path
|
|
2420
|
+
: update.acceptedPath + ' via ' + update.path;
|
|
2421
|
+
console.debug('[nasti] hot updated:', detail);
|
|
2422
|
+
};
|
|
2086
2423
|
}
|
|
2087
2424
|
|
|
2088
|
-
function
|
|
2089
|
-
const
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
.then(css => { el.textContent = css; });
|
|
2094
|
-
}
|
|
2425
|
+
function appendTimestampQuery(url, timestamp) {
|
|
2426
|
+
const hashIndex = url.indexOf('#');
|
|
2427
|
+
const hash = hashIndex >= 0 ? url.slice(hashIndex) : '';
|
|
2428
|
+
const withoutHash = hashIndex >= 0 ? url.slice(0, hashIndex) : url;
|
|
2429
|
+
return withoutHash + (withoutHash.includes('?') ? '&' : '?') + 't=' + timestamp + hash;
|
|
2095
2430
|
}
|
|
2096
2431
|
|
|
2097
2432
|
function clearErrorOverlay() {
|
|
@@ -2119,23 +2454,30 @@ function showErrorOverlay(err) {
|
|
|
2119
2454
|
document.body.appendChild(overlay);
|
|
2120
2455
|
}
|
|
2121
2456
|
|
|
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
2457
|
export function createHotContext(ownerPath) {
|
|
2458
|
+
if (!dataMap.has(ownerPath)) dataMap.set(ownerPath, {});
|
|
2459
|
+
|
|
2460
|
+
// \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
|
|
2461
|
+
const existing = hotModulesMap.get(ownerPath);
|
|
2462
|
+
if (existing) existing.callbacks = [];
|
|
2463
|
+
|
|
2464
|
+
const acceptDeps = (deps, callback = () => {}) => {
|
|
2465
|
+
const mod = hotModulesMap.get(ownerPath) || { id: ownerPath, callbacks: [] };
|
|
2466
|
+
mod.callbacks.push({ deps, fn: callback });
|
|
2467
|
+
hotModulesMap.set(ownerPath, mod);
|
|
2468
|
+
};
|
|
2469
|
+
|
|
2129
2470
|
return {
|
|
2130
2471
|
accept(deps, callback) {
|
|
2131
|
-
// \u81EA\u63A5\u53D7: hot.accept() \u6216 hot.accept(callback)
|
|
2132
2472
|
if (typeof deps === 'function' || deps === undefined) {
|
|
2133
|
-
|
|
2134
|
-
|
|
2473
|
+
acceptDeps([ownerPath], ([mod]) => deps?.(mod));
|
|
2474
|
+
} else if (typeof deps === 'string') {
|
|
2475
|
+
acceptDeps([deps], ([mod]) => callback?.(mod));
|
|
2476
|
+
} else if (Array.isArray(deps)) {
|
|
2477
|
+
acceptDeps(deps, callback);
|
|
2478
|
+
} else {
|
|
2479
|
+
throw new Error('invalid hot.accept() usage');
|
|
2135
2480
|
}
|
|
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
2481
|
},
|
|
2140
2482
|
prune(callback) {
|
|
2141
2483
|
pruneMap.set(ownerPath, callback);
|
|
@@ -2146,12 +2488,12 @@ export function createHotContext(ownerPath) {
|
|
|
2146
2488
|
invalidate() {
|
|
2147
2489
|
location.reload();
|
|
2148
2490
|
},
|
|
2149
|
-
data:
|
|
2491
|
+
data: dataMap.get(ownerPath),
|
|
2150
2492
|
};
|
|
2151
2493
|
}
|
|
2152
2494
|
`;
|
|
2153
2495
|
}
|
|
2154
|
-
var import_node_path4, import_node_fs4, import_node_module, import_node_url2, import_picocolors3, import_meta, __dirname_esm, __require, __refreshRuntimeCache, REACT_REFRESH_GLOBAL_PREAMBLE, esmBundleCache, VALID_IDENT, RESOLVE_EXTENSIONS, ESM_CONDITIONS;
|
|
2496
|
+
var import_node_path4, import_node_fs4, 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
2497
|
var init_middleware = __esm({
|
|
2156
2498
|
"src/server/middleware.ts"() {
|
|
2157
2499
|
"use strict";
|
|
@@ -2163,10 +2505,74 @@ var init_middleware = __esm({
|
|
|
2163
2505
|
init_transformer();
|
|
2164
2506
|
init_html();
|
|
2165
2507
|
init_env();
|
|
2508
|
+
init_url();
|
|
2166
2509
|
import_meta = {};
|
|
2167
2510
|
__dirname_esm = import_node_path4.default.dirname((0, import_node_url2.fileURLToPath)(import_meta.url));
|
|
2168
2511
|
__require = (0, import_node_module.createRequire)(import_meta.url);
|
|
2169
2512
|
__refreshRuntimeCache = null;
|
|
2513
|
+
REACT_REFRESH_BOUNDARY_HELPERS = `
|
|
2514
|
+
function __nastiIsPlainObject(obj) {
|
|
2515
|
+
return Object.prototype.toString.call(obj) === '[object Object]' &&
|
|
2516
|
+
(obj.constructor === Object || obj.constructor === undefined);
|
|
2517
|
+
}
|
|
2518
|
+
function __nastiIsCompoundComponent(type) {
|
|
2519
|
+
if (!__nastiIsPlainObject(type)) return false;
|
|
2520
|
+
for (const key in type) {
|
|
2521
|
+
if (!isLikelyComponentType(type[key])) return false;
|
|
2522
|
+
}
|
|
2523
|
+
return true;
|
|
2524
|
+
}
|
|
2525
|
+
export function registerExportsForReactRefresh(filename, moduleExports) {
|
|
2526
|
+
for (const key in moduleExports) {
|
|
2527
|
+
if (key === '__esModule') continue;
|
|
2528
|
+
const value = moduleExports[key];
|
|
2529
|
+
if (isLikelyComponentType(value)) {
|
|
2530
|
+
register(value, filename + ' export ' + key);
|
|
2531
|
+
} else if (__nastiIsCompoundComponent(value)) {
|
|
2532
|
+
for (const subKey in value) {
|
|
2533
|
+
register(value[subKey], filename + ' export ' + key + '-' + subKey);
|
|
2534
|
+
}
|
|
2535
|
+
}
|
|
2536
|
+
}
|
|
2537
|
+
}
|
|
2538
|
+
let __nastiRefreshTimer;
|
|
2539
|
+
function __nastiEnqueueRefresh() {
|
|
2540
|
+
clearTimeout(__nastiRefreshTimer);
|
|
2541
|
+
__nastiRefreshTimer = setTimeout(() => performReactRefresh(), 16);
|
|
2542
|
+
}
|
|
2543
|
+
function __nastiCheckExports(ignored, exports, predicate) {
|
|
2544
|
+
for (const key in exports) {
|
|
2545
|
+
if (ignored.includes(key)) continue;
|
|
2546
|
+
if (!predicate(key, exports[key])) return key;
|
|
2547
|
+
}
|
|
2548
|
+
return true;
|
|
2549
|
+
}
|
|
2550
|
+
export function validateRefreshBoundaryAndEnqueueUpdate(id, prevExports, nextExports) {
|
|
2551
|
+
const ignored = window.__getReactRefreshIgnoredExports?.({ id }) ?? [];
|
|
2552
|
+
if (__nastiCheckExports(ignored, prevExports, (key) => key in nextExports) !== true) {
|
|
2553
|
+
return 'Could not Fast Refresh (export removed)';
|
|
2554
|
+
}
|
|
2555
|
+
if (__nastiCheckExports(ignored, nextExports, (key) => key in prevExports) !== true) {
|
|
2556
|
+
return 'Could not Fast Refresh (new export)';
|
|
2557
|
+
}
|
|
2558
|
+
let hasExports = false;
|
|
2559
|
+
const compatible = __nastiCheckExports(ignored, nextExports, (key, value) => {
|
|
2560
|
+
hasExports = true;
|
|
2561
|
+
return isLikelyComponentType(value) ||
|
|
2562
|
+
__nastiIsCompoundComponent(value) ||
|
|
2563
|
+
prevExports[key] === value;
|
|
2564
|
+
});
|
|
2565
|
+
if (!hasExports) {
|
|
2566
|
+
return 'Could not Fast Refresh (no exports)';
|
|
2567
|
+
}
|
|
2568
|
+
if (compatible === true) {
|
|
2569
|
+
__nastiEnqueueRefresh();
|
|
2570
|
+
return;
|
|
2571
|
+
}
|
|
2572
|
+
return 'Could not Fast Refresh ("' + compatible + '" export is incompatible)';
|
|
2573
|
+
}
|
|
2574
|
+
export const __hmr_import = (module) => import(module);
|
|
2575
|
+
`;
|
|
2170
2576
|
REACT_REFRESH_GLOBAL_PREAMBLE = `
|
|
2171
2577
|
import RefreshRuntime from "/@react-refresh";
|
|
2172
2578
|
RefreshRuntime.injectIntoGlobalHook(window);
|
|
@@ -2193,8 +2599,10 @@ async function handleFileChange(file, server) {
|
|
|
2193
2599
|
}
|
|
2194
2600
|
const updates = [];
|
|
2195
2601
|
const timestamp = Date.now();
|
|
2602
|
+
const graph = moduleGraph;
|
|
2603
|
+
const invalidatedModules = /* @__PURE__ */ new Set();
|
|
2196
2604
|
for (const mod of mods) {
|
|
2197
|
-
|
|
2605
|
+
graph.invalidateModuleAndImporters(mod, timestamp, invalidatedModules);
|
|
2198
2606
|
const ctx = {
|
|
2199
2607
|
file,
|
|
2200
2608
|
timestamp,
|
|
@@ -2212,19 +2620,25 @@ async function handleFileChange(file, server) {
|
|
|
2212
2620
|
}
|
|
2213
2621
|
}
|
|
2214
2622
|
for (const affected of affectedModules) {
|
|
2215
|
-
|
|
2623
|
+
graph.invalidateModuleAndImporters(affected, timestamp, invalidatedModules);
|
|
2624
|
+
const boundaries = graph.getHmrBoundaries(affected);
|
|
2216
2625
|
if (boundaries.length === 0) {
|
|
2217
2626
|
logger.info(import_picocolors4.default.green("page reload ") + import_picocolors4.default.dim(shortFile), { timestamp: true });
|
|
2218
2627
|
ws.send({ type: "full-reload", path: relativePath });
|
|
2219
2628
|
return;
|
|
2220
2629
|
}
|
|
2221
|
-
for (const { boundary } of boundaries) {
|
|
2222
|
-
|
|
2630
|
+
for (const { boundary, acceptedVia } of boundaries) {
|
|
2631
|
+
const update = {
|
|
2223
2632
|
type: boundary.type === "css" ? "css-update" : "js-update",
|
|
2224
2633
|
path: boundary.url,
|
|
2225
|
-
acceptedPath:
|
|
2634
|
+
acceptedPath: acceptedVia.url,
|
|
2226
2635
|
timestamp
|
|
2227
|
-
}
|
|
2636
|
+
};
|
|
2637
|
+
if (!updates.some(
|
|
2638
|
+
(existing) => existing.type === update.type && existing.path === update.path && existing.acceptedPath === update.acceptedPath
|
|
2639
|
+
)) {
|
|
2640
|
+
updates.push(update);
|
|
2641
|
+
}
|
|
2228
2642
|
}
|
|
2229
2643
|
}
|
|
2230
2644
|
}
|
|
@@ -2295,6 +2709,7 @@ function resolvePlugin(config) {
|
|
|
2295
2709
|
}
|
|
2296
2710
|
if (!source.startsWith("/") && !source.startsWith(".")) {
|
|
2297
2711
|
if (vueRuntimeEntry && source === "vue") return vueRuntimeEntry;
|
|
2712
|
+
if (config.command === "build") return null;
|
|
2298
2713
|
try {
|
|
2299
2714
|
const resolved = require2.resolve(source, {
|
|
2300
2715
|
paths: [importer ? import_node_path6.default.dirname(importer) : config.root]
|
|
@@ -2387,27 +2802,27 @@ var require_process = __commonJS({
|
|
|
2387
2802
|
var require_filesystem = __commonJS({
|
|
2388
2803
|
"node_modules/detect-libc/lib/filesystem.js"(exports2, module2) {
|
|
2389
2804
|
"use strict";
|
|
2390
|
-
var
|
|
2805
|
+
var fs13 = require("fs");
|
|
2391
2806
|
var LDD_PATH = "/usr/bin/ldd";
|
|
2392
2807
|
var SELF_PATH = "/proc/self/exe";
|
|
2393
2808
|
var MAX_LENGTH = 2048;
|
|
2394
|
-
var readFileSync = (
|
|
2395
|
-
const fd =
|
|
2809
|
+
var readFileSync = (path18) => {
|
|
2810
|
+
const fd = fs13.openSync(path18, "r");
|
|
2396
2811
|
const buffer = Buffer.alloc(MAX_LENGTH);
|
|
2397
|
-
const bytesRead =
|
|
2398
|
-
|
|
2812
|
+
const bytesRead = fs13.readSync(fd, buffer, 0, MAX_LENGTH, 0);
|
|
2813
|
+
fs13.close(fd, () => {
|
|
2399
2814
|
});
|
|
2400
2815
|
return buffer.subarray(0, bytesRead);
|
|
2401
2816
|
};
|
|
2402
|
-
var readFile = (
|
|
2403
|
-
|
|
2817
|
+
var readFile = (path18) => new Promise((resolve, reject) => {
|
|
2818
|
+
fs13.open(path18, "r", (err, fd) => {
|
|
2404
2819
|
if (err) {
|
|
2405
2820
|
reject(err);
|
|
2406
2821
|
} else {
|
|
2407
2822
|
const buffer = Buffer.alloc(MAX_LENGTH);
|
|
2408
|
-
|
|
2823
|
+
fs13.read(fd, buffer, 0, MAX_LENGTH, 0, (_, bytesRead) => {
|
|
2409
2824
|
resolve(buffer.subarray(0, bytesRead));
|
|
2410
|
-
|
|
2825
|
+
fs13.close(fd, () => {
|
|
2411
2826
|
});
|
|
2412
2827
|
});
|
|
2413
2828
|
}
|
|
@@ -2519,11 +2934,11 @@ var require_detect_libc = __commonJS({
|
|
|
2519
2934
|
}
|
|
2520
2935
|
return null;
|
|
2521
2936
|
};
|
|
2522
|
-
var familyFromInterpreterPath = (
|
|
2523
|
-
if (
|
|
2524
|
-
if (
|
|
2937
|
+
var familyFromInterpreterPath = (path18) => {
|
|
2938
|
+
if (path18) {
|
|
2939
|
+
if (path18.includes("/ld-musl-")) {
|
|
2525
2940
|
return MUSL;
|
|
2526
|
-
} else if (
|
|
2941
|
+
} else if (path18.includes("/ld-linux-")) {
|
|
2527
2942
|
return GLIBC;
|
|
2528
2943
|
}
|
|
2529
2944
|
}
|
|
@@ -2570,8 +2985,8 @@ var require_detect_libc = __commonJS({
|
|
|
2570
2985
|
cachedFamilyInterpreter = null;
|
|
2571
2986
|
try {
|
|
2572
2987
|
const selfContent = await readFile(SELF_PATH);
|
|
2573
|
-
const
|
|
2574
|
-
cachedFamilyInterpreter = familyFromInterpreterPath(
|
|
2988
|
+
const path18 = interpreterPath(selfContent);
|
|
2989
|
+
cachedFamilyInterpreter = familyFromInterpreterPath(path18);
|
|
2575
2990
|
} catch (e) {
|
|
2576
2991
|
}
|
|
2577
2992
|
return cachedFamilyInterpreter;
|
|
@@ -2583,8 +2998,8 @@ var require_detect_libc = __commonJS({
|
|
|
2583
2998
|
cachedFamilyInterpreter = null;
|
|
2584
2999
|
try {
|
|
2585
3000
|
const selfContent = readFileSync(SELF_PATH);
|
|
2586
|
-
const
|
|
2587
|
-
cachedFamilyInterpreter = familyFromInterpreterPath(
|
|
3001
|
+
const path18 = interpreterPath(selfContent);
|
|
3002
|
+
cachedFamilyInterpreter = familyFromInterpreterPath(path18);
|
|
2588
3003
|
} catch (e) {
|
|
2589
3004
|
}
|
|
2590
3005
|
return cachedFamilyInterpreter;
|
|
@@ -3610,8 +4025,8 @@ function vuePlugin(config) {
|
|
|
3610
4025
|
let descriptor = descriptorCache.get(filePath);
|
|
3611
4026
|
if (!descriptor) {
|
|
3612
4027
|
try {
|
|
3613
|
-
const
|
|
3614
|
-
const source =
|
|
4028
|
+
const fs13 = await import("fs");
|
|
4029
|
+
const source = fs13.readFileSync(filePath, "utf-8");
|
|
3615
4030
|
const parsed = sfc.parse(source, { filename: filePath });
|
|
3616
4031
|
if (parsed.errors.length) return null;
|
|
3617
4032
|
descriptor = parsed.descriptor;
|
|
@@ -3750,16 +4165,27 @@ var init_vue = __esm({
|
|
|
3750
4165
|
// src/plugins/builtins.ts
|
|
3751
4166
|
function resolvePluginList(config, userPlugins, opts = {}) {
|
|
3752
4167
|
const isServe = config.command === "serve";
|
|
4168
|
+
let environmentOptions;
|
|
4169
|
+
if (opts.environmentName) {
|
|
4170
|
+
environmentOptions = config.environments[opts.environmentName];
|
|
4171
|
+
if (!environmentOptions) {
|
|
4172
|
+
throw new Error(
|
|
4173
|
+
`[nasti] unknown environment "${opts.environmentName}" \u2014 declare it in config.environments`
|
|
4174
|
+
);
|
|
4175
|
+
}
|
|
4176
|
+
}
|
|
4177
|
+
const pluginConfig = environmentOptions ? { ...config, resolve: environmentOptions.resolve, build: environmentOptions.build } : config;
|
|
4178
|
+
const consumer = opts.consumer ?? environmentOptions?.consumer;
|
|
3753
4179
|
return [
|
|
3754
4180
|
// vuePlugin 排最前(enforce: 'pre' 语义):.vue 先编译成 JS 再走后续管道
|
|
3755
|
-
...config.framework === "vue" ? [vuePlugin(
|
|
3756
|
-
resolvePlugin(
|
|
3757
|
-
cssPlugin(
|
|
3758
|
-
assetsPlugin(
|
|
3759
|
-
...isServe ? [htmlPlugin(
|
|
4181
|
+
...config.framework === "vue" ? [vuePlugin(pluginConfig)] : [],
|
|
4182
|
+
resolvePlugin(pluginConfig),
|
|
4183
|
+
cssPlugin(pluginConfig, opts.cssEngine, consumer),
|
|
4184
|
+
assetsPlugin(pluginConfig),
|
|
4185
|
+
...isServe ? [htmlPlugin(pluginConfig)] : [],
|
|
3760
4186
|
...userPlugins,
|
|
3761
4187
|
// cssPostPlugin 最后(enforce: 'post' 语义):renderChunk 聚合抽取
|
|
3762
|
-
...!isServe && opts.cssEngine ? [cssPostPlugin(
|
|
4188
|
+
...!isServe && opts.cssEngine ? [cssPostPlugin(pluginConfig, opts.cssEngine)] : []
|
|
3763
4189
|
];
|
|
3764
4190
|
}
|
|
3765
4191
|
var init_builtins = __esm({
|
|
@@ -4083,6 +4509,135 @@ var init_reporter = __esm({
|
|
|
4083
4509
|
}
|
|
4084
4510
|
});
|
|
4085
4511
|
|
|
4512
|
+
// src/core/build-app-context.ts
|
|
4513
|
+
function createBuildAppContext(config, results) {
|
|
4514
|
+
const output = [];
|
|
4515
|
+
const emitted = /* @__PURE__ */ new Set();
|
|
4516
|
+
const outDir = import_node_path12.default.resolve(config.root, config.build.outDir);
|
|
4517
|
+
let environmentArtifacts;
|
|
4518
|
+
return {
|
|
4519
|
+
config,
|
|
4520
|
+
results,
|
|
4521
|
+
get output() {
|
|
4522
|
+
return Object.freeze([...output]);
|
|
4523
|
+
},
|
|
4524
|
+
getResult(environmentName) {
|
|
4525
|
+
return results[environmentName];
|
|
4526
|
+
},
|
|
4527
|
+
getArtifact(environmentName, fileName) {
|
|
4528
|
+
const normalized = normalizeEnvironmentFileName(fileName);
|
|
4529
|
+
return results[environmentName]?.output.find(
|
|
4530
|
+
(artifact) => normalizeEnvironmentFileName(artifact.fileName) === normalized
|
|
4531
|
+
);
|
|
4532
|
+
},
|
|
4533
|
+
getEntry(environmentName, entryName) {
|
|
4534
|
+
const result = results[environmentName];
|
|
4535
|
+
const fileName = result?.entries?.[entryName];
|
|
4536
|
+
if (!fileName) return void 0;
|
|
4537
|
+
return result.output.find(
|
|
4538
|
+
(artifact) => normalizeEnvironmentFileName(artifact.fileName) === normalizeEnvironmentFileName(fileName)
|
|
4539
|
+
);
|
|
4540
|
+
},
|
|
4541
|
+
getManifest(environmentName) {
|
|
4542
|
+
return results[environmentName]?.manifest;
|
|
4543
|
+
},
|
|
4544
|
+
emitFile(file) {
|
|
4545
|
+
const fileName = normalizeAppFileName(file.fileName);
|
|
4546
|
+
const collisionKey = artifactCollisionKey(fileName);
|
|
4547
|
+
if (emitted.has(collisionKey)) {
|
|
4548
|
+
throw new Error(`[nasti] app artifact already emitted: ${fileName}`);
|
|
4549
|
+
}
|
|
4550
|
+
environmentArtifacts ??= collectEnvironmentArtifacts(config, results, outDir);
|
|
4551
|
+
if (environmentArtifacts.has(collisionKey)) {
|
|
4552
|
+
throw new Error(`[nasti] app artifact conflicts with environment output: ${fileName}`);
|
|
4553
|
+
}
|
|
4554
|
+
const target = import_node_path12.default.resolve(outDir, ...fileName.split("/"));
|
|
4555
|
+
const relative = import_node_path12.default.relative(outDir, target);
|
|
4556
|
+
if (relative.startsWith("..") || import_node_path12.default.isAbsolute(relative)) {
|
|
4557
|
+
throw new Error(`[nasti] app artifact must stay inside build.outDir: ${file.fileName}`);
|
|
4558
|
+
}
|
|
4559
|
+
assertNoSymlinkComponents(outDir, fileName);
|
|
4560
|
+
import_node_fs9.default.mkdirSync(import_node_path12.default.dirname(target), { recursive: true });
|
|
4561
|
+
import_node_fs9.default.writeFileSync(target, file.source);
|
|
4562
|
+
const artifact = {
|
|
4563
|
+
...file,
|
|
4564
|
+
fileName,
|
|
4565
|
+
type: "asset"
|
|
4566
|
+
};
|
|
4567
|
+
emitted.add(collisionKey);
|
|
4568
|
+
output.push(artifact);
|
|
4569
|
+
return fileName;
|
|
4570
|
+
}
|
|
4571
|
+
};
|
|
4572
|
+
}
|
|
4573
|
+
function normalizeEnvironmentFileName(fileName) {
|
|
4574
|
+
return import_node_path12.default.posix.normalize(fileName.replace(/\\/g, "/").replace(/^\.\//, ""));
|
|
4575
|
+
}
|
|
4576
|
+
function isInvalidEnvironmentFileName(fileName) {
|
|
4577
|
+
return !fileName || fileName === "." || fileName === ".." || fileName.startsWith("../") || import_node_path12.default.posix.isAbsolute(fileName) || /^[A-Za-z]:\//.test(fileName);
|
|
4578
|
+
}
|
|
4579
|
+
function normalizeAppFileName(fileName) {
|
|
4580
|
+
const normalized = normalizeEnvironmentFileName(fileName);
|
|
4581
|
+
if (isInvalidEnvironmentFileName(normalized)) {
|
|
4582
|
+
throw new Error(`[nasti] invalid app artifact fileName: ${fileName}`);
|
|
4583
|
+
}
|
|
4584
|
+
return normalized;
|
|
4585
|
+
}
|
|
4586
|
+
function artifactCollisionKey(fileName) {
|
|
4587
|
+
return normalizeEnvironmentFileName(fileName).toLowerCase();
|
|
4588
|
+
}
|
|
4589
|
+
function collectEnvironmentArtifacts(config, results, appOutDir) {
|
|
4590
|
+
const occupied = /* @__PURE__ */ new Set();
|
|
4591
|
+
for (const [environmentName, result] of Object.entries(results)) {
|
|
4592
|
+
const environment = config.environments[environmentName];
|
|
4593
|
+
if (!environment) continue;
|
|
4594
|
+
const environmentOutDir = import_node_path12.default.resolve(config.root, environment.build.outDir);
|
|
4595
|
+
for (const artifact of result.output) {
|
|
4596
|
+
const artifactPath = import_node_path12.default.resolve(
|
|
4597
|
+
environmentOutDir,
|
|
4598
|
+
...normalizeEnvironmentFileName(artifact.fileName).split("/")
|
|
4599
|
+
);
|
|
4600
|
+
const relative = import_node_path12.default.relative(appOutDir, artifactPath);
|
|
4601
|
+
if (!relative.startsWith("..") && !import_node_path12.default.isAbsolute(relative)) {
|
|
4602
|
+
occupied.add(artifactCollisionKey(relative));
|
|
4603
|
+
}
|
|
4604
|
+
}
|
|
4605
|
+
}
|
|
4606
|
+
return occupied;
|
|
4607
|
+
}
|
|
4608
|
+
function assertNoSymlinkComponents(outDir, fileName) {
|
|
4609
|
+
let current = outDir;
|
|
4610
|
+
for (const segment of fileName.split("/")) {
|
|
4611
|
+
current = import_node_path12.default.join(current, segment);
|
|
4612
|
+
let stats;
|
|
4613
|
+
try {
|
|
4614
|
+
stats = import_node_fs9.default.lstatSync(current);
|
|
4615
|
+
} catch (error) {
|
|
4616
|
+
if (error.code === "ENOENT") continue;
|
|
4617
|
+
throw error;
|
|
4618
|
+
}
|
|
4619
|
+
if (stats.isSymbolicLink()) {
|
|
4620
|
+
throw new Error(`[nasti] app artifact path cannot traverse a symlink: ${fileName}`);
|
|
4621
|
+
}
|
|
4622
|
+
}
|
|
4623
|
+
}
|
|
4624
|
+
function inferEnvironmentEntries(output) {
|
|
4625
|
+
const entries = {};
|
|
4626
|
+
for (const artifact of output) {
|
|
4627
|
+
if (artifact.type !== "chunk" || !artifact.isEntry || !artifact.name) continue;
|
|
4628
|
+
entries[artifact.name] = normalizeEnvironmentFileName(artifact.fileName);
|
|
4629
|
+
}
|
|
4630
|
+
return Object.keys(entries).length > 0 ? entries : void 0;
|
|
4631
|
+
}
|
|
4632
|
+
var import_node_fs9, import_node_path12;
|
|
4633
|
+
var init_build_app_context = __esm({
|
|
4634
|
+
"src/core/build-app-context.ts"() {
|
|
4635
|
+
"use strict";
|
|
4636
|
+
import_node_fs9 = __toESM(require("fs"), 1);
|
|
4637
|
+
import_node_path12 = __toESM(require("path"), 1);
|
|
4638
|
+
}
|
|
4639
|
+
});
|
|
4640
|
+
|
|
4086
4641
|
// src/build/index.ts
|
|
4087
4642
|
var build_exports = {};
|
|
4088
4643
|
__export(build_exports, {
|
|
@@ -4096,9 +4651,14 @@ function getRolldownOptions(environment, entryPoints, rolldownPlugins) {
|
|
|
4096
4651
|
const config = environment.config;
|
|
4097
4652
|
const envOptions = environment.options;
|
|
4098
4653
|
const isServer = environment.consumer === "server";
|
|
4099
|
-
const outDir =
|
|
4654
|
+
const outDir = import_node_path13.default.resolve(config.root, envOptions.build.outDir);
|
|
4100
4655
|
const assetsDir = envOptions.build.assetsDir;
|
|
4101
|
-
const {
|
|
4656
|
+
const {
|
|
4657
|
+
output: userOutput,
|
|
4658
|
+
transform: userTransform,
|
|
4659
|
+
resolve: userResolve,
|
|
4660
|
+
...restInputOptions
|
|
4661
|
+
} = envOptions.build.rolldownOptions;
|
|
4102
4662
|
const vueDefine = config.framework === "vue" ? {
|
|
4103
4663
|
__VUE_OPTIONS_API__: "true",
|
|
4104
4664
|
__VUE_PROD_DEVTOOLS__: "false",
|
|
@@ -4112,19 +4672,22 @@ function getRolldownOptions(environment, entryPoints, rolldownPlugins) {
|
|
|
4112
4672
|
input: entryPoints,
|
|
4113
4673
|
transform: { ...userTransform, define: mergedDefine },
|
|
4114
4674
|
plugins: rolldownPlugins,
|
|
4675
|
+
// client/server consumer 都必须使用当前环境的 conditions/mainFields;Lynx
|
|
4676
|
+
// BG/MT 通常同为 client consumer,但仍可能声明不同的运行时条件。
|
|
4677
|
+
resolve: {
|
|
4678
|
+
...userResolve ?? {},
|
|
4679
|
+
// Environment API 是条件解析的唯一高层入口,优先于继承来的底层选项。
|
|
4680
|
+
conditionNames: envOptions.resolve.conditions,
|
|
4681
|
+
mainFields: envOptions.resolve.mainFields
|
|
4682
|
+
},
|
|
4115
4683
|
...isServer ? {
|
|
4116
4684
|
platform: restInputOptions.platform ?? "node",
|
|
4117
|
-
resolve: {
|
|
4118
|
-
conditionNames: envOptions.resolve.conditions,
|
|
4119
|
-
mainFields: envOptions.resolve.mainFields,
|
|
4120
|
-
...restInputOptions.resolve
|
|
4121
|
-
},
|
|
4122
4685
|
// server 产物:node 内建恒外部化;bare specifier 默认外部化
|
|
4123
4686
|
//(同 Vite ssr.external 默认 —— 依赖由 node_modules 运行时解析),
|
|
4124
4687
|
// 相对/绝对/虚拟模块照常打包。需要内联依赖时经 rolldownOptions.external 覆盖。
|
|
4125
4688
|
external: restInputOptions.external ?? ((id) => {
|
|
4126
4689
|
if (NODE_BUILTINS2.has(id)) return true;
|
|
4127
|
-
return !id.startsWith(".") && !
|
|
4690
|
+
return !id.startsWith(".") && !import_node_path13.default.isAbsolute(id) && !id.startsWith("\0");
|
|
4128
4691
|
})
|
|
4129
4692
|
} : {}
|
|
4130
4693
|
};
|
|
@@ -4151,27 +4714,122 @@ function getRolldownOptions(environment, entryPoints, rolldownPlugins) {
|
|
|
4151
4714
|
};
|
|
4152
4715
|
return { inputOptions, outputOptions, outDir };
|
|
4153
4716
|
}
|
|
4154
|
-
function toRolldownPlugins(plugins) {
|
|
4717
|
+
function toRolldownPlugins(plugins, environment) {
|
|
4718
|
+
const wrap = (hook) => {
|
|
4719
|
+
if (!hook) return hook;
|
|
4720
|
+
return function(...args) {
|
|
4721
|
+
return hook.apply(attachEnvironment(this, environment), args);
|
|
4722
|
+
};
|
|
4723
|
+
};
|
|
4155
4724
|
return plugins.map((p) => ({
|
|
4156
4725
|
name: p.name,
|
|
4157
|
-
resolveId: p.resolveId,
|
|
4158
|
-
load: p.load,
|
|
4159
|
-
transform: p.transform,
|
|
4160
|
-
buildStart: p.buildStart,
|
|
4161
|
-
buildEnd: p.buildEnd,
|
|
4726
|
+
resolveId: wrap(p.resolveId),
|
|
4727
|
+
load: wrap(p.load),
|
|
4728
|
+
transform: wrap(p.transform),
|
|
4729
|
+
buildStart: wrap(p.buildStart),
|
|
4730
|
+
buildEnd: wrap(p.buildEnd),
|
|
4162
4731
|
// closeBundle 在 bundle.close() 时触发 —— PWA manifest/SW 等终态产物依赖
|
|
4163
|
-
closeBundle: p.closeBundle,
|
|
4164
|
-
renderChunk: p.renderChunk,
|
|
4165
|
-
augmentChunkHash: p.augmentChunkHash,
|
|
4166
|
-
generateBundle: p.generateBundle
|
|
4732
|
+
closeBundle: wrap(p.closeBundle),
|
|
4733
|
+
renderChunk: wrap(p.renderChunk),
|
|
4734
|
+
augmentChunkHash: wrap(p.augmentChunkHash),
|
|
4735
|
+
generateBundle: wrap(p.generateBundle)
|
|
4167
4736
|
}));
|
|
4168
4737
|
}
|
|
4738
|
+
function attachEnvironment(context, environment) {
|
|
4739
|
+
if (context?.environment === environment) return context;
|
|
4740
|
+
try {
|
|
4741
|
+
Object.defineProperty(context, "environment", {
|
|
4742
|
+
configurable: true,
|
|
4743
|
+
enumerable: false,
|
|
4744
|
+
writable: false,
|
|
4745
|
+
value: environment
|
|
4746
|
+
});
|
|
4747
|
+
return context;
|
|
4748
|
+
} catch {
|
|
4749
|
+
return new Proxy(context, {
|
|
4750
|
+
get(target, property) {
|
|
4751
|
+
if (property === "environment") return environment;
|
|
4752
|
+
const value = Reflect.get(target, property, target);
|
|
4753
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
4754
|
+
},
|
|
4755
|
+
set(target, property, value) {
|
|
4756
|
+
return Reflect.set(target, property, value, target);
|
|
4757
|
+
}
|
|
4758
|
+
});
|
|
4759
|
+
}
|
|
4760
|
+
}
|
|
4761
|
+
function finalizeEnvironmentResult(environment, result) {
|
|
4762
|
+
const metadata = environment.getBuildMetadata();
|
|
4763
|
+
const inferredEntries = inferEnvironmentEntries(result.output);
|
|
4764
|
+
const entries = {
|
|
4765
|
+
...inferredEntries,
|
|
4766
|
+
...metadata.entries,
|
|
4767
|
+
...result.entries
|
|
4768
|
+
};
|
|
4769
|
+
const normalizedEntries = Object.fromEntries(
|
|
4770
|
+
Object.entries(entries).map(([name, fileName]) => {
|
|
4771
|
+
const normalized = normalizeEnvironmentFileName(fileName);
|
|
4772
|
+
if (isInvalidEnvironmentFileName(normalized)) {
|
|
4773
|
+
throw new Error(
|
|
4774
|
+
`[nasti] environment "${environment.name}" returned invalid entry "${name}": ${fileName}`
|
|
4775
|
+
);
|
|
4776
|
+
}
|
|
4777
|
+
return [name, normalized];
|
|
4778
|
+
})
|
|
4779
|
+
);
|
|
4780
|
+
return {
|
|
4781
|
+
...metadata,
|
|
4782
|
+
...result,
|
|
4783
|
+
output: result.output,
|
|
4784
|
+
...Object.keys(normalizedEntries).length > 0 ? { entries: normalizedEntries } : {}
|
|
4785
|
+
};
|
|
4786
|
+
}
|
|
4787
|
+
function prepareBuildOutputDirectories(config, buildableNames) {
|
|
4788
|
+
const directories = /* @__PURE__ */ new Set();
|
|
4789
|
+
const protectedPaths = /* @__PURE__ */ new Set();
|
|
4790
|
+
const clientIsBuilt = buildableNames.includes("client");
|
|
4791
|
+
if (!clientIsBuilt && config.build.emptyOutDir) {
|
|
4792
|
+
directories.add(import_node_path13.default.resolve(config.root, config.build.outDir));
|
|
4793
|
+
}
|
|
4794
|
+
for (const name of buildableNames) {
|
|
4795
|
+
const environment = config.environments[name];
|
|
4796
|
+
const outDir = import_node_path13.default.resolve(config.root, environment.build.outDir);
|
|
4797
|
+
if (!environment.build.emptyOutDir) {
|
|
4798
|
+
protectedPaths.add(outDir);
|
|
4799
|
+
continue;
|
|
4800
|
+
}
|
|
4801
|
+
if (!environment.driver) directories.add(outDir);
|
|
4802
|
+
}
|
|
4803
|
+
const containsPath = (parent, child) => {
|
|
4804
|
+
const relative = import_node_path13.default.relative(parent, child);
|
|
4805
|
+
return relative === "" || !relative.startsWith("..") && !import_node_path13.default.isAbsolute(relative);
|
|
4806
|
+
};
|
|
4807
|
+
const roots = [...directories].filter(
|
|
4808
|
+
(directory) => ![...protectedPaths].some((protectedPath) => containsPath(directory, protectedPath))
|
|
4809
|
+
).sort((a, b) => a.length - b.length).filter(
|
|
4810
|
+
(directory, index2, all) => !all.slice(0, index2).some((parent) => containsPath(parent, directory))
|
|
4811
|
+
);
|
|
4812
|
+
for (const directory of roots) {
|
|
4813
|
+
if (import_node_fs10.default.existsSync(directory)) import_node_fs10.default.rmSync(directory, { recursive: true, force: true });
|
|
4814
|
+
}
|
|
4815
|
+
}
|
|
4816
|
+
function assertDriverBuildResult(environment, result) {
|
|
4817
|
+
const output = result != null && typeof result === "object" ? result.output : void 0;
|
|
4818
|
+
const hasValidOutput = Array.isArray(output) && output.every(
|
|
4819
|
+
(artifact) => artifact != null && typeof artifact === "object" && typeof artifact.fileName === "string" && typeof artifact.type === "string"
|
|
4820
|
+
);
|
|
4821
|
+
if (!hasValidOutput) {
|
|
4822
|
+
throw new Error(
|
|
4823
|
+
`[nasti] environment "${environment.name}" driver "${environment.driver?.name}" returned an invalid build result; expected { output: EnvironmentBuildOutput[] }`
|
|
4824
|
+
);
|
|
4825
|
+
}
|
|
4826
|
+
}
|
|
4169
4827
|
function resolveClientEntries(config, html) {
|
|
4170
4828
|
const configuredEntries = config.environments.client?.entry ?? [];
|
|
4171
4829
|
if (configuredEntries.length > 0) return configuredEntries;
|
|
4172
4830
|
const entryPoints = [];
|
|
4173
4831
|
const htmlFile = config.environments.client?.html;
|
|
4174
|
-
const htmlDir = htmlFile ?
|
|
4832
|
+
const htmlDir = htmlFile ? import_node_path13.default.dirname(htmlFile) : config.root;
|
|
4175
4833
|
if (html) {
|
|
4176
4834
|
const scriptMatches = html.matchAll(/<script[^>]+src=["']([^"']+)["'][^>]*>/gi);
|
|
4177
4835
|
for (const match of scriptMatches) {
|
|
@@ -4179,7 +4837,7 @@ function resolveClientEntries(config, html) {
|
|
|
4179
4837
|
if (src && !src.startsWith("http")) {
|
|
4180
4838
|
const cleanSrc = src.split(/[?#]/, 1)[0];
|
|
4181
4839
|
entryPoints.push(
|
|
4182
|
-
cleanSrc.startsWith("/") ?
|
|
4840
|
+
cleanSrc.startsWith("/") ? import_node_path13.default.resolve(config.root, cleanSrc.replace(/^\//, "")) : import_node_path13.default.resolve(htmlDir, cleanSrc)
|
|
4183
4841
|
);
|
|
4184
4842
|
}
|
|
4185
4843
|
}
|
|
@@ -4187,8 +4845,8 @@ function resolveClientEntries(config, html) {
|
|
|
4187
4845
|
if (entryPoints.length === 0) {
|
|
4188
4846
|
const fallbackEntries = ["src/main.ts", "src/main.tsx", "src/main.js", "src/index.ts", "src/index.tsx", "src/index.js"];
|
|
4189
4847
|
for (const entry of fallbackEntries) {
|
|
4190
|
-
const fullPath =
|
|
4191
|
-
if (
|
|
4848
|
+
const fullPath = import_node_path13.default.resolve(config.root, entry);
|
|
4849
|
+
if (import_node_fs10.default.existsSync(fullPath)) {
|
|
4192
4850
|
entryPoints.push(fullPath);
|
|
4193
4851
|
break;
|
|
4194
4852
|
}
|
|
@@ -4216,16 +4874,20 @@ async function build(inlineConfig = {}) {
|
|
|
4216
4874
|
const startTime = performance.now();
|
|
4217
4875
|
logger.info(
|
|
4218
4876
|
import_picocolors6.default.cyan(`
|
|
4219
|
-
nasti v${"2.
|
|
4877
|
+
nasti v${"2.4.0"} `) + import_picocolors6.default.green(`building for ${config.mode}...`)
|
|
4220
4878
|
);
|
|
4221
4879
|
debug5?.(`root: ${config.root}`);
|
|
4222
|
-
const buildableNames = Object.keys(config.environments).filter(
|
|
4223
|
-
|
|
4224
|
-
|
|
4880
|
+
const buildableNames = Object.keys(config.environments).filter((name) => {
|
|
4881
|
+
const environment = config.environments[name];
|
|
4882
|
+
if (!environment.buildEnabled) return false;
|
|
4883
|
+
return name === "client" || environment.entry.length > 0 || !!environment.driver;
|
|
4884
|
+
});
|
|
4225
4885
|
buildableNames.sort((a, b) => a === "client" ? -1 : b === "client" ? 1 : 0);
|
|
4886
|
+
prepareBuildOutputDirectories(config, buildableNames);
|
|
4226
4887
|
const environments = {};
|
|
4227
4888
|
const environmentResults = {};
|
|
4228
4889
|
const initializedEnvironments = [];
|
|
4890
|
+
const buildAppContext = createBuildAppContext(config, environmentResults);
|
|
4229
4891
|
let clientOutput = [];
|
|
4230
4892
|
let buildFailed = false;
|
|
4231
4893
|
try {
|
|
@@ -4241,7 +4903,7 @@ nasti v${"2.3.1"} `) + import_picocolors6.default.green(`building for ${config.m
|
|
|
4241
4903
|
}
|
|
4242
4904
|
const pluginApi = getPluginApi(config);
|
|
4243
4905
|
for (const plugin of config.plugins) {
|
|
4244
|
-
await plugin.afterBuildApp?.(environmentResults, pluginApi);
|
|
4906
|
+
await plugin.afterBuildApp?.(environmentResults, pluginApi, buildAppContext);
|
|
4245
4907
|
}
|
|
4246
4908
|
} catch (error) {
|
|
4247
4909
|
buildFailed = true;
|
|
@@ -4268,22 +4930,31 @@ nasti v${"2.3.1"} `) + import_picocolors6.default.green(`building for ${config.m
|
|
|
4268
4930
|
}
|
|
4269
4931
|
}
|
|
4270
4932
|
const elapsed = ((performance.now() - startTime) / 1e3).toFixed(2);
|
|
4271
|
-
const
|
|
4933
|
+
const allOutput = [...Object.values(environments).flat(), ...buildAppContext.output];
|
|
4934
|
+
const totalSize = allOutput.reduce((sum, chunk) => {
|
|
4272
4935
|
const content = chunk.type === "chunk" ? chunk.code : chunk.source;
|
|
4273
4936
|
if (content == null) return sum;
|
|
4274
4937
|
return sum + (typeof content === "string" ? Buffer.byteLength(content) : content.byteLength);
|
|
4275
4938
|
}, 0);
|
|
4276
|
-
const fileCount =
|
|
4939
|
+
const fileCount = allOutput.length;
|
|
4277
4940
|
const envSuffix = buildableNames.length > 1 ? ` (${buildableNames.join(" + ")})` : "";
|
|
4278
4941
|
logger.info(import_picocolors6.default.green(`\u2713 built in ${elapsed}s`) + import_picocolors6.default.dim(envSuffix));
|
|
4279
4942
|
logger.info(import_picocolors6.default.dim(` ${fileCount} files, ${displaySize(totalSize)} total \u2192 ${config.build.outDir}/`));
|
|
4280
|
-
return {
|
|
4943
|
+
return {
|
|
4944
|
+
output: clientOutput,
|
|
4945
|
+
environments,
|
|
4946
|
+
environmentResults,
|
|
4947
|
+
appOutput: [...buildAppContext.output]
|
|
4948
|
+
};
|
|
4281
4949
|
}
|
|
4282
4950
|
async function buildClientEnvironment(config) {
|
|
4283
4951
|
const logger = config.logger;
|
|
4284
|
-
const outDir =
|
|
4952
|
+
const outDir = import_node_path13.default.resolve(config.root, config.build.outDir);
|
|
4285
4953
|
const cssEngine = createCssEngine();
|
|
4286
|
-
const pluginList = resolvePluginList(config, config.plugins, {
|
|
4954
|
+
const pluginList = resolvePluginList(config, config.plugins, {
|
|
4955
|
+
cssEngine,
|
|
4956
|
+
environmentName: "client"
|
|
4957
|
+
});
|
|
4287
4958
|
const clientEnv = new NastiEnvironment("client", config, {
|
|
4288
4959
|
mode: "build",
|
|
4289
4960
|
plugins: pluginList,
|
|
@@ -4298,13 +4969,11 @@ async function buildClientEnvironment(config) {
|
|
|
4298
4969
|
);
|
|
4299
4970
|
}
|
|
4300
4971
|
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 });
|
|
4972
|
+
assertDriverBuildResult(clientEnv, result);
|
|
4973
|
+
return { environment: clientEnv, result: finalizeEnvironmentResult(clientEnv, result) };
|
|
4305
4974
|
}
|
|
4306
|
-
|
|
4307
|
-
const htmlFile = config.environments.client.html ??
|
|
4975
|
+
import_node_fs10.default.mkdirSync(outDir, { recursive: true });
|
|
4976
|
+
const htmlFile = config.environments.client.html ?? import_node_path13.default.resolve(config.root, "index.html");
|
|
4308
4977
|
const html = await readHtmlFile(config.root, htmlFile);
|
|
4309
4978
|
const entryPoints = resolveClientEntries(config, html);
|
|
4310
4979
|
if (entryPoints.length === 0) {
|
|
@@ -4314,7 +4983,7 @@ async function buildClientEnvironment(config) {
|
|
|
4314
4983
|
const nativeReporter = config.logLevel === "silent" ? null : await tryNativeReporterPlugin(config, logger);
|
|
4315
4984
|
const rolldownPlugins = [
|
|
4316
4985
|
createOxcTransformPlugin(config, clientEnv),
|
|
4317
|
-
...toRolldownPlugins(allPlugins),
|
|
4986
|
+
...toRolldownPlugins(allPlugins, clientEnv),
|
|
4318
4987
|
...nativeReporter ? [nativeReporter] : []
|
|
4319
4988
|
];
|
|
4320
4989
|
const { inputOptions, outputOptions } = getRolldownOptions(
|
|
@@ -4351,13 +5020,16 @@ async function buildClientEnvironment(config) {
|
|
|
4351
5020
|
);
|
|
4352
5021
|
}
|
|
4353
5022
|
}
|
|
4354
|
-
|
|
5023
|
+
import_node_fs10.default.writeFileSync(import_node_path13.default.resolve(outDir, "index.html"), processedHtml);
|
|
4355
5024
|
}
|
|
4356
5025
|
if (!nativeReporter && config.logLevel !== "silent") {
|
|
4357
5026
|
reportBuildOutput(output, config, logger);
|
|
4358
5027
|
}
|
|
4359
5028
|
warnLargeChunks(output, config, logger);
|
|
4360
|
-
return {
|
|
5029
|
+
return {
|
|
5030
|
+
environment: clientEnv,
|
|
5031
|
+
result: finalizeEnvironmentResult(clientEnv, { output })
|
|
5032
|
+
};
|
|
4361
5033
|
} catch (error) {
|
|
4362
5034
|
try {
|
|
4363
5035
|
await clientEnv.close();
|
|
@@ -4373,7 +5045,10 @@ async function buildClientEnvironment(config) {
|
|
|
4373
5045
|
async function buildServerEnvironment(config, name) {
|
|
4374
5046
|
const envOptions = config.environments[name];
|
|
4375
5047
|
const logger = config.logger;
|
|
4376
|
-
const pluginList = resolvePluginList(config, config.plugins, {
|
|
5048
|
+
const pluginList = resolvePluginList(config, config.plugins, {
|
|
5049
|
+
consumer: envOptions.consumer,
|
|
5050
|
+
environmentName: name
|
|
5051
|
+
});
|
|
4377
5052
|
const environment = new NastiEnvironment(name, config, {
|
|
4378
5053
|
mode: "build",
|
|
4379
5054
|
plugins: pluginList,
|
|
@@ -4389,38 +5064,39 @@ async function buildServerEnvironment(config, name) {
|
|
|
4389
5064
|
}
|
|
4390
5065
|
try {
|
|
4391
5066
|
const result = await environment.driver.build(environment.getDriverContext());
|
|
4392
|
-
|
|
5067
|
+
assertDriverBuildResult(environment, result);
|
|
5068
|
+
return { environment, result: finalizeEnvironmentResult(environment, result) };
|
|
4393
5069
|
} catch (error) {
|
|
4394
5070
|
await environment.close();
|
|
4395
5071
|
throw error;
|
|
4396
5072
|
}
|
|
4397
5073
|
}
|
|
4398
5074
|
for (const entry of envOptions.entry) {
|
|
4399
|
-
if (!
|
|
5075
|
+
if (!import_node_fs10.default.existsSync(entry)) {
|
|
4400
5076
|
await environment.close();
|
|
4401
5077
|
throw new Error(`[nasti] environment "${name}" entry not found: ${entry}`);
|
|
4402
5078
|
}
|
|
4403
5079
|
}
|
|
4404
5080
|
const rolldownPlugins = [
|
|
4405
5081
|
createOxcTransformPlugin(config, environment),
|
|
4406
|
-
...toRolldownPlugins(environment.plugins)
|
|
5082
|
+
...toRolldownPlugins(environment.plugins, environment)
|
|
4407
5083
|
];
|
|
4408
5084
|
const { inputOptions, outputOptions, outDir } = getRolldownOptions(
|
|
4409
5085
|
environment,
|
|
4410
5086
|
envOptions.entry,
|
|
4411
5087
|
rolldownPlugins
|
|
4412
5088
|
);
|
|
4413
|
-
|
|
4414
|
-
import_node_fs9.default.rmSync(outDir, { recursive: true, force: true });
|
|
4415
|
-
}
|
|
4416
|
-
import_node_fs9.default.mkdirSync(outDir, { recursive: true });
|
|
5089
|
+
import_node_fs10.default.mkdirSync(outDir, { recursive: true });
|
|
4417
5090
|
const bundle2 = await (0, import_rolldown.rolldown)(inputOptions);
|
|
4418
5091
|
const { output } = await bundle2.write(outputOptions);
|
|
4419
5092
|
await bundle2.close();
|
|
4420
5093
|
logger.info(
|
|
4421
|
-
import_picocolors6.default.dim(` [${name}] `) + output.map((o) =>
|
|
5094
|
+
import_picocolors6.default.dim(` [${name}] `) + output.map((o) => import_node_path13.default.join(envOptions.build.outDir, o.fileName)).join(import_picocolors6.default.dim(", "))
|
|
4422
5095
|
);
|
|
4423
|
-
return {
|
|
5096
|
+
return {
|
|
5097
|
+
environment,
|
|
5098
|
+
result: finalizeEnvironmentResult(environment, { output })
|
|
5099
|
+
};
|
|
4424
5100
|
}
|
|
4425
5101
|
function injectCssLinks(html, cssEngine, config) {
|
|
4426
5102
|
const cssLinkTags = [];
|
|
@@ -4447,9 +5123,9 @@ function escapeRegExp(string) {
|
|
|
4447
5123
|
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4448
5124
|
}
|
|
4449
5125
|
function replaceEntryScript(html, facadeModuleId, fileName, config, htmlFile, urlPrefix) {
|
|
4450
|
-
const rootRelative =
|
|
4451
|
-
const resolvedHtmlFile =
|
|
4452
|
-
const htmlRelative =
|
|
5126
|
+
const rootRelative = import_node_path13.default.relative(config.root, facadeModuleId).split(import_node_path13.default.sep).join("/");
|
|
5127
|
+
const resolvedHtmlFile = import_node_path13.default.resolve(config.root, htmlFile);
|
|
5128
|
+
const htmlRelative = import_node_path13.default.relative(import_node_path13.default.dirname(resolvedHtmlFile), facadeModuleId).split(import_node_path13.default.sep).join("/");
|
|
4453
5129
|
const candidates = /* @__PURE__ */ new Set([
|
|
4454
5130
|
rootRelative,
|
|
4455
5131
|
`/${rootRelative}`,
|
|
@@ -4465,12 +5141,12 @@ function replaceEntryScript(html, facadeModuleId, fileName, config, htmlFile, ur
|
|
|
4465
5141
|
}
|
|
4466
5142
|
return processed;
|
|
4467
5143
|
}
|
|
4468
|
-
var
|
|
5144
|
+
var import_node_path13, import_node_fs10, import_node_module5, import_rolldown, import_picocolors6, debug5, NODE_BUILTINS2;
|
|
4469
5145
|
var init_build = __esm({
|
|
4470
5146
|
"src/build/index.ts"() {
|
|
4471
5147
|
"use strict";
|
|
4472
|
-
|
|
4473
|
-
|
|
5148
|
+
import_node_path13 = __toESM(require("path"), 1);
|
|
5149
|
+
import_node_fs10 = __toESM(require("fs"), 1);
|
|
4474
5150
|
import_node_module5 = require("module");
|
|
4475
5151
|
import_rolldown = require("rolldown");
|
|
4476
5152
|
init_config();
|
|
@@ -4483,6 +5159,7 @@ var init_build = __esm({
|
|
|
4483
5159
|
init_reporter();
|
|
4484
5160
|
init_debug();
|
|
4485
5161
|
init_plugin_api();
|
|
5162
|
+
init_build_app_context();
|
|
4486
5163
|
import_picocolors6 = __toESM(require("picocolors"), 1);
|
|
4487
5164
|
debug5 = createDebugger("nasti:build");
|
|
4488
5165
|
NODE_BUILTINS2 = /* @__PURE__ */ new Set([...import_node_module5.builtinModules, ...import_node_module5.builtinModules.map((m) => `node:${m}`)]);
|
|
@@ -4526,7 +5203,7 @@ async function createBundledDevServer(opts) {
|
|
|
4526
5203
|
createReactRefreshRuntimePlugin(entryPoints),
|
|
4527
5204
|
createBundledOxcRefreshPlugin()
|
|
4528
5205
|
] : [],
|
|
4529
|
-
...stripCatchAllLoad(toRolldownPlugins(clientEnv.plugins)),
|
|
5206
|
+
...stripCatchAllLoad(toRolldownPlugins(clientEnv.plugins, clientEnv)),
|
|
4530
5207
|
...useReactRefresh ? [
|
|
4531
5208
|
refreshWrapperFn({
|
|
4532
5209
|
cwd: config.root,
|
|
@@ -4575,7 +5252,7 @@ async function createBundledDevServer(opts) {
|
|
|
4575
5252
|
}
|
|
4576
5253
|
const url = `/${patchPath}`;
|
|
4577
5254
|
logger.info(
|
|
4578
|
-
import_picocolors7.default.green("hmr update ") + import_picocolors7.default.dim(changedFiles.map((f) =>
|
|
5255
|
+
import_picocolors7.default.green("hmr update ") + import_picocolors7.default.dim(changedFiles.map((f) => import_node_path14.default.relative(config.root, f)).join(", ")),
|
|
4579
5256
|
{ timestamp: true }
|
|
4580
5257
|
);
|
|
4581
5258
|
sendTo(clientId, { type: "hmr:update", path: url, url });
|
|
@@ -4711,7 +5388,7 @@ async function createBundledDevServer(opts) {
|
|
|
4711
5388
|
return;
|
|
4712
5389
|
}
|
|
4713
5390
|
res.setHeader("ETag", hit.etag);
|
|
4714
|
-
res.setHeader("Content-Type", MIME_TYPES[
|
|
5391
|
+
res.setHeader("Content-Type", MIME_TYPES[import_node_path14.default.extname(fileName)] ?? "application/octet-stream");
|
|
4715
5392
|
res.setHeader("Cache-Control", "no-cache");
|
|
4716
5393
|
res.end(hit.content);
|
|
4717
5394
|
return;
|
|
@@ -4747,7 +5424,7 @@ function stripCatchAllLoad(plugins) {
|
|
|
4747
5424
|
);
|
|
4748
5425
|
}
|
|
4749
5426
|
function createReactRefreshRuntimePlugin(entryPoints) {
|
|
4750
|
-
const entryIds = new Set(entryPoints.map((p) =>
|
|
5427
|
+
const entryIds = new Set(entryPoints.map((p) => import_node_path14.default.resolve(p)));
|
|
4751
5428
|
return {
|
|
4752
5429
|
name: "nasti:bundled-react-refresh",
|
|
4753
5430
|
resolveId(source) {
|
|
@@ -4765,7 +5442,7 @@ function createReactRefreshRuntimePlugin(entryPoints) {
|
|
|
4765
5442
|
return null;
|
|
4766
5443
|
},
|
|
4767
5444
|
transform(code, id) {
|
|
4768
|
-
if (!entryIds.has(
|
|
5445
|
+
if (!entryIds.has(import_node_path14.default.resolve(id.split("?")[0]))) return null;
|
|
4769
5446
|
return { code: `import ${JSON.stringify(PREAMBLE_SPEC)};
|
|
4770
5447
|
${code}`, map: null };
|
|
4771
5448
|
}
|
|
@@ -4812,11 +5489,11 @@ async function renderBundledIndexHtml(html, config, entryFileNames) {
|
|
|
4812
5489
|
}
|
|
4813
5490
|
return processed;
|
|
4814
5491
|
}
|
|
4815
|
-
var
|
|
5492
|
+
var import_node_path14, import_node_crypto3, import_ws2, import_picocolors7, debug6, MIME_TYPES, MemoryFiles, PREAMBLE_SPEC, RESOLVED_PREAMBLE_ID, REFRESH_RUNTIME_URL, BUNDLED_PREAMBLE_CODE, WRAPPER_RUNTIME_HELPERS;
|
|
4816
5493
|
var init_dev_engine = __esm({
|
|
4817
5494
|
"src/server/bundled/dev-engine.ts"() {
|
|
4818
5495
|
"use strict";
|
|
4819
|
-
|
|
5496
|
+
import_node_path14 = __toESM(require("path"), 1);
|
|
4820
5497
|
import_node_crypto3 = __toESM(require("crypto"), 1);
|
|
4821
5498
|
import_ws2 = require("ws");
|
|
4822
5499
|
import_picocolors7 = __toESM(require("picocolors"), 1);
|
|
@@ -4943,7 +5620,9 @@ async function createServer(inlineConfig = {}) {
|
|
|
4943
5620
|
const startTime = performance.now();
|
|
4944
5621
|
const config = await resolveConfig(inlineConfig, "serve");
|
|
4945
5622
|
const logger = config.logger;
|
|
4946
|
-
const allPlugins = resolvePluginList(config, config.plugins
|
|
5623
|
+
const allPlugins = resolvePluginList(config, config.plugins, {
|
|
5624
|
+
environmentName: "client"
|
|
5625
|
+
});
|
|
4947
5626
|
const configWithPlugins = { ...config, plugins: allPlugins };
|
|
4948
5627
|
const app = (0, import_connect.default)();
|
|
4949
5628
|
const httpServer = import_node_http.default.createServer(app);
|
|
@@ -4960,7 +5639,10 @@ async function createServer(inlineConfig = {}) {
|
|
|
4960
5639
|
for (const name of Object.keys(config.environments)) {
|
|
4961
5640
|
if (name === "client") continue;
|
|
4962
5641
|
const consumer = config.environments[name].consumer;
|
|
4963
|
-
const envPlugins = resolvePluginList(config, config.plugins, {
|
|
5642
|
+
const envPlugins = resolvePluginList(config, config.plugins, {
|
|
5643
|
+
consumer,
|
|
5644
|
+
environmentName: name
|
|
5645
|
+
});
|
|
4964
5646
|
environments[name] = new NastiEnvironment(name, config, {
|
|
4965
5647
|
mode: "dev",
|
|
4966
5648
|
plugins: envPlugins,
|
|
@@ -4995,14 +5677,14 @@ async function createServer(inlineConfig = {}) {
|
|
|
4995
5677
|
app.use(bundledServer.middleware);
|
|
4996
5678
|
}
|
|
4997
5679
|
const ignoredSegments = /* @__PURE__ */ new Set(["node_modules", ".git", ".nasti"]);
|
|
4998
|
-
const outDirAbs =
|
|
5680
|
+
const outDirAbs = import_node_path15.default.resolve(config.root, config.build.outDir);
|
|
4999
5681
|
const watcher = (0, import_chokidar.watch)(config.root, {
|
|
5000
5682
|
ignored: (filePath) => {
|
|
5001
5683
|
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(
|
|
5684
|
+
if (filePath === outDirAbs || filePath.startsWith(outDirAbs + import_node_path15.default.sep)) return true;
|
|
5685
|
+
const rel = import_node_path15.default.relative(config.root, filePath);
|
|
5686
|
+
if (!rel || rel.startsWith("..") || import_node_path15.default.isAbsolute(rel)) return false;
|
|
5687
|
+
for (const seg of rel.split(import_node_path15.default.sep)) {
|
|
5006
5688
|
if (ignoredSegments.has(seg)) return true;
|
|
5007
5689
|
}
|
|
5008
5690
|
return false;
|
|
@@ -5103,7 +5785,7 @@ async function createServer(inlineConfig = {}) {
|
|
|
5103
5785
|
const readyIn = Math.ceil(performance.now() - startTime);
|
|
5104
5786
|
logger.info(
|
|
5105
5787
|
`
|
|
5106
|
-
${import_picocolors8.default.cyan(import_picocolors8.default.bold("NASTI"))} ${import_picocolors8.default.cyan(`v${"2.
|
|
5788
|
+
${import_picocolors8.default.cyan(import_picocolors8.default.bold("NASTI"))} ${import_picocolors8.default.cyan(`v${"2.4.0"}`)} ${import_picocolors8.default.dim("ready in")} ${import_picocolors8.default.bold(readyIn)} ${import_picocolors8.default.dim("ms")}
|
|
5107
5789
|
`
|
|
5108
5790
|
);
|
|
5109
5791
|
printServerUrls(
|
|
@@ -5131,7 +5813,12 @@ async function createServer(inlineConfig = {}) {
|
|
|
5131
5813
|
},
|
|
5132
5814
|
async transformRequest(url) {
|
|
5133
5815
|
const { transformRequest: transformRequest2 } = await Promise.resolve().then(() => (init_middleware(), middleware_exports));
|
|
5134
|
-
return transformRequest2(url, {
|
|
5816
|
+
return transformRequest2(url, {
|
|
5817
|
+
config: configWithPlugins,
|
|
5818
|
+
pluginContainer,
|
|
5819
|
+
moduleGraph,
|
|
5820
|
+
onPrune: (paths) => ws.send({ type: "prune", paths })
|
|
5821
|
+
});
|
|
5135
5822
|
},
|
|
5136
5823
|
async ssrLoadModule(url) {
|
|
5137
5824
|
const runner = await getSsrRunner();
|
|
@@ -5191,9 +5878,10 @@ async function createServer(inlineConfig = {}) {
|
|
|
5191
5878
|
app.use(transformMiddleware({
|
|
5192
5879
|
config: configWithPlugins,
|
|
5193
5880
|
pluginContainer,
|
|
5194
|
-
moduleGraph
|
|
5881
|
+
moduleGraph,
|
|
5882
|
+
onPrune: (paths) => ws.send({ type: "prune", paths })
|
|
5195
5883
|
}));
|
|
5196
|
-
const publicDir =
|
|
5884
|
+
const publicDir = import_node_path15.default.resolve(config.root, "public");
|
|
5197
5885
|
app.use((0, import_sirv.default)(publicDir, { dev: true, etag: true }));
|
|
5198
5886
|
app.use((0, import_sirv.default)(config.root, { dev: true, etag: true }));
|
|
5199
5887
|
const postMiddlewares = [];
|
|
@@ -5219,12 +5907,12 @@ function getNetworkAddress() {
|
|
|
5219
5907
|
}
|
|
5220
5908
|
return "localhost";
|
|
5221
5909
|
}
|
|
5222
|
-
var import_node_http,
|
|
5910
|
+
var import_node_http, import_node_path15, import_node_os, import_connect, import_sirv, import_chokidar, import_picocolors8;
|
|
5223
5911
|
var init_server = __esm({
|
|
5224
5912
|
"src/server/index.ts"() {
|
|
5225
5913
|
"use strict";
|
|
5226
5914
|
import_node_http = __toESM(require("http"), 1);
|
|
5227
|
-
|
|
5915
|
+
import_node_path15 = __toESM(require("path"), 1);
|
|
5228
5916
|
import_node_os = __toESM(require("os"), 1);
|
|
5229
5917
|
import_connect = __toESM(require("connect"), 1);
|
|
5230
5918
|
import_sirv = __toESM(require("sirv"), 1);
|
|
@@ -5293,16 +5981,16 @@ async function buildElectron(inlineConfig = {}) {
|
|
|
5293
5981
|
const config = await resolveConfig({ ...inlineConfig, target: "electron" }, "build");
|
|
5294
5982
|
const startTime = performance.now();
|
|
5295
5983
|
assertElectronVersion(config);
|
|
5296
|
-
console.log(import_picocolors9.default.cyan("\n\u26A1 nasti build (electron)") + import_picocolors9.default.dim(` v${"2.
|
|
5984
|
+
console.log(import_picocolors9.default.cyan("\n\u26A1 nasti build (electron)") + import_picocolors9.default.dim(` v${"2.4.0"}`));
|
|
5297
5985
|
console.log(import_picocolors9.default.dim(` root: ${config.root}`));
|
|
5298
5986
|
console.log(import_picocolors9.default.dim(` mode: ${config.mode}`));
|
|
5299
5987
|
console.log(import_picocolors9.default.dim(` target: electron (\u2265 ${config.electron.minVersion})`));
|
|
5300
|
-
const outDir =
|
|
5301
|
-
if (config.build.emptyOutDir &&
|
|
5302
|
-
|
|
5988
|
+
const outDir = import_node_path16.default.resolve(config.root, config.build.outDir);
|
|
5989
|
+
if (config.build.emptyOutDir && import_node_fs11.default.existsSync(outDir)) {
|
|
5990
|
+
import_node_fs11.default.rmSync(outDir, { recursive: true, force: true });
|
|
5303
5991
|
}
|
|
5304
|
-
|
|
5305
|
-
const rendererOutDir =
|
|
5992
|
+
import_node_fs11.default.mkdirSync(outDir, { recursive: true });
|
|
5993
|
+
const rendererOutDir = import_node_path16.default.join(outDir, "renderer");
|
|
5306
5994
|
const { build: build2 } = await Promise.resolve().then(() => (init_build(), build_exports));
|
|
5307
5995
|
await build2(createElectronRendererConfig(config, inlineConfig, {
|
|
5308
5996
|
build: {
|
|
@@ -5311,8 +5999,8 @@ async function buildElectron(inlineConfig = {}) {
|
|
|
5311
5999
|
emptyOutDir: false
|
|
5312
6000
|
}
|
|
5313
6001
|
}));
|
|
5314
|
-
const mainEntry =
|
|
5315
|
-
if (!
|
|
6002
|
+
const mainEntry = import_node_path16.default.resolve(config.root, config.electron.main);
|
|
6003
|
+
if (!import_node_fs11.default.existsSync(mainEntry)) {
|
|
5316
6004
|
throw new Error(
|
|
5317
6005
|
`Electron main entry not found: ${config.electron.main}
|
|
5318
6006
|
\u5728 nasti.config.ts \u7684 electron.main \u6307\u5B9A\u4E3B\u8FDB\u7A0B\u5165\u53E3\u6587\u4EF6\u3002`
|
|
@@ -5326,11 +6014,11 @@ async function buildElectron(inlineConfig = {}) {
|
|
|
5326
6014
|
const preloadEntries = normalizePreload(config.electron.preload, config.root);
|
|
5327
6015
|
const preloadFiles = [];
|
|
5328
6016
|
for (const entry of preloadEntries) {
|
|
5329
|
-
if (!
|
|
6017
|
+
if (!import_node_fs11.default.existsSync(entry)) {
|
|
5330
6018
|
console.warn(import_picocolors9.default.yellow(` \u26A0 preload entry not found, skipped: ${entry}`));
|
|
5331
6019
|
continue;
|
|
5332
6020
|
}
|
|
5333
|
-
const base =
|
|
6021
|
+
const base = import_node_path16.default.basename(entry).replace(/\.[^.]+$/, "");
|
|
5334
6022
|
const out = outFileName(outDir, base, config.electron.preloadFormat);
|
|
5335
6023
|
await bundleNode(config, entry, {
|
|
5336
6024
|
outFile: out,
|
|
@@ -5342,10 +6030,10 @@ async function buildElectron(inlineConfig = {}) {
|
|
|
5342
6030
|
const elapsed = ((performance.now() - startTime) / 1e3).toFixed(2);
|
|
5343
6031
|
console.log(import_picocolors9.default.green(`
|
|
5344
6032
|
\u2713 Electron build complete in ${elapsed}s`));
|
|
5345
|
-
console.log(import_picocolors9.default.dim(` renderer: ${
|
|
5346
|
-
console.log(import_picocolors9.default.dim(` main: ${
|
|
6033
|
+
console.log(import_picocolors9.default.dim(` renderer: ${import_node_path16.default.relative(config.root, rendererOutDir)}/`));
|
|
6034
|
+
console.log(import_picocolors9.default.dim(` main: ${import_node_path16.default.relative(config.root, mainFile)}`));
|
|
5347
6035
|
for (const pf of preloadFiles) {
|
|
5348
|
-
console.log(import_picocolors9.default.dim(` preload: ${
|
|
6036
|
+
console.log(import_picocolors9.default.dim(` preload: ${import_node_path16.default.relative(config.root, pf)}`));
|
|
5349
6037
|
}
|
|
5350
6038
|
console.log();
|
|
5351
6039
|
return { rendererOutDir, mainFile, preloadFiles };
|
|
@@ -5383,7 +6071,7 @@ async function bundleNode(config, entry, opts) {
|
|
|
5383
6071
|
},
|
|
5384
6072
|
plugins: [oxcTransformPlugin, electronPlugin(config), resolvePlugin(config)]
|
|
5385
6073
|
});
|
|
5386
|
-
|
|
6074
|
+
import_node_fs11.default.mkdirSync(import_node_path16.default.dirname(opts.outFile), { recursive: true });
|
|
5387
6075
|
await bundle2.write({
|
|
5388
6076
|
sourcemap: !!config.build.sourcemap,
|
|
5389
6077
|
minify: !!config.build.minify,
|
|
@@ -5394,7 +6082,7 @@ async function bundleNode(config, entry, opts) {
|
|
|
5394
6082
|
codeSplitting: false
|
|
5395
6083
|
});
|
|
5396
6084
|
await bundle2.close();
|
|
5397
|
-
console.log(import_picocolors9.default.dim(` \u2713 ${opts.label} \u2192 ${
|
|
6085
|
+
console.log(import_picocolors9.default.dim(` \u2713 ${opts.label} \u2192 ${import_node_path16.default.relative(config.root, opts.outFile)}`));
|
|
5398
6086
|
return opts.outFile;
|
|
5399
6087
|
}
|
|
5400
6088
|
function createElectronRendererConfig(config, inlineConfig = {}, overrides = {}) {
|
|
@@ -5418,11 +6106,11 @@ function createElectronRendererConfig(config, inlineConfig = {}, overrides = {})
|
|
|
5418
6106
|
}
|
|
5419
6107
|
function outFileName(outDir, base, format) {
|
|
5420
6108
|
const ext = format === "cjs" ? ".cjs" : ".mjs";
|
|
5421
|
-
return
|
|
6109
|
+
return import_node_path16.default.join(outDir, base + ext);
|
|
5422
6110
|
}
|
|
5423
6111
|
function normalizePreload(preload, root) {
|
|
5424
6112
|
const list = Array.isArray(preload) ? preload : preload ? [preload] : [];
|
|
5425
|
-
return list.map((p) =>
|
|
6113
|
+
return list.map((p) => import_node_path16.default.resolve(root, p));
|
|
5426
6114
|
}
|
|
5427
6115
|
function assertElectronVersion(config) {
|
|
5428
6116
|
const min = config.electron.minVersion;
|
|
@@ -5437,21 +6125,21 @@ function assertElectronVersion(config) {
|
|
|
5437
6125
|
}
|
|
5438
6126
|
function detectInstalledElectron(root) {
|
|
5439
6127
|
try {
|
|
5440
|
-
const pkgPath =
|
|
5441
|
-
if (!
|
|
5442
|
-
const pkg = JSON.parse(
|
|
6128
|
+
const pkgPath = import_node_path16.default.resolve(root, "node_modules/electron/package.json");
|
|
6129
|
+
if (!import_node_fs11.default.existsSync(pkgPath)) return null;
|
|
6130
|
+
const pkg = JSON.parse(import_node_fs11.default.readFileSync(pkgPath, "utf-8"));
|
|
5443
6131
|
const major = parseInt(String(pkg.version).split(".")[0], 10);
|
|
5444
6132
|
return Number.isFinite(major) ? major : null;
|
|
5445
6133
|
} catch {
|
|
5446
6134
|
return null;
|
|
5447
6135
|
}
|
|
5448
6136
|
}
|
|
5449
|
-
var
|
|
6137
|
+
var import_node_path16, import_node_fs11, import_rolldown2, import_picocolors9;
|
|
5450
6138
|
var init_electron2 = __esm({
|
|
5451
6139
|
"src/build/electron.ts"() {
|
|
5452
6140
|
"use strict";
|
|
5453
|
-
|
|
5454
|
-
|
|
6141
|
+
import_node_path16 = __toESM(require("path"), 1);
|
|
6142
|
+
import_node_fs11 = __toESM(require("fs"), 1);
|
|
5455
6143
|
import_rolldown2 = require("rolldown");
|
|
5456
6144
|
import_picocolors9 = __toESM(require("picocolors"), 1);
|
|
5457
6145
|
init_config();
|
|
@@ -5472,7 +6160,7 @@ async function startElectronDev(inlineConfig = {}) {
|
|
|
5472
6160
|
const { noSpawn, ...rest } = inlineConfig;
|
|
5473
6161
|
const config = await resolveConfig({ ...rest, target: "electron" }, "serve");
|
|
5474
6162
|
warnElectronVersion(config);
|
|
5475
|
-
console.log(import_picocolors10.default.cyan("\n\u26A1 nasti electron dev") + import_picocolors10.default.dim(` v${"2.
|
|
6163
|
+
console.log(import_picocolors10.default.cyan("\n\u26A1 nasti electron dev") + import_picocolors10.default.dim(` v${"2.4.0"}`));
|
|
5476
6164
|
const { createServer: createServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
|
|
5477
6165
|
const server = await createServer2({
|
|
5478
6166
|
...rest,
|
|
@@ -5482,11 +6170,11 @@ async function startElectronDev(inlineConfig = {}) {
|
|
|
5482
6170
|
await server.listen();
|
|
5483
6171
|
const devUrl = `http://localhost:${server.config.server.port}` + electronRendererDevPath(config.electron.renderer);
|
|
5484
6172
|
console.log(import_picocolors10.default.dim(` renderer: ${devUrl}`));
|
|
5485
|
-
const stageDir =
|
|
5486
|
-
|
|
5487
|
-
const mainEntry =
|
|
6173
|
+
const stageDir = import_node_path17.default.resolve(config.root, ".nasti");
|
|
6174
|
+
import_node_fs12.default.mkdirSync(stageDir, { recursive: true });
|
|
6175
|
+
const mainEntry = import_node_path17.default.resolve(config.root, config.electron.main);
|
|
5488
6176
|
const preloadEntries = normalizePreload(config.electron.preload, config.root);
|
|
5489
|
-
const builtMainFile =
|
|
6177
|
+
const builtMainFile = import_node_path17.default.join(stageDir, "main" + extFor(config.electron.mainFormat));
|
|
5490
6178
|
const builtPreloadFiles = [];
|
|
5491
6179
|
const compileAll = async () => {
|
|
5492
6180
|
await compileNode(config, mainEntry, {
|
|
@@ -5496,9 +6184,9 @@ async function startElectronDev(inlineConfig = {}) {
|
|
|
5496
6184
|
});
|
|
5497
6185
|
builtPreloadFiles.length = 0;
|
|
5498
6186
|
for (const entry of preloadEntries) {
|
|
5499
|
-
if (!
|
|
5500
|
-
const base =
|
|
5501
|
-
const out =
|
|
6187
|
+
if (!import_node_fs12.default.existsSync(entry)) continue;
|
|
6188
|
+
const base = import_node_path17.default.basename(entry).replace(/\.[^.]+$/, "");
|
|
6189
|
+
const out = import_node_path17.default.join(stageDir, base + extFor(config.electron.preloadFormat));
|
|
5502
6190
|
await compileNode(config, entry, {
|
|
5503
6191
|
outFile: out,
|
|
5504
6192
|
format: config.electron.preloadFormat,
|
|
@@ -5537,7 +6225,7 @@ async function startElectronDev(inlineConfig = {}) {
|
|
|
5537
6225
|
};
|
|
5538
6226
|
spawnElectron();
|
|
5539
6227
|
if (config.electron.autoRestart) {
|
|
5540
|
-
const watchTargets = [mainEntry, ...preloadEntries].filter(
|
|
6228
|
+
const watchTargets = [mainEntry, ...preloadEntries].filter(import_node_fs12.default.existsSync);
|
|
5541
6229
|
const watcher = import_chokidar2.default.watch(watchTargets, { ignoreInitial: true });
|
|
5542
6230
|
let restarting = null;
|
|
5543
6231
|
let pending = false;
|
|
@@ -5617,7 +6305,7 @@ async function compileNode(config, entry, opts) {
|
|
|
5617
6305
|
platform: "node",
|
|
5618
6306
|
plugins: [oxcTransformPlugin, electronPlugin(config), resolvePlugin(config)]
|
|
5619
6307
|
});
|
|
5620
|
-
|
|
6308
|
+
import_node_fs12.default.mkdirSync(import_node_path17.default.dirname(opts.outFile), { recursive: true });
|
|
5621
6309
|
await bundle2.write({
|
|
5622
6310
|
file: opts.outFile,
|
|
5623
6311
|
format: opts.format === "cjs" ? "cjs" : "esm",
|
|
@@ -5630,18 +6318,18 @@ async function compileNode(config, entry, opts) {
|
|
|
5630
6318
|
await bundle2.close();
|
|
5631
6319
|
}
|
|
5632
6320
|
function electronRendererDevPath(renderer) {
|
|
5633
|
-
const normalized = renderer.split(
|
|
6321
|
+
const normalized = renderer.split(import_node_path17.default.sep).join("/").replace(/^\.?\//, "");
|
|
5634
6322
|
return normalized === "index.html" ? "/" : `/${normalized}`;
|
|
5635
6323
|
}
|
|
5636
6324
|
function resolveElectronBinary(config) {
|
|
5637
|
-
if (config.electron.electronPath &&
|
|
6325
|
+
if (config.electron.electronPath && import_node_fs12.default.existsSync(config.electron.electronPath)) {
|
|
5638
6326
|
return config.electron.electronPath;
|
|
5639
6327
|
}
|
|
5640
6328
|
try {
|
|
5641
|
-
const require2 = (0, import_node_module7.createRequire)(
|
|
6329
|
+
const require2 = (0, import_node_module7.createRequire)(import_node_path17.default.resolve(config.root, "package.json"));
|
|
5642
6330
|
const pathFile = require2.resolve("electron");
|
|
5643
6331
|
const electronModule = require2(pathFile);
|
|
5644
|
-
if (typeof electronModule === "string" &&
|
|
6332
|
+
if (typeof electronModule === "string" && import_node_fs12.default.existsSync(electronModule)) {
|
|
5645
6333
|
return electronModule;
|
|
5646
6334
|
}
|
|
5647
6335
|
} catch {
|
|
@@ -5666,12 +6354,12 @@ function warnElectronVersion(config) {
|
|
|
5666
6354
|
);
|
|
5667
6355
|
}
|
|
5668
6356
|
}
|
|
5669
|
-
var
|
|
6357
|
+
var import_node_path17, import_node_fs12, import_node_module7, import_node_child_process, import_chokidar2, import_picocolors10, import_rolldown3;
|
|
5670
6358
|
var init_electron_dev = __esm({
|
|
5671
6359
|
"src/server/electron-dev.ts"() {
|
|
5672
6360
|
"use strict";
|
|
5673
|
-
|
|
5674
|
-
|
|
6361
|
+
import_node_path17 = __toESM(require("path"), 1);
|
|
6362
|
+
import_node_fs12 = __toESM(require("fs"), 1);
|
|
5675
6363
|
import_node_module7 = require("module");
|
|
5676
6364
|
import_node_child_process = require("child_process");
|
|
5677
6365
|
import_chokidar2 = __toESM(require("chokidar"), 1);
|
|
@@ -5824,20 +6512,20 @@ cli.command("preview [root]", "Preview production build").option("--port <port>"
|
|
|
5824
6512
|
const logger = createCliLogger(options);
|
|
5825
6513
|
try {
|
|
5826
6514
|
const http2 = await import("http");
|
|
5827
|
-
const
|
|
6515
|
+
const path18 = await import("path");
|
|
5828
6516
|
const os2 = await import("os");
|
|
5829
6517
|
const sirv2 = (await import("sirv")).default;
|
|
5830
6518
|
const connect2 = (await import("connect")).default;
|
|
5831
6519
|
const { printServerUrls: printServerUrls2 } = await Promise.resolve().then(() => (init_logger(), logger_exports));
|
|
5832
|
-
const resolvedRoot =
|
|
5833
|
-
const outDir =
|
|
6520
|
+
const resolvedRoot = path18.resolve(root ?? ".");
|
|
6521
|
+
const outDir = path18.resolve(resolvedRoot, options.outDir);
|
|
5834
6522
|
const app = connect2();
|
|
5835
6523
|
app.use(sirv2(outDir, { single: true, etag: true, gzip: true, brotli: true }));
|
|
5836
6524
|
const port = options.port;
|
|
5837
6525
|
const host = options.host === true ? "0.0.0.0" : options.host ?? "localhost";
|
|
5838
6526
|
http2.createServer(app).listen(port, host, () => {
|
|
5839
6527
|
logger.info(`
|
|
5840
|
-
${import_picocolors11.default.cyan(import_picocolors11.default.bold("NASTI"))} ${import_picocolors11.default.cyan(`v${"2.
|
|
6528
|
+
${import_picocolors11.default.cyan(import_picocolors11.default.bold("NASTI"))} ${import_picocolors11.default.cyan(`v${"2.4.0"}`)} ${import_picocolors11.default.dim("preview")}
|
|
5841
6529
|
`);
|
|
5842
6530
|
printServerUrls2(
|
|
5843
6531
|
{
|
|
@@ -5854,6 +6542,6 @@ cli.command("preview [root]", "Preview production build").option("--port <port>"
|
|
|
5854
6542
|
}
|
|
5855
6543
|
});
|
|
5856
6544
|
cli.help();
|
|
5857
|
-
cli.version("2.
|
|
6545
|
+
cli.version("2.4.0");
|
|
5858
6546
|
cli.parse();
|
|
5859
6547
|
//# sourceMappingURL=cli.cjs.map
|