@nasti-toolchain/nasti 1.7.1 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +3167 -702
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +3191 -699
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +3091 -638
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +346 -6
- package/dist/index.d.ts +346 -6
- package/dist/index.js +3158 -689
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
package/dist/cli.js
CHANGED
|
@@ -1,15 +1,168 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
1
2
|
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
2
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
8
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
9
|
+
}) : x)(function(x) {
|
|
10
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
11
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
12
|
+
});
|
|
13
|
+
var __glob = (map) => (path17) => {
|
|
14
|
+
var fn = map[path17];
|
|
15
|
+
if (fn) return fn();
|
|
16
|
+
throw new Error("Module not found in bundle: " + path17);
|
|
17
|
+
};
|
|
3
18
|
var __esm = (fn, res) => function __init() {
|
|
4
19
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
5
20
|
};
|
|
21
|
+
var __commonJS = (cb, mod) => function __require3() {
|
|
22
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
23
|
+
};
|
|
6
24
|
var __export = (target, all) => {
|
|
7
25
|
for (var name in all)
|
|
8
26
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
27
|
};
|
|
28
|
+
var __copyProps = (to, from, except, desc) => {
|
|
29
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
30
|
+
for (let key of __getOwnPropNames(from))
|
|
31
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
32
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
33
|
+
}
|
|
34
|
+
return to;
|
|
35
|
+
};
|
|
36
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
37
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
38
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
39
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
40
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
41
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
42
|
+
mod
|
|
43
|
+
));
|
|
44
|
+
|
|
45
|
+
// src/core/logger.ts
|
|
46
|
+
var logger_exports = {};
|
|
47
|
+
__export(logger_exports, {
|
|
48
|
+
LogLevels: () => LogLevels,
|
|
49
|
+
createLogger: () => createLogger,
|
|
50
|
+
printServerUrls: () => printServerUrls
|
|
51
|
+
});
|
|
52
|
+
import readline from "readline";
|
|
53
|
+
import pc from "picocolors";
|
|
54
|
+
function getTimeFormatter() {
|
|
55
|
+
return new Intl.DateTimeFormat(void 0, {
|
|
56
|
+
hour: "numeric",
|
|
57
|
+
minute: "numeric",
|
|
58
|
+
second: "numeric"
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
function createLogger(level = "info", options = {}) {
|
|
62
|
+
if (options.customLogger) {
|
|
63
|
+
return options.customLogger;
|
|
64
|
+
}
|
|
65
|
+
const timeFormatter = getTimeFormatter();
|
|
66
|
+
const loggedErrors = /* @__PURE__ */ new WeakSet();
|
|
67
|
+
const { prefix = "[nasti]", allowClearScreen = true, console: console_ = console } = options;
|
|
68
|
+
const thresh = LogLevels[level];
|
|
69
|
+
const canClearScreen = allowClearScreen && process.stdout.isTTY && !process.env.CI;
|
|
70
|
+
const clear = canClearScreen ? clearScreen : () => {
|
|
71
|
+
};
|
|
72
|
+
function format(type, msg, options2 = {}) {
|
|
73
|
+
if (options2.timestamp) {
|
|
74
|
+
const tag = type === "info" ? pc.cyan(pc.bold(prefix)) : type === "warn" ? pc.yellow(pc.bold(prefix)) : pc.red(pc.bold(prefix));
|
|
75
|
+
return `${pc.dim(timeFormatter.format(/* @__PURE__ */ new Date()))} ${tag} ${msg}`;
|
|
76
|
+
}
|
|
77
|
+
return msg;
|
|
78
|
+
}
|
|
79
|
+
function output(type, msg, options2 = {}) {
|
|
80
|
+
if (thresh < LogLevels[type]) return;
|
|
81
|
+
const method = type === "info" ? "log" : type;
|
|
82
|
+
if (options2.error) {
|
|
83
|
+
loggedErrors.add(options2.error);
|
|
84
|
+
}
|
|
85
|
+
if (canClearScreen) {
|
|
86
|
+
if (type === lastType && msg === lastMsg) {
|
|
87
|
+
sameCount++;
|
|
88
|
+
clear();
|
|
89
|
+
console_[method](format(type, msg, options2), pc.yellow(`(x${sameCount + 1})`));
|
|
90
|
+
} else {
|
|
91
|
+
sameCount = 0;
|
|
92
|
+
lastMsg = msg;
|
|
93
|
+
lastType = type;
|
|
94
|
+
if (options2.clear) clear();
|
|
95
|
+
console_[method](format(type, msg, options2));
|
|
96
|
+
}
|
|
97
|
+
} else {
|
|
98
|
+
console_[method](format(type, msg, options2));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const warnedMessages = /* @__PURE__ */ new Set();
|
|
102
|
+
const logger = {
|
|
103
|
+
hasWarned: false,
|
|
104
|
+
info(msg, opts) {
|
|
105
|
+
output("info", msg, opts);
|
|
106
|
+
},
|
|
107
|
+
warn(msg, opts) {
|
|
108
|
+
logger.hasWarned = true;
|
|
109
|
+
output("warn", msg, opts);
|
|
110
|
+
},
|
|
111
|
+
warnOnce(msg, opts) {
|
|
112
|
+
if (warnedMessages.has(msg)) return;
|
|
113
|
+
logger.hasWarned = true;
|
|
114
|
+
output("warn", msg, opts);
|
|
115
|
+
warnedMessages.add(msg);
|
|
116
|
+
},
|
|
117
|
+
error(msg, opts) {
|
|
118
|
+
output("error", msg, opts);
|
|
119
|
+
},
|
|
120
|
+
clearScreen(type) {
|
|
121
|
+
if (thresh >= LogLevels[type]) clear();
|
|
122
|
+
},
|
|
123
|
+
hasErrorLogged(error) {
|
|
124
|
+
return loggedErrors.has(error);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
return logger;
|
|
128
|
+
}
|
|
129
|
+
function clearScreen() {
|
|
130
|
+
const repeatCount = process.stdout.rows - 2;
|
|
131
|
+
const blank = repeatCount > 0 ? "\n".repeat(repeatCount) : "";
|
|
132
|
+
console.log(blank);
|
|
133
|
+
readline.cursorTo(process.stdout, 0, 0);
|
|
134
|
+
readline.clearScreenDown(process.stdout);
|
|
135
|
+
}
|
|
136
|
+
function printServerUrls(urls, info) {
|
|
137
|
+
const colorUrl = (url) => pc.cyan(url.replace(/:(\d+)\//, (_, port) => `:${pc.bold(port)}/`));
|
|
138
|
+
for (const url of urls.local) {
|
|
139
|
+
info(` ${pc.green("\u279C")} ${pc.bold("Local")}: ${colorUrl(url)}`);
|
|
140
|
+
}
|
|
141
|
+
for (const url of urls.network) {
|
|
142
|
+
info(` ${pc.green("\u279C")} ${pc.bold("Network")}: ${colorUrl(url)}`);
|
|
143
|
+
}
|
|
144
|
+
if (urls.network.length === 0) {
|
|
145
|
+
info(
|
|
146
|
+
pc.dim(` ${pc.green("\u279C")} ${pc.bold("Network")}: use `) + pc.bold("--host") + pc.dim(" to expose")
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
var LogLevels, lastType, lastMsg, sameCount;
|
|
151
|
+
var init_logger = __esm({
|
|
152
|
+
"src/core/logger.ts"() {
|
|
153
|
+
"use strict";
|
|
154
|
+
LogLevels = {
|
|
155
|
+
silent: 0,
|
|
156
|
+
error: 1,
|
|
157
|
+
warn: 2,
|
|
158
|
+
info: 3
|
|
159
|
+
};
|
|
160
|
+
sameCount = 0;
|
|
161
|
+
}
|
|
162
|
+
});
|
|
10
163
|
|
|
11
164
|
// src/config/defaults.ts
|
|
12
|
-
var defaultResolve, defaultServer, defaultBuild, defaultElectron, defaults;
|
|
165
|
+
var defaultResolve, defaultServer, defaultBuild, defaultElectron, defaultExperimental, defaults;
|
|
13
166
|
var init_defaults = __esm({
|
|
14
167
|
"src/config/defaults.ts"() {
|
|
15
168
|
"use strict";
|
|
@@ -36,7 +189,12 @@ var init_defaults = __esm({
|
|
|
36
189
|
target: "es2022",
|
|
37
190
|
rolldownOptions: {},
|
|
38
191
|
emptyOutDir: true,
|
|
39
|
-
css: {}
|
|
192
|
+
css: {},
|
|
193
|
+
reportCompressedSize: true,
|
|
194
|
+
chunkSizeWarningLimit: 500,
|
|
195
|
+
cssCodeSplit: true,
|
|
196
|
+
// 默认跟随 build.minify(resolveConfig 中按 minify 取值填充)
|
|
197
|
+
cssMinify: true
|
|
40
198
|
};
|
|
41
199
|
defaultElectron = {
|
|
42
200
|
main: "src/electron/main.ts",
|
|
@@ -51,6 +209,9 @@ var init_defaults = __esm({
|
|
|
51
209
|
minVersion: 41,
|
|
52
210
|
external: ["electron"]
|
|
53
211
|
};
|
|
212
|
+
defaultExperimental = {
|
|
213
|
+
bundledDev: false
|
|
214
|
+
};
|
|
54
215
|
defaults = {
|
|
55
216
|
root: ".",
|
|
56
217
|
base: "/",
|
|
@@ -63,7 +224,9 @@ var init_defaults = __esm({
|
|
|
63
224
|
electron: defaultElectron,
|
|
64
225
|
plugins: [],
|
|
65
226
|
envPrefix: ["NASTI_", "VITE_"],
|
|
66
|
-
logLevel: "info"
|
|
227
|
+
logLevel: "info",
|
|
228
|
+
clearScreen: true,
|
|
229
|
+
experimental: defaultExperimental
|
|
67
230
|
};
|
|
68
231
|
}
|
|
69
232
|
});
|
|
@@ -128,17 +291,28 @@ async function resolveConfig(inlineConfig = {}, command) {
|
|
|
128
291
|
...fileConfig.plugins ?? [],
|
|
129
292
|
...inlineConfig.plugins ?? []
|
|
130
293
|
];
|
|
131
|
-
const
|
|
294
|
+
const mode = merged.mode ?? (command === "build" ? "production" : "development");
|
|
295
|
+
const env = { mode, command };
|
|
132
296
|
for (const plugin of rawPlugins) {
|
|
133
297
|
if (plugin.config) {
|
|
134
298
|
const result = await plugin.config(merged, env);
|
|
135
299
|
if (result) Object.assign(merged, result);
|
|
136
300
|
}
|
|
137
301
|
}
|
|
302
|
+
const logLevel = merged.logLevel ?? defaults.logLevel;
|
|
303
|
+
const clearScreen2 = merged.clearScreen ?? defaults.clearScreen;
|
|
304
|
+
const logger = createLogger(logLevel, {
|
|
305
|
+
allowClearScreen: clearScreen2,
|
|
306
|
+
customLogger: merged.customLogger
|
|
307
|
+
});
|
|
308
|
+
const mergedBuild = { ...defaults.build, ...merged.build };
|
|
309
|
+
if (merged.build?.cssMinify === void 0) {
|
|
310
|
+
mergedBuild.cssMinify = !!mergedBuild.minify;
|
|
311
|
+
}
|
|
138
312
|
const resolved = {
|
|
139
313
|
root,
|
|
140
314
|
base: merged.base ?? defaults.base,
|
|
141
|
-
mode
|
|
315
|
+
mode,
|
|
142
316
|
target: merged.target ?? defaults.target,
|
|
143
317
|
framework: merged.framework ?? defaults.framework,
|
|
144
318
|
command,
|
|
@@ -151,11 +325,70 @@ async function resolveConfig(inlineConfig = {}, command) {
|
|
|
151
325
|
},
|
|
152
326
|
plugins: [],
|
|
153
327
|
server: { ...defaults.server, ...merged.server },
|
|
154
|
-
build:
|
|
328
|
+
build: mergedBuild,
|
|
155
329
|
electron: { ...defaults.electron, ...merged.electron },
|
|
156
330
|
envPrefix: Array.isArray(merged.envPrefix) ? merged.envPrefix : merged.envPrefix ? [merged.envPrefix] : [...defaults.envPrefix],
|
|
157
|
-
logLevel
|
|
331
|
+
logLevel,
|
|
332
|
+
clearScreen: clearScreen2,
|
|
333
|
+
logger,
|
|
334
|
+
environments: {},
|
|
335
|
+
experimental: {
|
|
336
|
+
bundledDev: merged.experimental?.bundledDev ?? defaults.experimental.bundledDev
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
const userEnvironments = {
|
|
340
|
+
client: {},
|
|
341
|
+
ssr: {},
|
|
342
|
+
...merged.environments ?? {}
|
|
158
343
|
};
|
|
344
|
+
for (const [name, envOptions] of Object.entries(userEnvironments)) {
|
|
345
|
+
for (const plugin of rawPlugins) {
|
|
346
|
+
if (plugin.configEnvironment) {
|
|
347
|
+
const result = await plugin.configEnvironment(name, envOptions, env);
|
|
348
|
+
if (result) Object.assign(envOptions, deepMerge(envOptions, result));
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
for (const [name, envOptions] of Object.entries(userEnvironments)) {
|
|
353
|
+
const consumer = envOptions.consumer ?? (name === "client" ? "client" : "server");
|
|
354
|
+
if (name === "client") {
|
|
355
|
+
if (envOptions.resolve) {
|
|
356
|
+
Object.assign(resolved.resolve, {
|
|
357
|
+
...envOptions.resolve,
|
|
358
|
+
alias: { ...resolved.resolve.alias, ...envOptions.resolve.alias }
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
if (envOptions.build) Object.assign(resolved.build, envOptions.build);
|
|
362
|
+
resolved.environments.client = {
|
|
363
|
+
consumer,
|
|
364
|
+
entry: [],
|
|
365
|
+
// 同引用 —— 精确镜像(assertClientEnvironmentMirror 校验)
|
|
366
|
+
resolve: resolved.resolve,
|
|
367
|
+
build: resolved.build
|
|
368
|
+
};
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
371
|
+
resolved.environments[name] = {
|
|
372
|
+
consumer,
|
|
373
|
+
entry: (Array.isArray(envOptions.entry) ? envOptions.entry : envOptions.entry ? [envOptions.entry] : []).map((e) => path.resolve(root, e)),
|
|
374
|
+
resolve: {
|
|
375
|
+
alias: { ...resolved.resolve.alias, ...envOptions.resolve?.alias },
|
|
376
|
+
extensions: envOptions.resolve?.extensions ?? [...resolved.resolve.extensions],
|
|
377
|
+
// server consumer:node conditions(去 'browser');client 非默认环境沿用 top-level
|
|
378
|
+
conditions: envOptions.resolve?.conditions ?? (consumer === "server" ? ["node", ...resolved.resolve.conditions.filter((c) => c !== "browser")] : [...resolved.resolve.conditions]),
|
|
379
|
+
mainFields: envOptions.resolve?.mainFields ?? (consumer === "server" ? ["module", "main"] : [...resolved.resolve.mainFields])
|
|
380
|
+
},
|
|
381
|
+
build: {
|
|
382
|
+
...resolved.build,
|
|
383
|
+
...envOptions.build,
|
|
384
|
+
// 非 client 环境默认产出到 <outDir>/<envName>(如 dist/ssr),可显式覆盖
|
|
385
|
+
outDir: envOptions.build?.outDir ?? path.join(resolved.build.outDir, name),
|
|
386
|
+
// server 产物默认不压缩(可调试性优先,与 Vite SSR 默认一致),可显式覆盖
|
|
387
|
+
minify: envOptions.build?.minify ?? (consumer === "server" ? false : resolved.build.minify)
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
assertClientEnvironmentMirror(resolved);
|
|
159
392
|
const filteredPlugins = rawPlugins.filter((p) => {
|
|
160
393
|
if (!p.apply) return true;
|
|
161
394
|
if (typeof p.apply === "function") return p.apply(resolved, env);
|
|
@@ -244,11 +477,40 @@ function hasDotNodeFile(dir, depth = 0) {
|
|
|
244
477
|
}
|
|
245
478
|
return false;
|
|
246
479
|
}
|
|
480
|
+
function assertClientEnvironmentMirror(config) {
|
|
481
|
+
if (process.env.NASTI_DISABLE_MIRROR_ASSERT) return;
|
|
482
|
+
const client = config.environments.client;
|
|
483
|
+
if (!client) {
|
|
484
|
+
throw new Error("[nasti] internal: environments.client missing after resolveConfig");
|
|
485
|
+
}
|
|
486
|
+
if (client.resolve === config.resolve && client.build === config.build) return;
|
|
487
|
+
const pairs = [
|
|
488
|
+
["resolve", config.resolve, client.resolve],
|
|
489
|
+
["build", config.build, client.build]
|
|
490
|
+
];
|
|
491
|
+
for (const [field, top, env] of pairs) {
|
|
492
|
+
const a = JSON.stringify(top);
|
|
493
|
+
const b = JSON.stringify(env);
|
|
494
|
+
if (a !== b) {
|
|
495
|
+
throw new Error(
|
|
496
|
+
`[nasti] config mirror violation: top-level \`${field}\` and \`environments.client.${field}\` diverged.
|
|
497
|
+
top-level: ${a}
|
|
498
|
+
client: ${b}
|
|
499
|
+
top-level \u4E0E client \u73AF\u5883\u5FC5\u987B\u7CBE\u786E\u955C\u50CF \u2014\u2014 \u8BF7\u901A\u8FC7 top-level \u6216 environments.client \u4E4B\u4E00\u914D\u7F6E\uFF0C\u4E0D\u8981\u5728\u89E3\u6790\u540E\u5206\u522B\u4FEE\u6539\u4E24\u8005\u3002`
|
|
500
|
+
);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
function isPlainObject(val) {
|
|
505
|
+
if (val === null || typeof val !== "object") return false;
|
|
506
|
+
const proto = Object.getPrototypeOf(val);
|
|
507
|
+
return proto === Object.prototype || proto === null;
|
|
508
|
+
}
|
|
247
509
|
function deepMerge(target, source) {
|
|
248
510
|
const result = { ...target };
|
|
249
511
|
for (const key of Object.keys(source)) {
|
|
250
512
|
const val = source[key];
|
|
251
|
-
if (
|
|
513
|
+
if (isPlainObject(val)) {
|
|
252
514
|
result[key] = deepMerge(
|
|
253
515
|
result[key] ?? {},
|
|
254
516
|
val
|
|
@@ -264,6 +526,7 @@ var init_config = __esm({
|
|
|
264
526
|
"src/config/index.ts"() {
|
|
265
527
|
"use strict";
|
|
266
528
|
init_defaults();
|
|
529
|
+
init_logger();
|
|
267
530
|
CONFIG_FILES = [
|
|
268
531
|
"nasti.config.ts",
|
|
269
532
|
"nasti.config.js",
|
|
@@ -294,8 +557,11 @@ var init_plugin_container = __esm({
|
|
|
294
557
|
config;
|
|
295
558
|
ctx;
|
|
296
559
|
emittedFiles = /* @__PURE__ */ new Map();
|
|
297
|
-
|
|
560
|
+
/** Environment API:容器所属环境(未传时为 undefined,行为同 1.x client) */
|
|
561
|
+
environment;
|
|
562
|
+
constructor(config, environment) {
|
|
298
563
|
this.config = config;
|
|
564
|
+
this.environment = environment;
|
|
299
565
|
this.plugins = sortPlugins(config.plugins);
|
|
300
566
|
this.ctx = this.createContext();
|
|
301
567
|
}
|
|
@@ -316,7 +582,8 @@ var init_plugin_container = __esm({
|
|
|
316
582
|
},
|
|
317
583
|
getModuleInfo(_id) {
|
|
318
584
|
return null;
|
|
319
|
-
}
|
|
585
|
+
},
|
|
586
|
+
environment: container.environment
|
|
320
587
|
};
|
|
321
588
|
}
|
|
322
589
|
/** 返回所有通过 emitFile() 输出的文件 */
|
|
@@ -338,13 +605,14 @@ var init_plugin_container = __esm({
|
|
|
338
605
|
}
|
|
339
606
|
}
|
|
340
607
|
async resolveId(source, importer, options = {}) {
|
|
608
|
+
const ssr = this.environment?.consumer === "server";
|
|
341
609
|
for (const plugin of this.plugins) {
|
|
342
610
|
if (!plugin.resolveId) continue;
|
|
343
611
|
const result = await plugin.resolveId.call(
|
|
344
612
|
this.ctx,
|
|
345
613
|
source,
|
|
346
614
|
importer ?? void 0,
|
|
347
|
-
{ isEntry: options.isEntry ?? false, ssr
|
|
615
|
+
{ isEntry: options.isEntry ?? false, ssr }
|
|
348
616
|
);
|
|
349
617
|
if (result != null) return result;
|
|
350
618
|
}
|
|
@@ -518,6 +786,171 @@ var init_module_graph = __esm({
|
|
|
518
786
|
}
|
|
519
787
|
});
|
|
520
788
|
|
|
789
|
+
// src/core/hot-channel.ts
|
|
790
|
+
function createNoopHotChannel() {
|
|
791
|
+
return {
|
|
792
|
+
send() {
|
|
793
|
+
},
|
|
794
|
+
on() {
|
|
795
|
+
},
|
|
796
|
+
off() {
|
|
797
|
+
},
|
|
798
|
+
listen() {
|
|
799
|
+
},
|
|
800
|
+
close() {
|
|
801
|
+
},
|
|
802
|
+
setInvokeHandler() {
|
|
803
|
+
}
|
|
804
|
+
};
|
|
805
|
+
}
|
|
806
|
+
function createWsHotChannel(ws) {
|
|
807
|
+
const listeners = /* @__PURE__ */ new Map();
|
|
808
|
+
let invokeHandlers;
|
|
809
|
+
return {
|
|
810
|
+
send(payload) {
|
|
811
|
+
ws.send(payload);
|
|
812
|
+
},
|
|
813
|
+
on(event, listener) {
|
|
814
|
+
let set = listeners.get(event);
|
|
815
|
+
if (!set) listeners.set(event, set = /* @__PURE__ */ new Set());
|
|
816
|
+
set.add(listener);
|
|
817
|
+
},
|
|
818
|
+
off(event, listener) {
|
|
819
|
+
listeners.get(event)?.delete(listener);
|
|
820
|
+
},
|
|
821
|
+
listen() {
|
|
822
|
+
},
|
|
823
|
+
close() {
|
|
824
|
+
ws.close();
|
|
825
|
+
},
|
|
826
|
+
setInvokeHandler(handlers) {
|
|
827
|
+
invokeHandlers = handlers;
|
|
828
|
+
void invokeHandlers;
|
|
829
|
+
}
|
|
830
|
+
};
|
|
831
|
+
}
|
|
832
|
+
var init_hot_channel = __esm({
|
|
833
|
+
"src/core/hot-channel.ts"() {
|
|
834
|
+
"use strict";
|
|
835
|
+
}
|
|
836
|
+
});
|
|
837
|
+
|
|
838
|
+
// src/core/debug.ts
|
|
839
|
+
import pc2 from "picocolors";
|
|
840
|
+
function createDebugger(namespace, options = {}) {
|
|
841
|
+
if (!DEBUG) return void 0;
|
|
842
|
+
const patterns = DEBUG.split(",").map((p) => p.trim());
|
|
843
|
+
const enabled = patterns.some((p) => {
|
|
844
|
+
if (p === "*" || p === "nasti:*" || p === "vite:*") return true;
|
|
845
|
+
const normalized = p.startsWith("vite:") ? `nasti:${p.slice(5)}` : p;
|
|
846
|
+
return normalized === namespace;
|
|
847
|
+
});
|
|
848
|
+
if (!enabled) return void 0;
|
|
849
|
+
if (options.onlyWhenFocused) {
|
|
850
|
+
const focus = typeof options.onlyWhenFocused === "string" ? options.onlyWhenFocused : namespace;
|
|
851
|
+
if (!patterns.includes(focus)) return void 0;
|
|
852
|
+
}
|
|
853
|
+
let lastTime = performance.now();
|
|
854
|
+
return (...args) => {
|
|
855
|
+
const now = performance.now();
|
|
856
|
+
const elapsed = now - lastTime;
|
|
857
|
+
lastTime = now;
|
|
858
|
+
const msg = args.map((a) => {
|
|
859
|
+
if (typeof a === "string") return a;
|
|
860
|
+
try {
|
|
861
|
+
return JSON.stringify(a);
|
|
862
|
+
} catch {
|
|
863
|
+
return String(a);
|
|
864
|
+
}
|
|
865
|
+
}).join(" ");
|
|
866
|
+
if (filter && !msg.includes(filter)) return;
|
|
867
|
+
console.debug(
|
|
868
|
+
`${pc2.magenta(namespace)} ${msg} ${pc2.dim(`+${Math.round(elapsed)}ms`)}`
|
|
869
|
+
);
|
|
870
|
+
};
|
|
871
|
+
}
|
|
872
|
+
var DEBUG, filter;
|
|
873
|
+
var init_debug = __esm({
|
|
874
|
+
"src/core/debug.ts"() {
|
|
875
|
+
"use strict";
|
|
876
|
+
DEBUG = process.env.DEBUG;
|
|
877
|
+
filter = process.env.NASTI_DEBUG_FILTER || process.env.VITE_DEBUG_FILTER;
|
|
878
|
+
}
|
|
879
|
+
});
|
|
880
|
+
|
|
881
|
+
// src/core/environment.ts
|
|
882
|
+
function resolveEnvironmentPlugins(environment, plugins) {
|
|
883
|
+
return plugins.filter((p) => {
|
|
884
|
+
if (!p.applyToEnvironment) return true;
|
|
885
|
+
try {
|
|
886
|
+
return p.applyToEnvironment(environment);
|
|
887
|
+
} catch (err) {
|
|
888
|
+
environment.config.logger.error(
|
|
889
|
+
`[nasti] plugin "${p.name}" applyToEnvironment threw: ${err.message}`,
|
|
890
|
+
{ error: err }
|
|
891
|
+
);
|
|
892
|
+
return false;
|
|
893
|
+
}
|
|
894
|
+
});
|
|
895
|
+
}
|
|
896
|
+
var debug, NastiEnvironment;
|
|
897
|
+
var init_environment = __esm({
|
|
898
|
+
"src/core/environment.ts"() {
|
|
899
|
+
"use strict";
|
|
900
|
+
init_plugin_container();
|
|
901
|
+
init_module_graph();
|
|
902
|
+
init_hot_channel();
|
|
903
|
+
init_debug();
|
|
904
|
+
debug = createDebugger("nasti:environment");
|
|
905
|
+
NastiEnvironment = class {
|
|
906
|
+
name;
|
|
907
|
+
consumer;
|
|
908
|
+
mode;
|
|
909
|
+
config;
|
|
910
|
+
options;
|
|
911
|
+
hot;
|
|
912
|
+
/** applyToEnvironment 过滤后的插件(init() 后可用) */
|
|
913
|
+
plugins = [];
|
|
914
|
+
/** per-env 插件容器(init() 后可用;dev 管线使用) */
|
|
915
|
+
pluginContainer = null;
|
|
916
|
+
/** per-env 模块图(dev 管线使用) */
|
|
917
|
+
moduleGraph;
|
|
918
|
+
candidatePlugins;
|
|
919
|
+
initialized = false;
|
|
920
|
+
constructor(name, config, init = {}) {
|
|
921
|
+
const options = config.environments[name];
|
|
922
|
+
if (!options) {
|
|
923
|
+
throw new Error(
|
|
924
|
+
`[nasti] unknown environment "${name}" \u2014 declare it in config.environments`
|
|
925
|
+
);
|
|
926
|
+
}
|
|
927
|
+
this.name = name;
|
|
928
|
+
this.consumer = options.consumer;
|
|
929
|
+
this.mode = init.mode ?? (config.command === "build" ? "build" : "dev");
|
|
930
|
+
this.config = config;
|
|
931
|
+
this.options = options;
|
|
932
|
+
this.hot = init.hot ?? createNoopHotChannel();
|
|
933
|
+
this.moduleGraph = new ModuleGraph();
|
|
934
|
+
this.candidatePlugins = init.plugins ?? config.plugins;
|
|
935
|
+
}
|
|
936
|
+
/** 过滤插件并建 per-env PluginContainer */
|
|
937
|
+
async init() {
|
|
938
|
+
if (this.initialized) return;
|
|
939
|
+
this.initialized = true;
|
|
940
|
+
this.plugins = resolveEnvironmentPlugins(this, this.candidatePlugins);
|
|
941
|
+
this.pluginContainer = new PluginContainer(
|
|
942
|
+
{ ...this.config, plugins: this.plugins },
|
|
943
|
+
this
|
|
944
|
+
);
|
|
945
|
+
debug?.(`env "${this.name}" initialized (${this.plugins.length} plugins)`);
|
|
946
|
+
}
|
|
947
|
+
async close() {
|
|
948
|
+
await this.hot.close?.();
|
|
949
|
+
}
|
|
950
|
+
};
|
|
951
|
+
}
|
|
952
|
+
});
|
|
953
|
+
|
|
521
954
|
// src/server/ws.ts
|
|
522
955
|
import { WebSocketServer as WsServer } from "ws";
|
|
523
956
|
function createWebSocketServer(server) {
|
|
@@ -718,7 +1151,7 @@ function loadEnv(mode, root, prefixes) {
|
|
|
718
1151
|
}
|
|
719
1152
|
return filtered;
|
|
720
1153
|
}
|
|
721
|
-
function buildEnvDefine(env, mode) {
|
|
1154
|
+
function buildEnvDefine(env, mode, overrides = {}) {
|
|
722
1155
|
const define = {};
|
|
723
1156
|
for (const [key, value] of Object.entries(env)) {
|
|
724
1157
|
define[`import.meta.env.${key}`] = JSON.stringify(value);
|
|
@@ -727,7 +1160,10 @@ function buildEnvDefine(env, mode) {
|
|
|
727
1160
|
define["import.meta.env.DEV"] = mode !== "production" ? "true" : "false";
|
|
728
1161
|
define["import.meta.env.PROD"] = mode === "production" ? "true" : "false";
|
|
729
1162
|
define["import.meta.env.SSR"] = "false";
|
|
730
|
-
return define;
|
|
1163
|
+
return { ...define, ...overrides };
|
|
1164
|
+
}
|
|
1165
|
+
function ssrDefineOverrides(consumer) {
|
|
1166
|
+
return { "import.meta.env.SSR": consumer === "server" ? "true" : "false" };
|
|
731
1167
|
}
|
|
732
1168
|
function replaceEnvInCode(code, define) {
|
|
733
1169
|
let result = code;
|
|
@@ -747,6 +1183,7 @@ var init_env = __esm({
|
|
|
747
1183
|
var middleware_exports = {};
|
|
748
1184
|
__export(middleware_exports, {
|
|
749
1185
|
REACT_REFRESH_GLOBAL_PREAMBLE: () => REACT_REFRESH_GLOBAL_PREAMBLE,
|
|
1186
|
+
getReactRefreshRuntimeEsm: () => getReactRefreshRuntimeEsm,
|
|
750
1187
|
transformMiddleware: () => transformMiddleware,
|
|
751
1188
|
transformRequest: () => transformRequest
|
|
752
1189
|
});
|
|
@@ -754,11 +1191,12 @@ import path4 from "path";
|
|
|
754
1191
|
import fs4 from "fs";
|
|
755
1192
|
import { createRequire } from "module";
|
|
756
1193
|
import { fileURLToPath, pathToFileURL as pathToFileURL2 } from "url";
|
|
1194
|
+
import pc3 from "picocolors";
|
|
757
1195
|
function getReactRefreshRuntimeEsm() {
|
|
758
1196
|
if (__refreshRuntimeCache) return __refreshRuntimeCache;
|
|
759
1197
|
let cjsPath;
|
|
760
1198
|
try {
|
|
761
|
-
const pkgPath =
|
|
1199
|
+
const pkgPath = __require2.resolve("react-refresh/package.json");
|
|
762
1200
|
cjsPath = path4.join(path4.dirname(pkgPath), "cjs", "react-refresh-runtime.development.js");
|
|
763
1201
|
} catch (err) {
|
|
764
1202
|
cjsPath = path4.resolve(__dirname_esm, "../../node_modules/react-refresh/cjs/react-refresh-runtime.development.js");
|
|
@@ -889,7 +1327,11 @@ function transformMiddleware(ctx) {
|
|
|
889
1327
|
return;
|
|
890
1328
|
}
|
|
891
1329
|
} catch (err) {
|
|
892
|
-
|
|
1330
|
+
ctx.config.logger.error(
|
|
1331
|
+
pc3.red(`Transform error: ${url}
|
|
1332
|
+
`) + (err.stack ?? err.message),
|
|
1333
|
+
{ timestamp: true, error: err }
|
|
1334
|
+
);
|
|
893
1335
|
res.statusCode = 500;
|
|
894
1336
|
res.end(`Transform error: ${err.message}`);
|
|
895
1337
|
return;
|
|
@@ -908,6 +1350,28 @@ async function transformRequest(url, ctx) {
|
|
|
908
1350
|
if (cleanReqUrl === "/@react-refresh") {
|
|
909
1351
|
return { code: getReactRefreshRuntimeEsm() };
|
|
910
1352
|
}
|
|
1353
|
+
if (cleanReqUrl.startsWith("/@modules/") && url.includes("?")) {
|
|
1354
|
+
const idParam = new URLSearchParams(url.slice(url.indexOf("?") + 1)).get("id");
|
|
1355
|
+
let realId = null;
|
|
1356
|
+
let realIdValid = false;
|
|
1357
|
+
try {
|
|
1358
|
+
if (idParam) {
|
|
1359
|
+
realId = fs4.realpathSync(idParam);
|
|
1360
|
+
realIdValid = fs4.statSync(realId).isFile() && (realId.includes(`${path4.sep}node_modules${path4.sep}`) || isUnderRoot(realId, config.root));
|
|
1361
|
+
}
|
|
1362
|
+
} catch {
|
|
1363
|
+
realId = null;
|
|
1364
|
+
realIdValid = false;
|
|
1365
|
+
}
|
|
1366
|
+
if (realId && realIdValid) {
|
|
1367
|
+
const mod2 = await moduleGraph.ensureEntryFromUrl(url);
|
|
1368
|
+
moduleGraph.registerModule(mod2, realId);
|
|
1369
|
+
const code2 = await bundlePackageAsEsm(realId, config.root);
|
|
1370
|
+
const transformResult2 = { code: code2 };
|
|
1371
|
+
mod2.transformResult = transformResult2;
|
|
1372
|
+
return transformResult2;
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
911
1375
|
if (cleanReqUrl.startsWith("/@modules/")) {
|
|
912
1376
|
const spec = cleanReqUrl.slice("/@modules/".length);
|
|
913
1377
|
const virtual = await loadVirtualModule(spec, ctx);
|
|
@@ -918,12 +1382,34 @@ async function transformRequest(url, ctx) {
|
|
|
918
1382
|
return virtual.result;
|
|
919
1383
|
}
|
|
920
1384
|
}
|
|
1385
|
+
const rawQuery = url.includes("?") ? url.slice(url.indexOf("?") + 1) : "";
|
|
1386
|
+
if (rawQuery && !/^t=\d+$/.test(rawQuery)) {
|
|
1387
|
+
const loaded = await pluginContainer.load(url);
|
|
1388
|
+
if (loaded != null) {
|
|
1389
|
+
let code2 = typeof loaded === "string" ? loaded : loaded.code;
|
|
1390
|
+
const transformed = await pluginContainer.transform(code2, url);
|
|
1391
|
+
if (transformed != null) {
|
|
1392
|
+
code2 = typeof transformed === "string" ? transformed : transformed.code;
|
|
1393
|
+
}
|
|
1394
|
+
const mod2 = await moduleGraph.ensureEntryFromUrl(url);
|
|
1395
|
+
moduleGraph.registerModule(mod2, cleanReqUrl);
|
|
1396
|
+
code2 = injectImportMetaHot(code2, url);
|
|
1397
|
+
code2 = replaceEnvInCode(code2, ctx.envDefine ?? buildEnvDefine(
|
|
1398
|
+
loadEnv(config.mode, config.root, config.envPrefix),
|
|
1399
|
+
config.mode
|
|
1400
|
+
));
|
|
1401
|
+
code2 = rewriteImports(code2, config, cleanReqUrl);
|
|
1402
|
+
const transformResult2 = { code: code2 };
|
|
1403
|
+
mod2.transformResult = transformResult2;
|
|
1404
|
+
return transformResult2;
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
921
1407
|
const filePath = resolveUrlToFile(url, config.root);
|
|
922
1408
|
if (!filePath || !fs4.existsSync(filePath)) return null;
|
|
923
1409
|
const mod = await moduleGraph.ensureEntryFromUrl(url);
|
|
924
1410
|
moduleGraph.registerModule(mod, filePath);
|
|
925
1411
|
if (cleanReqUrl.startsWith("/@modules/")) {
|
|
926
|
-
const code2 = await bundlePackageAsEsm(filePath);
|
|
1412
|
+
const code2 = await bundlePackageAsEsm(filePath, config.root);
|
|
927
1413
|
const transformResult2 = { code: code2 };
|
|
928
1414
|
mod.transformResult = transformResult2;
|
|
929
1415
|
return transformResult2;
|
|
@@ -986,17 +1472,17 @@ async function loadVirtualModule(spec, ctx) {
|
|
|
986
1472
|
code = rewriteImports(code, config, anchor);
|
|
987
1473
|
return { id: resolvedId, result: { code } };
|
|
988
1474
|
}
|
|
989
|
-
async function bundlePackageAsEsm(entryFile) {
|
|
1475
|
+
async function bundlePackageAsEsm(entryFile, root) {
|
|
990
1476
|
if (!esmBundleCache.has(entryFile)) {
|
|
991
|
-
esmBundleCache.set(entryFile, doBundlePackage(entryFile));
|
|
1477
|
+
esmBundleCache.set(entryFile, doBundlePackage(entryFile, root));
|
|
992
1478
|
}
|
|
993
1479
|
return esmBundleCache.get(entryFile);
|
|
994
1480
|
}
|
|
995
|
-
async function doBundlePackage(entryFile) {
|
|
996
|
-
const shim = await tryGenerateSubpathShim(entryFile);
|
|
1481
|
+
async function doBundlePackage(entryFile, root) {
|
|
1482
|
+
const shim = await tryGenerateSubpathShim(entryFile, root);
|
|
997
1483
|
if (shim != null) return shim;
|
|
998
1484
|
const { rolldown: rolldown4 } = await import("rolldown");
|
|
999
|
-
const
|
|
1485
|
+
const bundle2 = await rolldown4({
|
|
1000
1486
|
input: entryFile,
|
|
1001
1487
|
// 仅将其他 npm 包外部化;相对路径(包内部文件)全部内联打包
|
|
1002
1488
|
external: (id) => {
|
|
@@ -1004,27 +1490,28 @@ async function doBundlePackage(entryFile) {
|
|
|
1004
1490
|
return true;
|
|
1005
1491
|
}
|
|
1006
1492
|
});
|
|
1007
|
-
const result = await
|
|
1008
|
-
await
|
|
1493
|
+
const result = await bundle2.generate({ format: "esm", exports: "named" });
|
|
1494
|
+
await bundle2.close();
|
|
1009
1495
|
let code = result.output[0].code;
|
|
1010
1496
|
code = code.replace(/process\.env\.NODE_ENV/g, '"development"');
|
|
1497
|
+
const externalBaseDir = path4.dirname(entryFile);
|
|
1011
1498
|
code = code.replace(
|
|
1012
1499
|
/^(import\b[^;'"]*?\bfrom\s+)(['"])([^'"./][^'"]*)(\2)/gm,
|
|
1013
|
-
(_, prefix, q, spec) => `${prefix}${q}
|
|
1500
|
+
(_, prefix, q, spec) => `${prefix}${q}${externalSpecToModuleUrl(spec, externalBaseDir)}${q}`
|
|
1014
1501
|
).replace(
|
|
1015
1502
|
/^(export\b[^;'"]*?\bfrom\s+)(['"])([^'"./][^'"]*)(\2)/gm,
|
|
1016
|
-
(_, prefix, q, spec) => `${prefix}${q}
|
|
1503
|
+
(_, prefix, q, spec) => `${prefix}${q}${externalSpecToModuleUrl(spec, externalBaseDir)}${q}`
|
|
1017
1504
|
).replace(
|
|
1018
1505
|
/^(import\s+)(['"])([^'"./][^'"]*)(\2)/gm,
|
|
1019
|
-
(_, prefix, q, spec) => `${prefix}${q}
|
|
1506
|
+
(_, prefix, q, spec) => `${prefix}${q}${externalSpecToModuleUrl(spec, externalBaseDir)}${q}`
|
|
1020
1507
|
);
|
|
1021
|
-
code = rewriteExternalRequires(code);
|
|
1508
|
+
code = rewriteExternalRequires(code, externalBaseDir);
|
|
1022
1509
|
if (code.includes("__commonJSMin")) {
|
|
1023
1510
|
code = await injectCjsNamedExports(code, entryFile);
|
|
1024
1511
|
}
|
|
1025
1512
|
return code;
|
|
1026
1513
|
}
|
|
1027
|
-
async function tryGenerateSubpathShim(entryFile) {
|
|
1514
|
+
async function tryGenerateSubpathShim(entryFile, root) {
|
|
1028
1515
|
const NM = `${path4.sep}node_modules${path4.sep}`;
|
|
1029
1516
|
if (!entryFile.includes(NM)) return null;
|
|
1030
1517
|
let pkgDir = null;
|
|
@@ -1075,9 +1562,11 @@ async function tryGenerateSubpathShim(entryFile) {
|
|
|
1075
1562
|
if (!("default" in mainNs)) return null;
|
|
1076
1563
|
if (mainNs["default"] !== subNs["default"]) return null;
|
|
1077
1564
|
}
|
|
1565
|
+
const rootMain = resolveNodeModule(root, pkgName);
|
|
1566
|
+
const mainEntryUrl = rootMain && rootMain.startsWith(pkgDir + path4.sep) ? `/@modules/${pkgName}` : `/@modules/${pkgName}?id=${encodeURIComponent(mainEntry)}`;
|
|
1078
1567
|
const lines = [
|
|
1079
1568
|
`// Nasti subpath shim \u2192 ${pkgName} (avoid duplicate bundling)`,
|
|
1080
|
-
`import * as __pkg from "
|
|
1569
|
+
`import * as __pkg from "${mainEntryUrl}";`
|
|
1081
1570
|
];
|
|
1082
1571
|
for (const k of subKeys) {
|
|
1083
1572
|
lines.push(`export const ${k} = __pkg[${JSON.stringify(k)}];`);
|
|
@@ -1121,7 +1610,7 @@ function pickMainEntryByExtension(pkgDir, preferredExt) {
|
|
|
1121
1610
|
}
|
|
1122
1611
|
return null;
|
|
1123
1612
|
}
|
|
1124
|
-
function rewriteExternalRequires(code) {
|
|
1613
|
+
function rewriteExternalRequires(code, baseDir) {
|
|
1125
1614
|
const pkgs = /* @__PURE__ */ new Set();
|
|
1126
1615
|
const re = /__require\(["']([^"']+)["']\)/g;
|
|
1127
1616
|
let m;
|
|
@@ -1133,7 +1622,7 @@ function rewriteExternalRequires(code) {
|
|
|
1133
1622
|
const imports = [];
|
|
1134
1623
|
for (const pkg of pkgs) {
|
|
1135
1624
|
const safe = pkg.replace(/[^a-zA-Z0-9_$]/g, "_");
|
|
1136
|
-
imports.push(`import * as __ns_${safe} from "
|
|
1625
|
+
imports.push(`import * as __ns_${safe} from "${externalSpecToModuleUrl(pkg, baseDir)}";`);
|
|
1137
1626
|
imports.push(`var __req_${safe} = "default" in __ns_${safe} ? __ns_${safe}["default"] : __ns_${safe};`);
|
|
1138
1627
|
result = result.replaceAll(`__require("${pkg}")`, `__req_${safe}`);
|
|
1139
1628
|
result = result.replaceAll(`__require('${pkg}')`, `__req_${safe}`);
|
|
@@ -1142,8 +1631,8 @@ function rewriteExternalRequires(code) {
|
|
|
1142
1631
|
}
|
|
1143
1632
|
async function injectCjsNamedExports(code, entryFile) {
|
|
1144
1633
|
try {
|
|
1145
|
-
const { createRequire:
|
|
1146
|
-
const req =
|
|
1634
|
+
const { createRequire: createRequire6 } = await import("module");
|
|
1635
|
+
const req = createRequire6(entryFile);
|
|
1147
1636
|
const cjsExports = req(entryFile);
|
|
1148
1637
|
if (!cjsExports || typeof cjsExports !== "object" && typeof cjsExports !== "function" || Array.isArray(cjsExports)) return code;
|
|
1149
1638
|
const namedKeys = Object.keys(cjsExports).filter(
|
|
@@ -1230,7 +1719,20 @@ function isUnderRoot(abs, root) {
|
|
|
1230
1719
|
const rel = path4.relative(root, abs);
|
|
1231
1720
|
return !!rel && !rel.startsWith("..") && !path4.isAbsolute(rel);
|
|
1232
1721
|
}
|
|
1233
|
-
function
|
|
1722
|
+
function externalSpecToModuleUrl(spec, baseDir) {
|
|
1723
|
+
const resolved = resolveNodeModule(baseDir, spec);
|
|
1724
|
+
return resolved ? `/@modules/${spec}?id=${encodeURIComponent(resolved)}` : `/@modules/${spec}`;
|
|
1725
|
+
}
|
|
1726
|
+
function resolveNodeModule(baseDir, moduleName) {
|
|
1727
|
+
const resolved = resolveNodeModuleEntry(baseDir, moduleName);
|
|
1728
|
+
if (!resolved) return null;
|
|
1729
|
+
try {
|
|
1730
|
+
return fs4.realpathSync(resolved);
|
|
1731
|
+
} catch {
|
|
1732
|
+
return resolved;
|
|
1733
|
+
}
|
|
1734
|
+
}
|
|
1735
|
+
function resolveNodeModuleEntry(root, moduleName) {
|
|
1234
1736
|
let pkgName;
|
|
1235
1737
|
let subpath;
|
|
1236
1738
|
if (moduleName.startsWith("@")) {
|
|
@@ -1300,7 +1802,12 @@ function resolvePackageExports(exports, key, pkgDir) {
|
|
|
1300
1802
|
return key === "." ? path4.join(pkgDir, exports) : null;
|
|
1301
1803
|
}
|
|
1302
1804
|
const entry = exports[key];
|
|
1303
|
-
if (entry === void 0)
|
|
1805
|
+
if (entry === void 0) {
|
|
1806
|
+
if (key === "." && typeof exports === "object" && !Object.keys(exports).some((k) => k.startsWith("."))) {
|
|
1807
|
+
return resolveExportValue(exports, pkgDir);
|
|
1808
|
+
}
|
|
1809
|
+
return null;
|
|
1810
|
+
}
|
|
1304
1811
|
return resolveExportValue(entry, pkgDir);
|
|
1305
1812
|
}
|
|
1306
1813
|
function resolveExportValue(value, pkgDir) {
|
|
@@ -1477,7 +1984,7 @@ export function createHotContext(ownerPath) {
|
|
|
1477
1984
|
}
|
|
1478
1985
|
`;
|
|
1479
1986
|
}
|
|
1480
|
-
var __dirname_esm,
|
|
1987
|
+
var __dirname_esm, __require2, __refreshRuntimeCache, REACT_REFRESH_GLOBAL_PREAMBLE, esmBundleCache, VALID_IDENT, RESOLVE_EXTENSIONS, ESM_CONDITIONS;
|
|
1481
1988
|
var init_middleware = __esm({
|
|
1482
1989
|
"src/server/middleware.ts"() {
|
|
1483
1990
|
"use strict";
|
|
@@ -1485,7 +1992,7 @@ var init_middleware = __esm({
|
|
|
1485
1992
|
init_html();
|
|
1486
1993
|
init_env();
|
|
1487
1994
|
__dirname_esm = path4.dirname(fileURLToPath(import.meta.url));
|
|
1488
|
-
|
|
1995
|
+
__require2 = createRequire(import.meta.url);
|
|
1489
1996
|
__refreshRuntimeCache = null;
|
|
1490
1997
|
REACT_REFRESH_GLOBAL_PREAMBLE = `
|
|
1491
1998
|
import RefreshRuntime from "/@react-refresh";
|
|
@@ -1504,9 +2011,12 @@ window.__vite_plugin_react_preamble_installed__ = true;
|
|
|
1504
2011
|
// src/server/hmr.ts
|
|
1505
2012
|
import path5 from "path";
|
|
1506
2013
|
import fs5 from "fs";
|
|
2014
|
+
import pc4 from "picocolors";
|
|
1507
2015
|
async function handleFileChange(file, server) {
|
|
1508
2016
|
const { moduleGraph, ws, config } = server;
|
|
2017
|
+
const logger = config.logger;
|
|
1509
2018
|
const relativePath = "/" + path5.relative(config.root, file);
|
|
2019
|
+
const shortFile = path5.relative(config.root, file);
|
|
1510
2020
|
const mods = moduleGraph.getModulesByFile(file);
|
|
1511
2021
|
if (!mods || mods.size === 0) {
|
|
1512
2022
|
return;
|
|
@@ -1534,6 +2044,7 @@ async function handleFileChange(file, server) {
|
|
|
1534
2044
|
for (const affected of affectedModules) {
|
|
1535
2045
|
const boundaries = moduleGraph.getHmrBoundaries(affected);
|
|
1536
2046
|
if (boundaries.length === 0) {
|
|
2047
|
+
logger.info(pc4.green("page reload ") + pc4.dim(shortFile), { timestamp: true });
|
|
1537
2048
|
ws.send({ type: "full-reload", path: relativePath });
|
|
1538
2049
|
return;
|
|
1539
2050
|
}
|
|
@@ -1548,6 +2059,10 @@ async function handleFileChange(file, server) {
|
|
|
1548
2059
|
}
|
|
1549
2060
|
}
|
|
1550
2061
|
if (updates.length > 0) {
|
|
2062
|
+
logger.info(
|
|
2063
|
+
updates.map((u) => pc4.green("hmr update ") + pc4.dim(u.path)).join("\n"),
|
|
2064
|
+
{ timestamp: true }
|
|
2065
|
+
);
|
|
1551
2066
|
ws.send({ type: "update", updates });
|
|
1552
2067
|
}
|
|
1553
2068
|
}
|
|
@@ -1662,396 +2177,2469 @@ var init_resolve = __esm({
|
|
|
1662
2177
|
}
|
|
1663
2178
|
});
|
|
1664
2179
|
|
|
1665
|
-
//
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
const withoutBlockComments = css.replace(/\/\*[\s\S]*?\*\//g, "");
|
|
1671
|
-
const withoutLineComments = withoutBlockComments.replace(/\/\/.*$/gm, "");
|
|
1672
|
-
return TAILWIND_DIRECTIVE_RE.test(withoutLineComments);
|
|
1673
|
-
}
|
|
1674
|
-
async function loadTailwind(projectRoot) {
|
|
1675
|
-
if (cached && cachedRoot === projectRoot) return cached;
|
|
1676
|
-
const req = createRequire3(path7.join(projectRoot, "package.json"));
|
|
1677
|
-
let nodePath;
|
|
1678
|
-
let oxidePath;
|
|
1679
|
-
try {
|
|
1680
|
-
nodePath = req.resolve("@tailwindcss/node");
|
|
1681
|
-
oxidePath = req.resolve("@tailwindcss/oxide");
|
|
1682
|
-
} catch {
|
|
1683
|
-
throw new Error(
|
|
1684
|
-
"[nasti] CSS contains Tailwind v4 directives but `@tailwindcss/node` and/or `@tailwindcss/oxide` are not installed in this project. Install them with: npm i -D tailwindcss @tailwindcss/node @tailwindcss/oxide"
|
|
1685
|
-
);
|
|
1686
|
-
}
|
|
1687
|
-
const node = await import(pathToFileURL3(nodePath).href);
|
|
1688
|
-
const oxide = await import(pathToFileURL3(oxidePath).href);
|
|
1689
|
-
cached = { node, oxide };
|
|
1690
|
-
cachedRoot = projectRoot;
|
|
1691
|
-
return cached;
|
|
1692
|
-
}
|
|
1693
|
-
async function compileTailwind(css, fromFile, projectRoot) {
|
|
1694
|
-
const { node, oxide } = await loadTailwind(projectRoot);
|
|
1695
|
-
const dependencies = [];
|
|
1696
|
-
const compiler2 = await node.compile(css, {
|
|
1697
|
-
base: path7.dirname(fromFile),
|
|
1698
|
-
from: fromFile,
|
|
1699
|
-
onDependency: (p) => dependencies.push(p)
|
|
1700
|
-
});
|
|
1701
|
-
const scanner = new oxide.Scanner({ sources: compiler2.sources });
|
|
1702
|
-
const candidates = scanner.scan();
|
|
1703
|
-
return {
|
|
1704
|
-
css: compiler2.build(candidates),
|
|
1705
|
-
dependencies: [...dependencies, ...scanner.files]
|
|
1706
|
-
};
|
|
1707
|
-
}
|
|
1708
|
-
var TAILWIND_DIRECTIVE_RE, cached, cachedRoot;
|
|
1709
|
-
var init_tailwind = __esm({
|
|
1710
|
-
"src/plugins/tailwind.ts"() {
|
|
1711
|
-
"use strict";
|
|
1712
|
-
TAILWIND_DIRECTIVE_RE = /@(?:import\s+["']tailwindcss(?:\b|\/)|tailwind\b|theme\b|apply\b|plugin\b|source\b|utility\b|variant\b|custom-variant\b|reference\b)/;
|
|
1713
|
-
cached = null;
|
|
1714
|
-
cachedRoot = null;
|
|
2180
|
+
// require("../lightningcss.*.node") in node_modules/lightningcss/node/index.js
|
|
2181
|
+
var globRequire_lightningcss_node;
|
|
2182
|
+
var init_ = __esm({
|
|
2183
|
+
'require("../lightningcss.*.node") in node_modules/lightningcss/node/index.js'() {
|
|
2184
|
+
globRequire_lightningcss_node = __glob({});
|
|
1715
2185
|
}
|
|
1716
2186
|
});
|
|
1717
2187
|
|
|
1718
|
-
//
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
2188
|
+
// node_modules/detect-libc/lib/process.js
|
|
2189
|
+
var require_process = __commonJS({
|
|
2190
|
+
"node_modules/detect-libc/lib/process.js"(exports, module) {
|
|
2191
|
+
"use strict";
|
|
2192
|
+
var isLinux = () => process.platform === "linux";
|
|
2193
|
+
var report = null;
|
|
2194
|
+
var getReport = () => {
|
|
2195
|
+
if (!report) {
|
|
2196
|
+
if (isLinux() && process.report) {
|
|
2197
|
+
const orig = process.report.excludeNetwork;
|
|
2198
|
+
process.report.excludeNetwork = true;
|
|
2199
|
+
report = process.report.getReport();
|
|
2200
|
+
process.report.excludeNetwork = orig;
|
|
2201
|
+
} else {
|
|
2202
|
+
report = {};
|
|
2203
|
+
}
|
|
1733
2204
|
}
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
const css = ${escaped};
|
|
1740
|
-
const __nasti_css_id__ = ${JSON.stringify(id)};
|
|
1741
|
-
const __nasti_existing__ = document.querySelector('style[data-nasti-css=' + JSON.stringify(__nasti_css_id__) + ']');
|
|
1742
|
-
if (__nasti_existing__) __nasti_existing__.remove();
|
|
1743
|
-
const style = document.createElement('style');
|
|
1744
|
-
style.setAttribute('data-nasti-css', __nasti_css_id__);
|
|
1745
|
-
style.textContent = css;
|
|
1746
|
-
document.head.appendChild(style);
|
|
2205
|
+
return report;
|
|
2206
|
+
};
|
|
2207
|
+
module.exports = { isLinux, getReport };
|
|
2208
|
+
}
|
|
2209
|
+
});
|
|
1747
2210
|
|
|
1748
|
-
//
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
2211
|
+
// node_modules/detect-libc/lib/filesystem.js
|
|
2212
|
+
var require_filesystem = __commonJS({
|
|
2213
|
+
"node_modules/detect-libc/lib/filesystem.js"(exports, module) {
|
|
2214
|
+
"use strict";
|
|
2215
|
+
var fs12 = __require("fs");
|
|
2216
|
+
var LDD_PATH = "/usr/bin/ldd";
|
|
2217
|
+
var SELF_PATH = "/proc/self/exe";
|
|
2218
|
+
var MAX_LENGTH = 2048;
|
|
2219
|
+
var readFileSync = (path17) => {
|
|
2220
|
+
const fd = fs12.openSync(path17, "r");
|
|
2221
|
+
const buffer = Buffer.alloc(MAX_LENGTH);
|
|
2222
|
+
const bytesRead = fs12.readSync(fd, buffer, 0, MAX_LENGTH, 0);
|
|
2223
|
+
fs12.close(fd, () => {
|
|
2224
|
+
});
|
|
2225
|
+
return buffer.subarray(0, bytesRead);
|
|
2226
|
+
};
|
|
2227
|
+
var readFile = (path17) => new Promise((resolve, reject) => {
|
|
2228
|
+
fs12.open(path17, "r", (err, fd) => {
|
|
2229
|
+
if (err) {
|
|
2230
|
+
reject(err);
|
|
2231
|
+
} else {
|
|
2232
|
+
const buffer = Buffer.alloc(MAX_LENGTH);
|
|
2233
|
+
fs12.read(fd, buffer, 0, MAX_LENGTH, 0, (_, bytesRead) => {
|
|
2234
|
+
resolve(buffer.subarray(0, bytesRead));
|
|
2235
|
+
fs12.close(fd, () => {
|
|
2236
|
+
});
|
|
2237
|
+
});
|
|
2238
|
+
}
|
|
2239
|
+
});
|
|
2240
|
+
});
|
|
2241
|
+
module.exports = {
|
|
2242
|
+
LDD_PATH,
|
|
2243
|
+
SELF_PATH,
|
|
2244
|
+
readFileSync,
|
|
2245
|
+
readFile
|
|
2246
|
+
};
|
|
2247
|
+
}
|
|
2248
|
+
});
|
|
1755
2249
|
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
2250
|
+
// node_modules/detect-libc/lib/elf.js
|
|
2251
|
+
var require_elf = __commonJS({
|
|
2252
|
+
"node_modules/detect-libc/lib/elf.js"(exports, module) {
|
|
2253
|
+
"use strict";
|
|
2254
|
+
var interpreterPath = (elf) => {
|
|
2255
|
+
if (elf.length < 64) {
|
|
2256
|
+
return null;
|
|
1759
2257
|
}
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
if (
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
2258
|
+
if (elf.readUInt32BE(0) !== 2135247942) {
|
|
2259
|
+
return null;
|
|
2260
|
+
}
|
|
2261
|
+
if (elf.readUInt8(4) !== 2) {
|
|
2262
|
+
return null;
|
|
2263
|
+
}
|
|
2264
|
+
if (elf.readUInt8(5) !== 1) {
|
|
2265
|
+
return null;
|
|
2266
|
+
}
|
|
2267
|
+
const offset = elf.readUInt32LE(32);
|
|
2268
|
+
const size = elf.readUInt16LE(54);
|
|
2269
|
+
const count = elf.readUInt16LE(56);
|
|
2270
|
+
for (let i = 0; i < count; i++) {
|
|
2271
|
+
const headerOffset = offset + i * size;
|
|
2272
|
+
const type = elf.readUInt32LE(headerOffset);
|
|
2273
|
+
if (type === 3) {
|
|
2274
|
+
const fileOffset = elf.readUInt32LE(headerOffset + 8);
|
|
2275
|
+
const fileSize = elf.readUInt32LE(headerOffset + 32);
|
|
2276
|
+
return elf.subarray(fileOffset, fileOffset + fileSize).toString().replace(/\0.*$/g, "");
|
|
2277
|
+
}
|
|
2278
|
+
}
|
|
2279
|
+
return null;
|
|
2280
|
+
};
|
|
2281
|
+
module.exports = {
|
|
2282
|
+
interpreterPath
|
|
2283
|
+
};
|
|
2284
|
+
}
|
|
2285
|
+
});
|
|
2286
|
+
|
|
2287
|
+
// node_modules/detect-libc/lib/detect-libc.js
|
|
2288
|
+
var require_detect_libc = __commonJS({
|
|
2289
|
+
"node_modules/detect-libc/lib/detect-libc.js"(exports, module) {
|
|
2290
|
+
"use strict";
|
|
2291
|
+
var childProcess = __require("child_process");
|
|
2292
|
+
var { isLinux, getReport } = require_process();
|
|
2293
|
+
var { LDD_PATH, SELF_PATH, readFile, readFileSync } = require_filesystem();
|
|
2294
|
+
var { interpreterPath } = require_elf();
|
|
2295
|
+
var cachedFamilyInterpreter;
|
|
2296
|
+
var cachedFamilyFilesystem;
|
|
2297
|
+
var cachedVersionFilesystem;
|
|
2298
|
+
var command = "getconf GNU_LIBC_VERSION 2>&1 || true; ldd --version 2>&1 || true";
|
|
2299
|
+
var commandOut = "";
|
|
2300
|
+
var safeCommand = () => {
|
|
2301
|
+
if (!commandOut) {
|
|
2302
|
+
return new Promise((resolve) => {
|
|
2303
|
+
childProcess.exec(command, (err, out) => {
|
|
2304
|
+
commandOut = err ? " " : out;
|
|
2305
|
+
resolve(commandOut);
|
|
2306
|
+
});
|
|
2307
|
+
});
|
|
2308
|
+
}
|
|
2309
|
+
return commandOut;
|
|
2310
|
+
};
|
|
2311
|
+
var safeCommandSync = () => {
|
|
2312
|
+
if (!commandOut) {
|
|
2313
|
+
try {
|
|
2314
|
+
commandOut = childProcess.execSync(command, { encoding: "utf8" });
|
|
2315
|
+
} catch (_err) {
|
|
2316
|
+
commandOut = " ";
|
|
2317
|
+
}
|
|
2318
|
+
}
|
|
2319
|
+
return commandOut;
|
|
2320
|
+
};
|
|
2321
|
+
var GLIBC = "glibc";
|
|
2322
|
+
var RE_GLIBC_VERSION = /LIBC[a-z0-9 \-).]*?(\d+\.\d+)/i;
|
|
2323
|
+
var MUSL = "musl";
|
|
2324
|
+
var isFileMusl = (f) => f.includes("libc.musl-") || f.includes("ld-musl-");
|
|
2325
|
+
var familyFromReport = () => {
|
|
2326
|
+
const report = getReport();
|
|
2327
|
+
if (report.header && report.header.glibcVersionRuntime) {
|
|
2328
|
+
return GLIBC;
|
|
2329
|
+
}
|
|
2330
|
+
if (Array.isArray(report.sharedObjects)) {
|
|
2331
|
+
if (report.sharedObjects.some(isFileMusl)) {
|
|
2332
|
+
return MUSL;
|
|
2333
|
+
}
|
|
2334
|
+
}
|
|
2335
|
+
return null;
|
|
2336
|
+
};
|
|
2337
|
+
var familyFromCommand = (out) => {
|
|
2338
|
+
const [getconf, ldd1] = out.split(/[\r\n]+/);
|
|
2339
|
+
if (getconf && getconf.includes(GLIBC)) {
|
|
2340
|
+
return GLIBC;
|
|
2341
|
+
}
|
|
2342
|
+
if (ldd1 && ldd1.includes(MUSL)) {
|
|
2343
|
+
return MUSL;
|
|
2344
|
+
}
|
|
2345
|
+
return null;
|
|
2346
|
+
};
|
|
2347
|
+
var familyFromInterpreterPath = (path17) => {
|
|
2348
|
+
if (path17) {
|
|
2349
|
+
if (path17.includes("/ld-musl-")) {
|
|
2350
|
+
return MUSL;
|
|
2351
|
+
} else if (path17.includes("/ld-linux-")) {
|
|
2352
|
+
return GLIBC;
|
|
2353
|
+
}
|
|
2354
|
+
}
|
|
2355
|
+
return null;
|
|
2356
|
+
};
|
|
2357
|
+
var getFamilyFromLddContent = (content) => {
|
|
2358
|
+
content = content.toString();
|
|
2359
|
+
if (content.includes("musl")) {
|
|
2360
|
+
return MUSL;
|
|
2361
|
+
}
|
|
2362
|
+
if (content.includes("GNU C Library")) {
|
|
2363
|
+
return GLIBC;
|
|
2364
|
+
}
|
|
2365
|
+
return null;
|
|
2366
|
+
};
|
|
2367
|
+
var familyFromFilesystem = async () => {
|
|
2368
|
+
if (cachedFamilyFilesystem !== void 0) {
|
|
2369
|
+
return cachedFamilyFilesystem;
|
|
2370
|
+
}
|
|
2371
|
+
cachedFamilyFilesystem = null;
|
|
2372
|
+
try {
|
|
2373
|
+
const lddContent = await readFile(LDD_PATH);
|
|
2374
|
+
cachedFamilyFilesystem = getFamilyFromLddContent(lddContent);
|
|
2375
|
+
} catch (e) {
|
|
2376
|
+
}
|
|
2377
|
+
return cachedFamilyFilesystem;
|
|
2378
|
+
};
|
|
2379
|
+
var familyFromFilesystemSync = () => {
|
|
2380
|
+
if (cachedFamilyFilesystem !== void 0) {
|
|
2381
|
+
return cachedFamilyFilesystem;
|
|
2382
|
+
}
|
|
2383
|
+
cachedFamilyFilesystem = null;
|
|
2384
|
+
try {
|
|
2385
|
+
const lddContent = readFileSync(LDD_PATH);
|
|
2386
|
+
cachedFamilyFilesystem = getFamilyFromLddContent(lddContent);
|
|
2387
|
+
} catch (e) {
|
|
2388
|
+
}
|
|
2389
|
+
return cachedFamilyFilesystem;
|
|
2390
|
+
};
|
|
2391
|
+
var familyFromInterpreter = async () => {
|
|
2392
|
+
if (cachedFamilyInterpreter !== void 0) {
|
|
2393
|
+
return cachedFamilyInterpreter;
|
|
2394
|
+
}
|
|
2395
|
+
cachedFamilyInterpreter = null;
|
|
2396
|
+
try {
|
|
2397
|
+
const selfContent = await readFile(SELF_PATH);
|
|
2398
|
+
const path17 = interpreterPath(selfContent);
|
|
2399
|
+
cachedFamilyInterpreter = familyFromInterpreterPath(path17);
|
|
2400
|
+
} catch (e) {
|
|
2401
|
+
}
|
|
2402
|
+
return cachedFamilyInterpreter;
|
|
2403
|
+
};
|
|
2404
|
+
var familyFromInterpreterSync = () => {
|
|
2405
|
+
if (cachedFamilyInterpreter !== void 0) {
|
|
2406
|
+
return cachedFamilyInterpreter;
|
|
2407
|
+
}
|
|
2408
|
+
cachedFamilyInterpreter = null;
|
|
2409
|
+
try {
|
|
2410
|
+
const selfContent = readFileSync(SELF_PATH);
|
|
2411
|
+
const path17 = interpreterPath(selfContent);
|
|
2412
|
+
cachedFamilyInterpreter = familyFromInterpreterPath(path17);
|
|
2413
|
+
} catch (e) {
|
|
2414
|
+
}
|
|
2415
|
+
return cachedFamilyInterpreter;
|
|
2416
|
+
};
|
|
2417
|
+
var family = async () => {
|
|
2418
|
+
let family2 = null;
|
|
2419
|
+
if (isLinux()) {
|
|
2420
|
+
family2 = await familyFromInterpreter();
|
|
2421
|
+
if (!family2) {
|
|
2422
|
+
family2 = await familyFromFilesystem();
|
|
2423
|
+
if (!family2) {
|
|
2424
|
+
family2 = familyFromReport();
|
|
2425
|
+
}
|
|
2426
|
+
if (!family2) {
|
|
2427
|
+
const out = await safeCommand();
|
|
2428
|
+
family2 = familyFromCommand(out);
|
|
2429
|
+
}
|
|
2430
|
+
}
|
|
2431
|
+
}
|
|
2432
|
+
return family2;
|
|
2433
|
+
};
|
|
2434
|
+
var familySync = () => {
|
|
2435
|
+
let family2 = null;
|
|
2436
|
+
if (isLinux()) {
|
|
2437
|
+
family2 = familyFromInterpreterSync();
|
|
2438
|
+
if (!family2) {
|
|
2439
|
+
family2 = familyFromFilesystemSync();
|
|
2440
|
+
if (!family2) {
|
|
2441
|
+
family2 = familyFromReport();
|
|
2442
|
+
}
|
|
2443
|
+
if (!family2) {
|
|
2444
|
+
const out = safeCommandSync();
|
|
2445
|
+
family2 = familyFromCommand(out);
|
|
2446
|
+
}
|
|
2447
|
+
}
|
|
2448
|
+
}
|
|
2449
|
+
return family2;
|
|
2450
|
+
};
|
|
2451
|
+
var isNonGlibcLinux = async () => isLinux() && await family() !== GLIBC;
|
|
2452
|
+
var isNonGlibcLinuxSync = () => isLinux() && familySync() !== GLIBC;
|
|
2453
|
+
var versionFromFilesystem = async () => {
|
|
2454
|
+
if (cachedVersionFilesystem !== void 0) {
|
|
2455
|
+
return cachedVersionFilesystem;
|
|
2456
|
+
}
|
|
2457
|
+
cachedVersionFilesystem = null;
|
|
2458
|
+
try {
|
|
2459
|
+
const lddContent = await readFile(LDD_PATH);
|
|
2460
|
+
const versionMatch = lddContent.match(RE_GLIBC_VERSION);
|
|
2461
|
+
if (versionMatch) {
|
|
2462
|
+
cachedVersionFilesystem = versionMatch[1];
|
|
2463
|
+
}
|
|
2464
|
+
} catch (e) {
|
|
2465
|
+
}
|
|
2466
|
+
return cachedVersionFilesystem;
|
|
2467
|
+
};
|
|
2468
|
+
var versionFromFilesystemSync = () => {
|
|
2469
|
+
if (cachedVersionFilesystem !== void 0) {
|
|
2470
|
+
return cachedVersionFilesystem;
|
|
2471
|
+
}
|
|
2472
|
+
cachedVersionFilesystem = null;
|
|
2473
|
+
try {
|
|
2474
|
+
const lddContent = readFileSync(LDD_PATH);
|
|
2475
|
+
const versionMatch = lddContent.match(RE_GLIBC_VERSION);
|
|
2476
|
+
if (versionMatch) {
|
|
2477
|
+
cachedVersionFilesystem = versionMatch[1];
|
|
2478
|
+
}
|
|
2479
|
+
} catch (e) {
|
|
2480
|
+
}
|
|
2481
|
+
return cachedVersionFilesystem;
|
|
2482
|
+
};
|
|
2483
|
+
var versionFromReport = () => {
|
|
2484
|
+
const report = getReport();
|
|
2485
|
+
if (report.header && report.header.glibcVersionRuntime) {
|
|
2486
|
+
return report.header.glibcVersionRuntime;
|
|
2487
|
+
}
|
|
2488
|
+
return null;
|
|
2489
|
+
};
|
|
2490
|
+
var versionSuffix = (s) => s.trim().split(/\s+/)[1];
|
|
2491
|
+
var versionFromCommand = (out) => {
|
|
2492
|
+
const [getconf, ldd1, ldd2] = out.split(/[\r\n]+/);
|
|
2493
|
+
if (getconf && getconf.includes(GLIBC)) {
|
|
2494
|
+
return versionSuffix(getconf);
|
|
2495
|
+
}
|
|
2496
|
+
if (ldd1 && ldd2 && ldd1.includes(MUSL)) {
|
|
2497
|
+
return versionSuffix(ldd2);
|
|
2498
|
+
}
|
|
2499
|
+
return null;
|
|
2500
|
+
};
|
|
2501
|
+
var version = async () => {
|
|
2502
|
+
let version2 = null;
|
|
2503
|
+
if (isLinux()) {
|
|
2504
|
+
version2 = await versionFromFilesystem();
|
|
2505
|
+
if (!version2) {
|
|
2506
|
+
version2 = versionFromReport();
|
|
2507
|
+
}
|
|
2508
|
+
if (!version2) {
|
|
2509
|
+
const out = await safeCommand();
|
|
2510
|
+
version2 = versionFromCommand(out);
|
|
2511
|
+
}
|
|
2512
|
+
}
|
|
2513
|
+
return version2;
|
|
2514
|
+
};
|
|
2515
|
+
var versionSync = () => {
|
|
2516
|
+
let version2 = null;
|
|
2517
|
+
if (isLinux()) {
|
|
2518
|
+
version2 = versionFromFilesystemSync();
|
|
2519
|
+
if (!version2) {
|
|
2520
|
+
version2 = versionFromReport();
|
|
2521
|
+
}
|
|
2522
|
+
if (!version2) {
|
|
2523
|
+
const out = safeCommandSync();
|
|
2524
|
+
version2 = versionFromCommand(out);
|
|
2525
|
+
}
|
|
2526
|
+
}
|
|
2527
|
+
return version2;
|
|
2528
|
+
};
|
|
2529
|
+
module.exports = {
|
|
2530
|
+
GLIBC,
|
|
2531
|
+
MUSL,
|
|
2532
|
+
family,
|
|
2533
|
+
familySync,
|
|
2534
|
+
isNonGlibcLinux,
|
|
2535
|
+
isNonGlibcLinuxSync,
|
|
2536
|
+
version,
|
|
2537
|
+
versionSync
|
|
2538
|
+
};
|
|
2539
|
+
}
|
|
2540
|
+
});
|
|
2541
|
+
|
|
2542
|
+
// node_modules/lightningcss/node/browserslistToTargets.js
|
|
2543
|
+
var require_browserslistToTargets = __commonJS({
|
|
2544
|
+
"node_modules/lightningcss/node/browserslistToTargets.js"(exports, module) {
|
|
2545
|
+
"use strict";
|
|
2546
|
+
var BROWSER_MAPPING = {
|
|
2547
|
+
and_chr: "chrome",
|
|
2548
|
+
and_ff: "firefox",
|
|
2549
|
+
ie_mob: "ie",
|
|
2550
|
+
op_mob: "opera",
|
|
2551
|
+
and_qq: null,
|
|
2552
|
+
and_uc: null,
|
|
2553
|
+
baidu: null,
|
|
2554
|
+
bb: null,
|
|
2555
|
+
kaios: null,
|
|
2556
|
+
op_mini: null
|
|
2557
|
+
};
|
|
2558
|
+
function browserslistToTargets2(browserslist) {
|
|
2559
|
+
let targets = {};
|
|
2560
|
+
for (let browser of browserslist) {
|
|
2561
|
+
let [name, v] = browser.split(" ");
|
|
2562
|
+
if (BROWSER_MAPPING[name] === null) {
|
|
2563
|
+
continue;
|
|
2564
|
+
}
|
|
2565
|
+
let version = parseVersion(v);
|
|
2566
|
+
if (version == null) {
|
|
2567
|
+
continue;
|
|
2568
|
+
}
|
|
2569
|
+
if (targets[name] == null || version < targets[name]) {
|
|
2570
|
+
targets[name] = version;
|
|
2571
|
+
}
|
|
2572
|
+
}
|
|
2573
|
+
return targets;
|
|
2574
|
+
}
|
|
2575
|
+
function parseVersion(version) {
|
|
2576
|
+
let [major, minor = 0, patch = 0] = version.split("-")[0].split(".").map((v) => parseInt(v, 10));
|
|
2577
|
+
if (isNaN(major) || isNaN(minor) || isNaN(patch)) {
|
|
2578
|
+
return null;
|
|
2579
|
+
}
|
|
2580
|
+
return major << 16 | minor << 8 | patch;
|
|
2581
|
+
}
|
|
2582
|
+
module.exports = browserslistToTargets2;
|
|
2583
|
+
}
|
|
2584
|
+
});
|
|
2585
|
+
|
|
2586
|
+
// node_modules/lightningcss/node/composeVisitors.js
|
|
2587
|
+
var require_composeVisitors = __commonJS({
|
|
2588
|
+
"node_modules/lightningcss/node/composeVisitors.js"(exports, module) {
|
|
2589
|
+
"use strict";
|
|
2590
|
+
function composeVisitors2(visitors) {
|
|
2591
|
+
if (visitors.length === 1) {
|
|
2592
|
+
return visitors[0];
|
|
2593
|
+
}
|
|
2594
|
+
if (visitors.some((v) => typeof v === "function")) {
|
|
2595
|
+
return (opts) => {
|
|
2596
|
+
let v = visitors.map((v2) => typeof v2 === "function" ? v2(opts) : v2);
|
|
2597
|
+
return composeVisitors2(v);
|
|
2598
|
+
};
|
|
2599
|
+
}
|
|
2600
|
+
let res = {};
|
|
2601
|
+
composeSimpleVisitors(res, visitors, "StyleSheet");
|
|
2602
|
+
composeSimpleVisitors(res, visitors, "StyleSheetExit");
|
|
2603
|
+
composeObjectVisitors(res, visitors, "Rule", ruleVisitor, wrapCustomAndUnknownAtRule);
|
|
2604
|
+
composeObjectVisitors(res, visitors, "RuleExit", ruleVisitor, wrapCustomAndUnknownAtRule);
|
|
2605
|
+
composeObjectVisitors(res, visitors, "Declaration", declarationVisitor, wrapCustomProperty);
|
|
2606
|
+
composeObjectVisitors(res, visitors, "DeclarationExit", declarationVisitor, wrapCustomProperty);
|
|
2607
|
+
composeSimpleVisitors(res, visitors, "Url");
|
|
2608
|
+
composeSimpleVisitors(res, visitors, "Color");
|
|
2609
|
+
composeSimpleVisitors(res, visitors, "Image");
|
|
2610
|
+
composeSimpleVisitors(res, visitors, "ImageExit");
|
|
2611
|
+
composeSimpleVisitors(res, visitors, "Length");
|
|
2612
|
+
composeSimpleVisitors(res, visitors, "Angle");
|
|
2613
|
+
composeSimpleVisitors(res, visitors, "Ratio");
|
|
2614
|
+
composeSimpleVisitors(res, visitors, "Resolution");
|
|
2615
|
+
composeSimpleVisitors(res, visitors, "Time");
|
|
2616
|
+
composeSimpleVisitors(res, visitors, "CustomIdent");
|
|
2617
|
+
composeSimpleVisitors(res, visitors, "DashedIdent");
|
|
2618
|
+
composeArrayFunctions(res, visitors, "MediaQuery");
|
|
2619
|
+
composeArrayFunctions(res, visitors, "MediaQueryExit");
|
|
2620
|
+
composeSimpleVisitors(res, visitors, "SupportsCondition");
|
|
2621
|
+
composeSimpleVisitors(res, visitors, "SupportsConditionExit");
|
|
2622
|
+
composeArrayFunctions(res, visitors, "Selector");
|
|
2623
|
+
composeTokenVisitors(res, visitors, "Token", "token", false);
|
|
2624
|
+
composeTokenVisitors(res, visitors, "Function", "function", false);
|
|
2625
|
+
composeTokenVisitors(res, visitors, "FunctionExit", "function", true);
|
|
2626
|
+
composeTokenVisitors(res, visitors, "Variable", "var", false);
|
|
2627
|
+
composeTokenVisitors(res, visitors, "VariableExit", "var", true);
|
|
2628
|
+
composeTokenVisitors(res, visitors, "EnvironmentVariable", "env", false);
|
|
2629
|
+
composeTokenVisitors(res, visitors, "EnvironmentVariableExit", "env", true);
|
|
2630
|
+
return res;
|
|
2631
|
+
}
|
|
2632
|
+
module.exports = composeVisitors2;
|
|
2633
|
+
function wrapCustomAndUnknownAtRule(k, f) {
|
|
2634
|
+
if (k === "unknown") {
|
|
2635
|
+
return ((value) => f({ type: "unknown", value }));
|
|
2636
|
+
}
|
|
2637
|
+
if (k === "custom") {
|
|
2638
|
+
return ((value) => f({ type: "custom", value }));
|
|
2639
|
+
}
|
|
2640
|
+
return f;
|
|
2641
|
+
}
|
|
2642
|
+
function wrapCustomProperty(k, f) {
|
|
2643
|
+
return k === "custom" ? ((value) => f({ property: "custom", value })) : f;
|
|
2644
|
+
}
|
|
2645
|
+
function ruleVisitor(f, item) {
|
|
2646
|
+
if (typeof f === "object") {
|
|
2647
|
+
if (item.type === "unknown") {
|
|
2648
|
+
let v = f.unknown;
|
|
2649
|
+
if (typeof v === "object") {
|
|
2650
|
+
v = v[item.value.name];
|
|
2651
|
+
}
|
|
2652
|
+
return v?.(item.value);
|
|
2653
|
+
}
|
|
2654
|
+
if (item.type === "custom") {
|
|
2655
|
+
let v = f.custom;
|
|
2656
|
+
if (typeof v === "object") {
|
|
2657
|
+
v = v[item.value.name];
|
|
2658
|
+
}
|
|
2659
|
+
return v?.(item.value);
|
|
2660
|
+
}
|
|
2661
|
+
return f[item.type]?.(item);
|
|
2662
|
+
}
|
|
2663
|
+
return f?.(item);
|
|
2664
|
+
}
|
|
2665
|
+
function declarationVisitor(f, item) {
|
|
2666
|
+
if (typeof f === "object") {
|
|
2667
|
+
let name = item.property;
|
|
2668
|
+
if (item.property === "unparsed") {
|
|
2669
|
+
name = item.value.propertyId.property;
|
|
2670
|
+
} else if (item.property === "custom") {
|
|
2671
|
+
let v = f.custom;
|
|
2672
|
+
if (typeof v === "object") {
|
|
2673
|
+
v = v[item.value.name];
|
|
2674
|
+
}
|
|
2675
|
+
return v?.(item.value);
|
|
2676
|
+
}
|
|
2677
|
+
return f[name]?.(item);
|
|
2678
|
+
}
|
|
2679
|
+
return f?.(item);
|
|
2680
|
+
}
|
|
2681
|
+
function extractObjectsOrFunctions(visitors, key) {
|
|
2682
|
+
let values = [];
|
|
2683
|
+
let hasFunction = false;
|
|
2684
|
+
let allKeys = /* @__PURE__ */ new Set();
|
|
2685
|
+
for (let visitor of visitors) {
|
|
2686
|
+
let v = visitor[key];
|
|
2687
|
+
if (v) {
|
|
2688
|
+
if (typeof v === "function") {
|
|
2689
|
+
hasFunction = true;
|
|
2690
|
+
} else {
|
|
2691
|
+
for (let key2 in v) {
|
|
2692
|
+
allKeys.add(key2);
|
|
2693
|
+
}
|
|
2694
|
+
}
|
|
2695
|
+
values.push(v);
|
|
2696
|
+
}
|
|
2697
|
+
}
|
|
2698
|
+
return [values, hasFunction, allKeys];
|
|
2699
|
+
}
|
|
2700
|
+
function composeObjectVisitors(res, visitors, key, apply, wrapKey) {
|
|
2701
|
+
let [values, hasFunction, allKeys] = extractObjectsOrFunctions(visitors, key);
|
|
2702
|
+
if (values.length === 0) {
|
|
2703
|
+
return;
|
|
2704
|
+
}
|
|
2705
|
+
if (values.length === 1) {
|
|
2706
|
+
res[key] = values[0];
|
|
2707
|
+
return;
|
|
2708
|
+
}
|
|
2709
|
+
let f = createArrayVisitor(visitors, (visitor, item) => apply(visitor[key], item));
|
|
2710
|
+
if (hasFunction) {
|
|
2711
|
+
res[key] = f;
|
|
2712
|
+
} else {
|
|
2713
|
+
let v = {};
|
|
2714
|
+
for (let k of allKeys) {
|
|
2715
|
+
v[k] = wrapKey(k, f);
|
|
2716
|
+
}
|
|
2717
|
+
res[key] = v;
|
|
2718
|
+
}
|
|
2719
|
+
}
|
|
2720
|
+
function composeTokenVisitors(res, visitors, key, type, isExit) {
|
|
2721
|
+
let [values, hasFunction, allKeys] = extractObjectsOrFunctions(visitors, key);
|
|
2722
|
+
if (values.length === 0) {
|
|
2723
|
+
return;
|
|
2724
|
+
}
|
|
2725
|
+
if (values.length === 1) {
|
|
2726
|
+
res[key] = values[0];
|
|
2727
|
+
return;
|
|
2728
|
+
}
|
|
2729
|
+
let f = createTokenVisitor(visitors, type, isExit);
|
|
2730
|
+
if (hasFunction) {
|
|
2731
|
+
res[key] = f;
|
|
2732
|
+
} else {
|
|
2733
|
+
let v = {};
|
|
2734
|
+
for (let key2 of allKeys) {
|
|
2735
|
+
v[key2] = f;
|
|
2736
|
+
}
|
|
2737
|
+
res[key] = v;
|
|
2738
|
+
}
|
|
2739
|
+
}
|
|
2740
|
+
function createTokenVisitor(visitors, type, isExit) {
|
|
2741
|
+
let v = createArrayVisitor(visitors, (visitor, item) => {
|
|
2742
|
+
let f;
|
|
2743
|
+
switch (item.type) {
|
|
2744
|
+
case "token":
|
|
2745
|
+
f = visitor.Token;
|
|
2746
|
+
if (typeof f === "object") {
|
|
2747
|
+
f = f[item.value.type];
|
|
2748
|
+
}
|
|
2749
|
+
break;
|
|
2750
|
+
case "function":
|
|
2751
|
+
f = isExit ? visitor.FunctionExit : visitor.Function;
|
|
2752
|
+
if (typeof f === "object") {
|
|
2753
|
+
f = f[item.value.name];
|
|
2754
|
+
}
|
|
2755
|
+
break;
|
|
2756
|
+
case "var":
|
|
2757
|
+
f = isExit ? visitor.VariableExit : visitor.Variable;
|
|
2758
|
+
break;
|
|
2759
|
+
case "env":
|
|
2760
|
+
f = isExit ? visitor.EnvironmentVariableExit : visitor.EnvironmentVariable;
|
|
2761
|
+
if (typeof f === "object") {
|
|
2762
|
+
let name;
|
|
2763
|
+
switch (item.value.name.type) {
|
|
2764
|
+
case "ua":
|
|
2765
|
+
case "unknown":
|
|
2766
|
+
name = item.value.name.value;
|
|
2767
|
+
break;
|
|
2768
|
+
case "custom":
|
|
2769
|
+
name = item.value.name.ident;
|
|
2770
|
+
break;
|
|
2771
|
+
}
|
|
2772
|
+
f = f[name];
|
|
2773
|
+
}
|
|
2774
|
+
break;
|
|
2775
|
+
case "color":
|
|
2776
|
+
f = visitor.Color;
|
|
2777
|
+
break;
|
|
2778
|
+
case "url":
|
|
2779
|
+
f = visitor.Url;
|
|
2780
|
+
break;
|
|
2781
|
+
case "length":
|
|
2782
|
+
f = visitor.Length;
|
|
2783
|
+
break;
|
|
2784
|
+
case "angle":
|
|
2785
|
+
f = visitor.Angle;
|
|
2786
|
+
break;
|
|
2787
|
+
case "time":
|
|
2788
|
+
f = visitor.Time;
|
|
2789
|
+
break;
|
|
2790
|
+
case "resolution":
|
|
2791
|
+
f = visitor.Resolution;
|
|
2792
|
+
break;
|
|
2793
|
+
case "dashed-ident":
|
|
2794
|
+
f = visitor.DashedIdent;
|
|
2795
|
+
break;
|
|
2796
|
+
}
|
|
2797
|
+
if (!f) {
|
|
2798
|
+
return;
|
|
2799
|
+
}
|
|
2800
|
+
let res = f(item.value);
|
|
2801
|
+
switch (item.type) {
|
|
2802
|
+
case "color":
|
|
2803
|
+
case "url":
|
|
2804
|
+
case "length":
|
|
2805
|
+
case "angle":
|
|
2806
|
+
case "time":
|
|
2807
|
+
case "resolution":
|
|
2808
|
+
case "dashed-ident":
|
|
2809
|
+
if (Array.isArray(res)) {
|
|
2810
|
+
res = res.map((value) => ({ type: item.type, value }));
|
|
2811
|
+
} else if (res) {
|
|
2812
|
+
res = { type: item.type, value: res };
|
|
2813
|
+
}
|
|
2814
|
+
break;
|
|
2815
|
+
}
|
|
2816
|
+
return res;
|
|
2817
|
+
});
|
|
2818
|
+
return (value) => v({ type, value });
|
|
2819
|
+
}
|
|
2820
|
+
function extractFunctions(visitors, key) {
|
|
2821
|
+
let functions = [];
|
|
2822
|
+
for (let visitor of visitors) {
|
|
2823
|
+
let f = visitor[key];
|
|
2824
|
+
if (f) {
|
|
2825
|
+
functions.push(f);
|
|
2826
|
+
}
|
|
2827
|
+
}
|
|
2828
|
+
return functions;
|
|
2829
|
+
}
|
|
2830
|
+
function composeSimpleVisitors(res, visitors, key) {
|
|
2831
|
+
let functions = extractFunctions(visitors, key);
|
|
2832
|
+
if (functions.length === 0) {
|
|
2833
|
+
return;
|
|
2834
|
+
}
|
|
2835
|
+
if (functions.length === 1) {
|
|
2836
|
+
res[key] = functions[0];
|
|
2837
|
+
return;
|
|
2838
|
+
}
|
|
2839
|
+
res[key] = (arg) => {
|
|
2840
|
+
let mutated = false;
|
|
2841
|
+
for (let f of functions) {
|
|
2842
|
+
let res2 = f(arg);
|
|
2843
|
+
if (res2) {
|
|
2844
|
+
arg = res2;
|
|
2845
|
+
mutated = true;
|
|
2846
|
+
}
|
|
2847
|
+
}
|
|
2848
|
+
return mutated ? arg : void 0;
|
|
2849
|
+
};
|
|
2850
|
+
}
|
|
2851
|
+
function composeArrayFunctions(res, visitors, key) {
|
|
2852
|
+
let functions = extractFunctions(visitors, key);
|
|
2853
|
+
if (functions.length === 0) {
|
|
2854
|
+
return;
|
|
2855
|
+
}
|
|
2856
|
+
if (functions.length === 1) {
|
|
2857
|
+
res[key] = functions[0];
|
|
2858
|
+
return;
|
|
2859
|
+
}
|
|
2860
|
+
res[key] = createArrayVisitor(functions, (f, item) => f(item));
|
|
2861
|
+
}
|
|
2862
|
+
function createArrayVisitor(visitors, apply) {
|
|
2863
|
+
let seen = new Bitset(visitors.length);
|
|
2864
|
+
return (arg) => {
|
|
2865
|
+
let arr = [arg];
|
|
2866
|
+
let mutated = false;
|
|
2867
|
+
seen.clear();
|
|
2868
|
+
for (let i = 0; i < arr.length; i++) {
|
|
2869
|
+
for (let v = 0; v < visitors.length && i < arr.length; ) {
|
|
2870
|
+
if (seen.get(v)) {
|
|
2871
|
+
v++;
|
|
2872
|
+
continue;
|
|
2873
|
+
}
|
|
2874
|
+
let item = arr[i];
|
|
2875
|
+
let visitor = visitors[v];
|
|
2876
|
+
let res = apply(visitor, item);
|
|
2877
|
+
if (Array.isArray(res)) {
|
|
2878
|
+
if (res.length === 0) {
|
|
2879
|
+
arr.splice(i, 1);
|
|
2880
|
+
} else if (res.length === 1) {
|
|
2881
|
+
arr[i] = res[0];
|
|
2882
|
+
} else {
|
|
2883
|
+
arr.splice(i, 1, ...res);
|
|
2884
|
+
}
|
|
2885
|
+
mutated = true;
|
|
2886
|
+
seen.set(v);
|
|
2887
|
+
v = 0;
|
|
2888
|
+
} else if (res) {
|
|
2889
|
+
arr[i] = res;
|
|
2890
|
+
mutated = true;
|
|
2891
|
+
seen.set(v);
|
|
2892
|
+
v = 0;
|
|
2893
|
+
} else {
|
|
2894
|
+
v++;
|
|
2895
|
+
}
|
|
2896
|
+
}
|
|
2897
|
+
}
|
|
2898
|
+
if (!mutated) {
|
|
2899
|
+
return;
|
|
2900
|
+
}
|
|
2901
|
+
return arr.length === 1 ? arr[0] : arr;
|
|
2902
|
+
};
|
|
2903
|
+
}
|
|
2904
|
+
var Bitset = class {
|
|
2905
|
+
constructor(maxBits = 32) {
|
|
2906
|
+
this.bits = 0;
|
|
2907
|
+
this.more = maxBits > 32 ? new Uint32Array(Math.ceil((maxBits - 32) / 32)) : null;
|
|
2908
|
+
}
|
|
2909
|
+
/** @param {number} bit */
|
|
2910
|
+
get(bit) {
|
|
2911
|
+
if (bit >= 32 && this.more) {
|
|
2912
|
+
let i = Math.floor((bit - 32) / 32);
|
|
2913
|
+
let b = bit % 32;
|
|
2914
|
+
return Boolean(this.more[i] & 1 << b);
|
|
2915
|
+
} else {
|
|
2916
|
+
return Boolean(this.bits & 1 << bit);
|
|
2917
|
+
}
|
|
2918
|
+
}
|
|
2919
|
+
/** @param {number} bit */
|
|
2920
|
+
set(bit) {
|
|
2921
|
+
if (bit >= 32 && this.more) {
|
|
2922
|
+
let i = Math.floor((bit - 32) / 32);
|
|
2923
|
+
let b = bit % 32;
|
|
2924
|
+
this.more[i] |= 1 << b;
|
|
2925
|
+
} else {
|
|
2926
|
+
this.bits |= 1 << bit;
|
|
2927
|
+
}
|
|
2928
|
+
}
|
|
2929
|
+
clear() {
|
|
2930
|
+
this.bits = 0;
|
|
2931
|
+
if (this.more) {
|
|
2932
|
+
this.more.fill(0);
|
|
2933
|
+
}
|
|
2934
|
+
}
|
|
2935
|
+
};
|
|
2936
|
+
}
|
|
2937
|
+
});
|
|
2938
|
+
|
|
2939
|
+
// node_modules/lightningcss/node/flags.js
|
|
2940
|
+
var require_flags = __commonJS({
|
|
2941
|
+
"node_modules/lightningcss/node/flags.js"(exports) {
|
|
2942
|
+
"use strict";
|
|
2943
|
+
exports.Features = {
|
|
2944
|
+
Nesting: 1,
|
|
2945
|
+
NotSelectorList: 2,
|
|
2946
|
+
DirSelector: 4,
|
|
2947
|
+
LangSelectorList: 8,
|
|
2948
|
+
IsSelector: 16,
|
|
2949
|
+
TextDecorationThicknessPercent: 32,
|
|
2950
|
+
MediaIntervalSyntax: 64,
|
|
2951
|
+
MediaRangeSyntax: 128,
|
|
2952
|
+
CustomMediaQueries: 256,
|
|
2953
|
+
ClampFunction: 512,
|
|
2954
|
+
ColorFunction: 1024,
|
|
2955
|
+
OklabColors: 2048,
|
|
2956
|
+
LabColors: 4096,
|
|
2957
|
+
P3Colors: 8192,
|
|
2958
|
+
HexAlphaColors: 16384,
|
|
2959
|
+
SpaceSeparatedColorNotation: 32768,
|
|
2960
|
+
FontFamilySystemUi: 65536,
|
|
2961
|
+
DoublePositionGradients: 131072,
|
|
2962
|
+
VendorPrefixes: 262144,
|
|
2963
|
+
LogicalProperties: 524288,
|
|
2964
|
+
LightDark: 1048576,
|
|
2965
|
+
Selectors: 31,
|
|
2966
|
+
MediaQueries: 448,
|
|
2967
|
+
Colors: 1113088
|
|
2968
|
+
};
|
|
2969
|
+
}
|
|
2970
|
+
});
|
|
2971
|
+
|
|
2972
|
+
// node_modules/lightningcss/node/index.js
|
|
2973
|
+
var require_node = __commonJS({
|
|
2974
|
+
"node_modules/lightningcss/node/index.js"(exports, module) {
|
|
2975
|
+
"use strict";
|
|
2976
|
+
init_();
|
|
2977
|
+
var parts = [process.platform, process.arch];
|
|
2978
|
+
if (process.platform === "linux") {
|
|
2979
|
+
const { MUSL, familySync } = require_detect_libc();
|
|
2980
|
+
const family = familySync();
|
|
2981
|
+
if (family === MUSL) {
|
|
2982
|
+
parts.push("musl");
|
|
2983
|
+
} else if (process.arch === "arm") {
|
|
2984
|
+
parts.push("gnueabihf");
|
|
2985
|
+
} else {
|
|
2986
|
+
parts.push("gnu");
|
|
2987
|
+
}
|
|
2988
|
+
} else if (process.platform === "win32") {
|
|
2989
|
+
parts.push("msvc");
|
|
2990
|
+
}
|
|
2991
|
+
var native;
|
|
2992
|
+
try {
|
|
2993
|
+
native = __require(`lightningcss-${parts.join("-")}`);
|
|
2994
|
+
} catch (err) {
|
|
2995
|
+
native = globRequire_lightningcss_node(`../lightningcss.${parts.join("-")}.node`);
|
|
2996
|
+
}
|
|
2997
|
+
module.exports.transform = wrap(native.transform);
|
|
2998
|
+
module.exports.transformStyleAttribute = wrap(native.transformStyleAttribute);
|
|
2999
|
+
module.exports.bundle = wrap(native.bundle);
|
|
3000
|
+
module.exports.bundleAsync = wrap(native.bundleAsync);
|
|
3001
|
+
module.exports.browserslistToTargets = require_browserslistToTargets();
|
|
3002
|
+
module.exports.composeVisitors = require_composeVisitors();
|
|
3003
|
+
module.exports.Features = require_flags().Features;
|
|
3004
|
+
function wrap(call) {
|
|
3005
|
+
return (options) => {
|
|
3006
|
+
if (typeof options.visitor === "function") {
|
|
3007
|
+
let deps = [];
|
|
3008
|
+
options.visitor = options.visitor({
|
|
3009
|
+
addDependency(dep) {
|
|
3010
|
+
deps.push(dep);
|
|
3011
|
+
}
|
|
3012
|
+
});
|
|
3013
|
+
let result = call(options);
|
|
3014
|
+
if (result instanceof Promise) {
|
|
3015
|
+
result = result.then((res) => {
|
|
3016
|
+
if (deps.length) {
|
|
3017
|
+
res.dependencies ??= [];
|
|
3018
|
+
res.dependencies.push(...deps);
|
|
3019
|
+
}
|
|
3020
|
+
return res;
|
|
3021
|
+
});
|
|
3022
|
+
} else if (deps.length) {
|
|
3023
|
+
result.dependencies ??= [];
|
|
3024
|
+
result.dependencies.push(...deps);
|
|
3025
|
+
}
|
|
3026
|
+
return result;
|
|
3027
|
+
} else {
|
|
3028
|
+
return call(options);
|
|
3029
|
+
}
|
|
3030
|
+
};
|
|
3031
|
+
}
|
|
3032
|
+
}
|
|
3033
|
+
});
|
|
3034
|
+
|
|
3035
|
+
// node_modules/lightningcss/node/index.mjs
|
|
3036
|
+
var node_exports = {};
|
|
3037
|
+
__export(node_exports, {
|
|
3038
|
+
Features: () => Features,
|
|
3039
|
+
browserslistToTargets: () => browserslistToTargets,
|
|
3040
|
+
bundle: () => bundle,
|
|
3041
|
+
bundleAsync: () => bundleAsync,
|
|
3042
|
+
composeVisitors: () => composeVisitors,
|
|
3043
|
+
transform: () => transform,
|
|
3044
|
+
transformStyleAttribute: () => transformStyleAttribute
|
|
3045
|
+
});
|
|
3046
|
+
var import_index, transform, transformStyleAttribute, bundle, bundleAsync, browserslistToTargets, composeVisitors, Features;
|
|
3047
|
+
var init_node = __esm({
|
|
3048
|
+
"node_modules/lightningcss/node/index.mjs"() {
|
|
3049
|
+
"use strict";
|
|
3050
|
+
import_index = __toESM(require_node(), 1);
|
|
3051
|
+
({ transform, transformStyleAttribute, bundle, bundleAsync, browserslistToTargets, composeVisitors, Features } = import_index.default);
|
|
3052
|
+
}
|
|
3053
|
+
});
|
|
3054
|
+
|
|
3055
|
+
// src/core/css-engine.ts
|
|
3056
|
+
function createCssEngine() {
|
|
3057
|
+
return {
|
|
3058
|
+
styles: /* @__PURE__ */ new Map(),
|
|
3059
|
+
entryCss: /* @__PURE__ */ new Map(),
|
|
3060
|
+
allCss: [],
|
|
3061
|
+
pendingSingle: [],
|
|
3062
|
+
singleFileName: null
|
|
3063
|
+
};
|
|
3064
|
+
}
|
|
3065
|
+
function normalizeCssModuleId(id) {
|
|
3066
|
+
return id.startsWith("\0") ? id.slice(1) : id;
|
|
3067
|
+
}
|
|
3068
|
+
async function minifyCss(css, config) {
|
|
3069
|
+
if (lightningCss === void 0) {
|
|
3070
|
+
try {
|
|
3071
|
+
lightningCss = await Promise.resolve().then(() => (init_node(), node_exports));
|
|
3072
|
+
} catch {
|
|
3073
|
+
lightningCss = null;
|
|
3074
|
+
debug2?.("lightningcss unavailable, falling back to regex minifier");
|
|
3075
|
+
}
|
|
3076
|
+
}
|
|
3077
|
+
if (lightningCss) {
|
|
3078
|
+
try {
|
|
3079
|
+
const result = lightningCss.transform({
|
|
3080
|
+
filename: "bundle.css",
|
|
3081
|
+
code: Buffer.from(css),
|
|
3082
|
+
minify: true,
|
|
3083
|
+
// 不展开 @import(Tailwind 已 flatten;裸 @import 保留原样交给浏览器)
|
|
3084
|
+
errorRecovery: true
|
|
3085
|
+
});
|
|
3086
|
+
for (const w of result.warnings ?? []) {
|
|
3087
|
+
config.logger.warnOnce(`[nasti:css] ${w.message}`);
|
|
3088
|
+
}
|
|
3089
|
+
return result.code.toString();
|
|
3090
|
+
} catch (err) {
|
|
3091
|
+
config.logger.warnOnce(
|
|
3092
|
+
`[nasti:css] Lightning CSS minify failed (${err.message}), emitting unminified CSS`
|
|
3093
|
+
);
|
|
3094
|
+
return css;
|
|
3095
|
+
}
|
|
3096
|
+
}
|
|
3097
|
+
return fallbackMinify(css);
|
|
3098
|
+
}
|
|
3099
|
+
function fallbackMinify(css) {
|
|
3100
|
+
return css.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\s*([{}:;,])\s*/g, "$1").replace(/;}/g, "}").replace(/\s+/g, " ").trim();
|
|
3101
|
+
}
|
|
3102
|
+
var debug2, lightningCss;
|
|
3103
|
+
var init_css_engine = __esm({
|
|
3104
|
+
"src/core/css-engine.ts"() {
|
|
3105
|
+
"use strict";
|
|
3106
|
+
init_debug();
|
|
3107
|
+
debug2 = createDebugger("nasti:css");
|
|
3108
|
+
}
|
|
3109
|
+
});
|
|
3110
|
+
|
|
3111
|
+
// src/plugins/tailwind.ts
|
|
3112
|
+
import path7 from "path";
|
|
3113
|
+
import { createRequire as createRequire3 } from "module";
|
|
3114
|
+
import { pathToFileURL as pathToFileURL3 } from "url";
|
|
3115
|
+
function hasTailwindDirectives(css) {
|
|
3116
|
+
const withoutBlockComments = css.replace(/\/\*[\s\S]*?\*\//g, "");
|
|
3117
|
+
const withoutLineComments = withoutBlockComments.replace(/\/\/.*$/gm, "");
|
|
3118
|
+
return TAILWIND_DIRECTIVE_RE.test(withoutLineComments);
|
|
3119
|
+
}
|
|
3120
|
+
async function loadTailwind(projectRoot) {
|
|
3121
|
+
if (cached && cachedRoot === projectRoot) return cached;
|
|
3122
|
+
const req = createRequire3(path7.join(projectRoot, "package.json"));
|
|
3123
|
+
let nodePath;
|
|
3124
|
+
let oxidePath;
|
|
3125
|
+
try {
|
|
3126
|
+
nodePath = req.resolve("@tailwindcss/node");
|
|
3127
|
+
oxidePath = req.resolve("@tailwindcss/oxide");
|
|
3128
|
+
} catch {
|
|
3129
|
+
throw new Error(
|
|
3130
|
+
"[nasti] CSS contains Tailwind v4 directives but `@tailwindcss/node` and/or `@tailwindcss/oxide` are not installed in this project. Install them with: npm i -D tailwindcss @tailwindcss/node @tailwindcss/oxide"
|
|
3131
|
+
);
|
|
3132
|
+
}
|
|
3133
|
+
const node = await import(pathToFileURL3(nodePath).href);
|
|
3134
|
+
const oxide = await import(pathToFileURL3(oxidePath).href);
|
|
3135
|
+
cached = { node, oxide };
|
|
3136
|
+
cachedRoot = projectRoot;
|
|
3137
|
+
return cached;
|
|
3138
|
+
}
|
|
3139
|
+
async function compileTailwind(css, fromFile, projectRoot) {
|
|
3140
|
+
const { node, oxide } = await loadTailwind(projectRoot);
|
|
3141
|
+
const dependencies = [];
|
|
3142
|
+
const compiler2 = await node.compile(css, {
|
|
3143
|
+
base: path7.dirname(fromFile),
|
|
3144
|
+
from: fromFile,
|
|
3145
|
+
onDependency: (p) => dependencies.push(p)
|
|
3146
|
+
});
|
|
3147
|
+
const scanner = new oxide.Scanner({ sources: compiler2.sources });
|
|
3148
|
+
const candidates = scanner.scan();
|
|
3149
|
+
return {
|
|
3150
|
+
css: compiler2.build(candidates),
|
|
3151
|
+
dependencies: [...dependencies, ...scanner.files]
|
|
3152
|
+
};
|
|
3153
|
+
}
|
|
3154
|
+
var TAILWIND_DIRECTIVE_RE, cached, cachedRoot;
|
|
3155
|
+
var init_tailwind = __esm({
|
|
3156
|
+
"src/plugins/tailwind.ts"() {
|
|
3157
|
+
"use strict";
|
|
3158
|
+
TAILWIND_DIRECTIVE_RE = /@(?:import\s+["']tailwindcss(?:\b|\/)|tailwind\b|theme\b|apply\b|plugin\b|source\b|utility\b|variant\b|custom-variant\b|reference\b)/;
|
|
3159
|
+
cached = null;
|
|
3160
|
+
cachedRoot = null;
|
|
3161
|
+
}
|
|
3162
|
+
});
|
|
3163
|
+
|
|
3164
|
+
// src/plugins/css.ts
|
|
3165
|
+
import path8 from "path";
|
|
3166
|
+
function cssPlugin(config, engine, consumer = "client") {
|
|
3167
|
+
return {
|
|
3168
|
+
name: "nasti:css",
|
|
3169
|
+
resolveId(source) {
|
|
3170
|
+
if (source.endsWith(".css")) return null;
|
|
3171
|
+
return null;
|
|
3172
|
+
},
|
|
3173
|
+
async transform(code, id) {
|
|
3174
|
+
const [file, query = ""] = id.split("?", 2);
|
|
3175
|
+
const isCssRequest = file.endsWith(".css") || /\.css$/.test(id);
|
|
3176
|
+
if (!isCssRequest) return null;
|
|
3177
|
+
if (query === "raw" || query === "url") return null;
|
|
3178
|
+
let cssSource = code;
|
|
3179
|
+
if (hasTailwindDirectives(code)) {
|
|
3180
|
+
const compiled = await compileTailwind(code, id, config.root);
|
|
3181
|
+
cssSource = compiled.css;
|
|
3182
|
+
}
|
|
3183
|
+
const rewritten = rewriteCssUrls(cssSource, file, config.root);
|
|
3184
|
+
const escaped = JSON.stringify(rewritten);
|
|
3185
|
+
if (query === "inline") {
|
|
3186
|
+
return { code: `export default ${escaped};
|
|
3187
|
+
`, moduleType: "js" };
|
|
3188
|
+
}
|
|
3189
|
+
if (consumer === "server") {
|
|
3190
|
+
return { code: `export default ${escaped};
|
|
3191
|
+
`, moduleType: "js" };
|
|
3192
|
+
}
|
|
3193
|
+
if (config.command === "serve") {
|
|
3194
|
+
return {
|
|
3195
|
+
code: `
|
|
3196
|
+
const css = ${escaped};
|
|
3197
|
+
const __nasti_css_id__ = ${JSON.stringify(id)};
|
|
3198
|
+
const __nasti_existing__ = document.querySelector('style[data-nasti-css=' + JSON.stringify(__nasti_css_id__) + ']');
|
|
3199
|
+
if (__nasti_existing__) __nasti_existing__.remove();
|
|
3200
|
+
const style = document.createElement('style');
|
|
3201
|
+
style.setAttribute('data-nasti-css', __nasti_css_id__);
|
|
3202
|
+
style.textContent = css;
|
|
3203
|
+
document.head.appendChild(style);
|
|
3204
|
+
|
|
3205
|
+
// HMR\uFF08prune \u5728 bundled \u6A21\u5F0F\u7684 rolldown hot context \u4E0A\u4E0D\u5B58\u5728\uFF0C\u987B\u5B88\u536B\uFF09
|
|
3206
|
+
if (import.meta.hot) {
|
|
3207
|
+
import.meta.hot.accept();
|
|
3208
|
+
if (import.meta.hot.prune) {
|
|
3209
|
+
import.meta.hot.prune(() => {
|
|
3210
|
+
style.remove();
|
|
3211
|
+
});
|
|
3212
|
+
}
|
|
3213
|
+
}
|
|
3214
|
+
|
|
3215
|
+
export default css;
|
|
3216
|
+
`,
|
|
3217
|
+
// bundled dev(DevEngine)下该模块会进 Rolldown:不标 js 会按 .css
|
|
3218
|
+
// 扩展名走 CSS 管线触发 #4271 报错;unbundled 中间件忽略此字段
|
|
1779
3219
|
moduleType: "js"
|
|
1780
3220
|
};
|
|
1781
3221
|
}
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
3222
|
+
if (engine) {
|
|
3223
|
+
engine.styles.set(normalizeCssModuleId(id), rewritten);
|
|
3224
|
+
return {
|
|
3225
|
+
code: `export default '';
|
|
3226
|
+
`,
|
|
3227
|
+
moduleType: "js",
|
|
3228
|
+
// 防止空 stub 被 tree-shake 出 chunk.moduleIds(css-post 靠它定位)
|
|
3229
|
+
moduleSideEffects: "no-treeshake"
|
|
3230
|
+
};
|
|
3231
|
+
}
|
|
3232
|
+
const cssConfig = config.build.css || {};
|
|
3233
|
+
const nonce = cssConfig.nonce;
|
|
3234
|
+
const nonceAttr = nonce ? `style.setAttribute('nonce', ${JSON.stringify(nonce)});` : "";
|
|
3235
|
+
return {
|
|
3236
|
+
code: `
|
|
3237
|
+
const css = ${escaped};
|
|
3238
|
+
const style = document.createElement('style');
|
|
3239
|
+
style.setAttribute('data-nasti-css', ${JSON.stringify(id)});
|
|
3240
|
+
${nonceAttr}
|
|
3241
|
+
style.textContent = css;
|
|
3242
|
+
document.head.appendChild(style);
|
|
3243
|
+
|
|
3244
|
+
export default css;
|
|
3245
|
+
`,
|
|
3246
|
+
moduleType: "js"
|
|
3247
|
+
};
|
|
3248
|
+
}
|
|
3249
|
+
};
|
|
3250
|
+
}
|
|
3251
|
+
function rewriteCssUrls(css, from, root) {
|
|
3252
|
+
return css.replace(/url\(\s*['"]?([^'")\s]+)['"]?\s*\)/g, (match, url) => {
|
|
3253
|
+
if (url.startsWith("/") || url.startsWith("data:") || url.startsWith("http")) {
|
|
3254
|
+
return match;
|
|
3255
|
+
}
|
|
3256
|
+
const resolved = path8.resolve(path8.dirname(from), url);
|
|
3257
|
+
const relative = "/" + path8.relative(root, resolved).replace(/\\/g, "/");
|
|
3258
|
+
return `url(${relative})`;
|
|
3259
|
+
});
|
|
3260
|
+
}
|
|
3261
|
+
var init_css = __esm({
|
|
3262
|
+
"src/plugins/css.ts"() {
|
|
3263
|
+
"use strict";
|
|
3264
|
+
init_css_engine();
|
|
3265
|
+
init_tailwind();
|
|
3266
|
+
}
|
|
3267
|
+
});
|
|
3268
|
+
|
|
3269
|
+
// src/plugins/css-post.ts
|
|
3270
|
+
function collectChunkCss(chunk, engine) {
|
|
3271
|
+
const ids = chunk.moduleIds ?? Object.keys(chunk.modules);
|
|
3272
|
+
let css = "";
|
|
3273
|
+
for (const id of ids) {
|
|
3274
|
+
const styles = engine.styles.get(normalizeCssModuleId(id));
|
|
3275
|
+
if (styles) css += styles + "\n";
|
|
3276
|
+
}
|
|
3277
|
+
return css;
|
|
3278
|
+
}
|
|
3279
|
+
function cssPostPlugin(config, engine) {
|
|
3280
|
+
return {
|
|
3281
|
+
name: "nasti:css-post",
|
|
3282
|
+
enforce: "post",
|
|
3283
|
+
async renderChunk(code, chunk) {
|
|
3284
|
+
const css = collectChunkCss(chunk, engine);
|
|
3285
|
+
if (!css) return null;
|
|
3286
|
+
if (!config.build.cssCodeSplit) {
|
|
3287
|
+
engine.pendingSingle.push(css);
|
|
3288
|
+
return null;
|
|
3289
|
+
}
|
|
3290
|
+
const finalCss = config.build.cssMinify ? await minifyCss(css, config) : css;
|
|
3291
|
+
const ref = this.emitFile({
|
|
3292
|
+
type: "asset",
|
|
3293
|
+
name: `${chunk.name}.css`,
|
|
3294
|
+
source: finalCss
|
|
3295
|
+
});
|
|
3296
|
+
const fileName = this.getFileName(ref);
|
|
3297
|
+
engine.allCss.push(fileName);
|
|
3298
|
+
if (chunk.isEntry) {
|
|
3299
|
+
const key = chunk.facadeModuleId ?? chunk.name;
|
|
3300
|
+
const existing = engine.entryCss.get(key) ?? [];
|
|
3301
|
+
existing.push(fileName);
|
|
3302
|
+
engine.entryCss.set(key, existing);
|
|
3303
|
+
return null;
|
|
3304
|
+
}
|
|
3305
|
+
const href = JSON.stringify(config.base + fileName);
|
|
3306
|
+
const snippet = `
|
|
3307
|
+
;(function(){try{var d=document,h=${href};if(!d.querySelector('link[data-nasti-css="'+h+'"]')){var l=d.createElement('link');l.rel='stylesheet';l.href=h;l.setAttribute('data-nasti-css',h);d.head.appendChild(l);}}catch(e){}})();`;
|
|
3308
|
+
return { code: code + snippet, map: null };
|
|
3309
|
+
},
|
|
3310
|
+
augmentChunkHash(chunk) {
|
|
3311
|
+
const css = collectChunkCss(chunk, engine);
|
|
3312
|
+
return css || void 0;
|
|
3313
|
+
},
|
|
3314
|
+
async generateBundle() {
|
|
3315
|
+
if (config.build.cssCodeSplit || engine.pendingSingle.length === 0) return;
|
|
3316
|
+
const merged = engine.pendingSingle.join("\n");
|
|
3317
|
+
const finalCss = config.build.cssMinify ? await minifyCss(merged, config) : merged;
|
|
3318
|
+
const ref = this.emitFile({ type: "asset", name: "style.css", source: finalCss });
|
|
3319
|
+
const fileName = this.getFileName(ref);
|
|
3320
|
+
engine.singleFileName = fileName;
|
|
3321
|
+
engine.allCss.push(fileName);
|
|
3322
|
+
}
|
|
3323
|
+
};
|
|
3324
|
+
}
|
|
3325
|
+
var init_css_post = __esm({
|
|
3326
|
+
"src/plugins/css-post.ts"() {
|
|
3327
|
+
"use strict";
|
|
3328
|
+
init_css_engine();
|
|
3329
|
+
}
|
|
3330
|
+
});
|
|
3331
|
+
|
|
3332
|
+
// src/plugins/assets.ts
|
|
3333
|
+
import path9 from "path";
|
|
3334
|
+
import fs7 from "fs";
|
|
3335
|
+
import crypto from "crypto";
|
|
3336
|
+
function assetsPlugin(config) {
|
|
3337
|
+
return {
|
|
3338
|
+
name: "nasti:assets",
|
|
3339
|
+
resolveId(source) {
|
|
3340
|
+
if (source.endsWith("?url") || source.endsWith("?raw")) {
|
|
3341
|
+
return source;
|
|
3342
|
+
}
|
|
3343
|
+
return null;
|
|
3344
|
+
},
|
|
3345
|
+
load(id) {
|
|
3346
|
+
const ext = path9.extname(id.replace(/\?.*$/, ""));
|
|
3347
|
+
if (id.endsWith("?raw")) {
|
|
3348
|
+
const file = id.slice(0, -4);
|
|
3349
|
+
if (fs7.existsSync(file)) {
|
|
3350
|
+
const content = fs7.readFileSync(file, "utf-8");
|
|
3351
|
+
return `export default ${JSON.stringify(content)}`;
|
|
3352
|
+
}
|
|
3353
|
+
}
|
|
3354
|
+
if (id.endsWith("?url") || ASSET_EXTENSIONS.has(ext)) {
|
|
3355
|
+
const file = id.replace(/\?.*$/, "");
|
|
3356
|
+
if (!fs7.existsSync(file)) return null;
|
|
3357
|
+
if (config.command === "serve") {
|
|
3358
|
+
const url = "/" + path9.relative(config.root, file);
|
|
3359
|
+
return `export default ${JSON.stringify(url)}`;
|
|
3360
|
+
}
|
|
3361
|
+
const content = fs7.readFileSync(file);
|
|
3362
|
+
const hash = crypto.createHash("sha256").update(content).digest("hex").slice(0, 8);
|
|
3363
|
+
const basename = path9.basename(file, ext);
|
|
3364
|
+
const hashedName = `${config.build.assetsDir}/${basename}.${hash}${ext}`;
|
|
3365
|
+
return `export default ${JSON.stringify(config.base + hashedName)}`;
|
|
3366
|
+
}
|
|
3367
|
+
return null;
|
|
3368
|
+
}
|
|
3369
|
+
};
|
|
3370
|
+
}
|
|
3371
|
+
var ASSET_EXTENSIONS;
|
|
3372
|
+
var init_assets = __esm({
|
|
3373
|
+
"src/plugins/assets.ts"() {
|
|
3374
|
+
"use strict";
|
|
3375
|
+
ASSET_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
3376
|
+
".png",
|
|
3377
|
+
".jpg",
|
|
3378
|
+
".jpeg",
|
|
3379
|
+
".gif",
|
|
3380
|
+
".svg",
|
|
3381
|
+
".ico",
|
|
3382
|
+
".webp",
|
|
3383
|
+
".avif",
|
|
3384
|
+
".mp4",
|
|
3385
|
+
".webm",
|
|
3386
|
+
".ogg",
|
|
3387
|
+
".mp3",
|
|
3388
|
+
".wav",
|
|
3389
|
+
".flac",
|
|
3390
|
+
".aac",
|
|
3391
|
+
".woff",
|
|
3392
|
+
".woff2",
|
|
3393
|
+
".eot",
|
|
3394
|
+
".ttf",
|
|
3395
|
+
".otf",
|
|
3396
|
+
".pdf",
|
|
3397
|
+
".txt"
|
|
3398
|
+
]);
|
|
3399
|
+
}
|
|
3400
|
+
});
|
|
3401
|
+
|
|
3402
|
+
// src/plugins/vue.ts
|
|
3403
|
+
import crypto2 from "crypto";
|
|
3404
|
+
async function loadVueCompiler() {
|
|
3405
|
+
if (compiler) return compiler;
|
|
3406
|
+
try {
|
|
3407
|
+
compiler = await import("@vue/compiler-sfc");
|
|
3408
|
+
return compiler;
|
|
3409
|
+
} catch {
|
|
3410
|
+
return null;
|
|
3411
|
+
}
|
|
3412
|
+
}
|
|
3413
|
+
function vuePlugin(config) {
|
|
3414
|
+
const isDev = config.command === "serve";
|
|
3415
|
+
const descriptorCache = /* @__PURE__ */ new Map();
|
|
3416
|
+
return {
|
|
3417
|
+
name: "nasti:vue",
|
|
3418
|
+
enforce: "pre",
|
|
3419
|
+
async resolveId(source) {
|
|
3420
|
+
if (VUE_QUERY_RE.test(source)) {
|
|
3421
|
+
return source;
|
|
3422
|
+
}
|
|
3423
|
+
return null;
|
|
3424
|
+
},
|
|
3425
|
+
// 虚拟子模块必须有 load 钩子:build 下 Rolldown 否则会按字面路径读盘,
|
|
3426
|
+
// 抛 UNLOADABLE_DEPENDENCY(1.x Vue 生产构建因此直接失败)。
|
|
3427
|
+
// style 子块在这里编译成 CSS 字符串,交给 css 插件统一处理
|
|
3428
|
+
// (dev = <style> 注入 + HMR;build = CssEngine 抽取成 hashed .css)。
|
|
3429
|
+
async load(id) {
|
|
3430
|
+
const match = id.match(/(.+\.vue)\?vue&type=style(?:&index=(\d+))?/);
|
|
3431
|
+
if (!match) return null;
|
|
3432
|
+
const sfc = await loadVueCompiler();
|
|
3433
|
+
if (!sfc) return null;
|
|
3434
|
+
const [, filePath, indexStr] = match;
|
|
3435
|
+
let descriptor = descriptorCache.get(filePath);
|
|
3436
|
+
if (!descriptor) {
|
|
3437
|
+
try {
|
|
3438
|
+
const fs12 = await import("fs");
|
|
3439
|
+
const source = fs12.readFileSync(filePath, "utf-8");
|
|
3440
|
+
const parsed = sfc.parse(source, { filename: filePath });
|
|
3441
|
+
if (parsed.errors.length) return null;
|
|
3442
|
+
descriptor = parsed.descriptor;
|
|
3443
|
+
descriptorCache.set(filePath, descriptor);
|
|
3444
|
+
} catch {
|
|
3445
|
+
return null;
|
|
3446
|
+
}
|
|
3447
|
+
}
|
|
3448
|
+
const index2 = parseInt(indexStr ?? "0", 10);
|
|
3449
|
+
const style = descriptor.styles[index2];
|
|
3450
|
+
if (!style) return null;
|
|
3451
|
+
const scopeId = hashId(filePath);
|
|
3452
|
+
const result = await sfc.compileStyleAsync({
|
|
3453
|
+
source: style.content,
|
|
3454
|
+
filename: filePath,
|
|
3455
|
+
id: `data-v-${scopeId}`,
|
|
3456
|
+
scoped: style.scoped ?? false,
|
|
3457
|
+
// <style lang="scss|less|stylus"> 需经对应预处理器(缺省 undefined = 纯 CSS)
|
|
3458
|
+
preprocessLang: style.lang
|
|
3459
|
+
});
|
|
3460
|
+
return result.code;
|
|
3461
|
+
},
|
|
3462
|
+
async transform(code, id) {
|
|
3463
|
+
if (!VUE_FILE_RE.test(id) && !VUE_QUERY_RE.test(id)) return null;
|
|
3464
|
+
const sfc = await loadVueCompiler();
|
|
3465
|
+
if (!sfc) {
|
|
3466
|
+
console.warn("[nasti:vue] @vue/compiler-sfc not found. Install it: npm install @vue/compiler-sfc");
|
|
3467
|
+
return null;
|
|
3468
|
+
}
|
|
3469
|
+
if (VUE_QUERY_RE.test(id)) {
|
|
3470
|
+
return null;
|
|
3471
|
+
}
|
|
3472
|
+
const { descriptor, errors } = sfc.parse(code, { filename: id });
|
|
3473
|
+
if (errors.length) {
|
|
3474
|
+
console.error(`[nasti:vue] Parse error in ${id}:`, errors[0].message);
|
|
3475
|
+
return null;
|
|
3476
|
+
}
|
|
3477
|
+
descriptorCache.set(id, descriptor);
|
|
3478
|
+
const scopeId = hashId(id);
|
|
3479
|
+
let scriptCode = "";
|
|
3480
|
+
if (descriptor.script || descriptor.scriptSetup) {
|
|
3481
|
+
const compiled = sfc.compileScript(descriptor, {
|
|
3482
|
+
id: scopeId,
|
|
3483
|
+
isProd: !isDev,
|
|
3484
|
+
inlineTemplate: true,
|
|
3485
|
+
// 让 compileScript 产出 `const __sfc__ = ...`(而非默认的 `export default {...}`)。
|
|
3486
|
+
// 否则下方追加的 `__sfc__.render` / `__sfc__.__scopeId` / HMR 记录会引用一个
|
|
3487
|
+
// 不存在的 `__sfc__`,并与 compileScript 自带的 `export default` 形成双重默认导出。
|
|
3488
|
+
genDefaultAs: "__sfc__"
|
|
3489
|
+
});
|
|
3490
|
+
scriptCode = compiled.content;
|
|
3491
|
+
}
|
|
3492
|
+
let templateCode = "";
|
|
3493
|
+
if (descriptor.template && !descriptor.scriptSetup) {
|
|
3494
|
+
const compiled = sfc.compileTemplate({
|
|
3495
|
+
source: descriptor.template.content,
|
|
3496
|
+
filename: id,
|
|
3497
|
+
id: scopeId,
|
|
3498
|
+
compilerOptions: { scopeId: `data-v-${scopeId}` }
|
|
3499
|
+
});
|
|
3500
|
+
templateCode = compiled.code;
|
|
3501
|
+
}
|
|
3502
|
+
let output = scriptCode || "const __sfc__ = {}";
|
|
3503
|
+
if (templateCode) {
|
|
3504
|
+
output += `
|
|
3505
|
+
${templateCode}
|
|
3506
|
+
`;
|
|
3507
|
+
output += `
|
|
3508
|
+
__sfc__.render = render
|
|
3509
|
+
`;
|
|
3510
|
+
}
|
|
3511
|
+
if (descriptor.styles.length > 0) {
|
|
3512
|
+
for (let i = 0; i < descriptor.styles.length; i++) {
|
|
3513
|
+
output += `
|
|
3514
|
+
import "${id}?vue&type=style&index=${i}&lang.css"
|
|
3515
|
+
`;
|
|
3516
|
+
}
|
|
3517
|
+
}
|
|
3518
|
+
output += `
|
|
3519
|
+
__sfc__.__scopeId = "data-v-${scopeId}"
|
|
3520
|
+
`;
|
|
3521
|
+
if (isDev) {
|
|
3522
|
+
output += `
|
|
3523
|
+
__sfc__.__hmrId = ${JSON.stringify(scopeId)}
|
|
3524
|
+
if (typeof __VUE_HMR_RUNTIME__ !== 'undefined') {
|
|
3525
|
+
__VUE_HMR_RUNTIME__.createRecord(__sfc__.__hmrId, __sfc__)
|
|
3526
|
+
}
|
|
3527
|
+
if (import.meta.hot) {
|
|
3528
|
+
import.meta.hot.accept((mod) => {
|
|
3529
|
+
if (!mod) return
|
|
3530
|
+
const { default: updated } = mod
|
|
3531
|
+
if (typeof __VUE_HMR_RUNTIME__ !== 'undefined') {
|
|
3532
|
+
__VUE_HMR_RUNTIME__.rerender(updated.__hmrId, updated.render)
|
|
3533
|
+
}
|
|
3534
|
+
})
|
|
3535
|
+
}
|
|
3536
|
+
`;
|
|
3537
|
+
}
|
|
3538
|
+
output += `
|
|
3539
|
+
export default __sfc__
|
|
3540
|
+
`;
|
|
3541
|
+
const lang = descriptor.scriptSetup?.lang ?? descriptor.script?.lang;
|
|
3542
|
+
if (lang === "ts") {
|
|
3543
|
+
const transpiled = transformCode(`${id}.ts`, output, { sourcemap: false });
|
|
3544
|
+
return { code: transpiled.code };
|
|
3545
|
+
}
|
|
3546
|
+
return { code: output };
|
|
3547
|
+
},
|
|
3548
|
+
handleHotUpdate(ctx) {
|
|
3549
|
+
const { file, modules } = ctx;
|
|
3550
|
+
if (VUE_FILE_RE.test(file)) {
|
|
3551
|
+
for (const mod of modules) {
|
|
3552
|
+
mod.isSelfAccepting = true;
|
|
3553
|
+
}
|
|
3554
|
+
descriptorCache.delete(file);
|
|
3555
|
+
}
|
|
3556
|
+
return modules;
|
|
3557
|
+
}
|
|
3558
|
+
};
|
|
3559
|
+
}
|
|
3560
|
+
function hashId(filename) {
|
|
3561
|
+
return crypto2.createHash("sha256").update(filename).digest("hex").slice(0, 8);
|
|
3562
|
+
}
|
|
3563
|
+
var VUE_FILE_RE, VUE_QUERY_RE, compiler;
|
|
3564
|
+
var init_vue = __esm({
|
|
3565
|
+
"src/plugins/vue.ts"() {
|
|
3566
|
+
"use strict";
|
|
3567
|
+
init_transformer();
|
|
3568
|
+
VUE_FILE_RE = /\.vue$/;
|
|
3569
|
+
VUE_QUERY_RE = /\.vue\?vue&type=(script|template|style)(&index=\d+)?(&lang[.=]\w+)?/;
|
|
3570
|
+
compiler = null;
|
|
3571
|
+
}
|
|
3572
|
+
});
|
|
3573
|
+
|
|
3574
|
+
// src/plugins/builtins.ts
|
|
3575
|
+
function resolvePluginList(config, userPlugins, opts = {}) {
|
|
3576
|
+
const isServe = config.command === "serve";
|
|
3577
|
+
return [
|
|
3578
|
+
// vuePlugin 排最前(enforce: 'pre' 语义):.vue 先编译成 JS 再走后续管道
|
|
3579
|
+
...config.framework === "vue" ? [vuePlugin(config)] : [],
|
|
3580
|
+
resolvePlugin(config),
|
|
3581
|
+
cssPlugin(config, opts.cssEngine, opts.consumer),
|
|
3582
|
+
assetsPlugin(config),
|
|
3583
|
+
...isServe ? [htmlPlugin(config)] : [],
|
|
3584
|
+
...userPlugins,
|
|
3585
|
+
// cssPostPlugin 最后(enforce: 'post' 语义):renderChunk 聚合抽取
|
|
3586
|
+
...!isServe && opts.cssEngine ? [cssPostPlugin(config, opts.cssEngine)] : []
|
|
3587
|
+
];
|
|
3588
|
+
}
|
|
3589
|
+
var init_builtins = __esm({
|
|
3590
|
+
"src/plugins/builtins.ts"() {
|
|
3591
|
+
"use strict";
|
|
3592
|
+
init_resolve();
|
|
3593
|
+
init_css();
|
|
3594
|
+
init_css_post();
|
|
3595
|
+
init_assets();
|
|
3596
|
+
init_vue();
|
|
3597
|
+
init_html();
|
|
3598
|
+
}
|
|
3599
|
+
});
|
|
3600
|
+
|
|
3601
|
+
// src/server/runnable-environment.ts
|
|
3602
|
+
var runnable_environment_exports = {};
|
|
3603
|
+
__export(runnable_environment_exports, {
|
|
3604
|
+
NastiModuleRunner: () => NastiModuleRunner,
|
|
3605
|
+
createModuleRunner: () => createModuleRunner
|
|
3606
|
+
});
|
|
3607
|
+
import path10 from "path";
|
|
3608
|
+
import fs8 from "fs";
|
|
3609
|
+
import { builtinModules, createRequire as createRequire4 } from "module";
|
|
3610
|
+
import { pathToFileURL as pathToFileURL4 } from "url";
|
|
3611
|
+
function createModuleRunner(environment) {
|
|
3612
|
+
if (environment.consumer !== "server") {
|
|
3613
|
+
throw new Error(
|
|
3614
|
+
`[nasti] module runner requires a server-consumer environment (got "${environment.name}" / ${environment.consumer})`
|
|
3615
|
+
);
|
|
3616
|
+
}
|
|
3617
|
+
return new NastiModuleRunner(environment);
|
|
3618
|
+
}
|
|
3619
|
+
var debug3, NODE_BUILTINS, NastiModuleRunner, AsyncFunction;
|
|
3620
|
+
var init_runnable_environment = __esm({
|
|
3621
|
+
"src/server/runnable-environment.ts"() {
|
|
3622
|
+
"use strict";
|
|
3623
|
+
init_transformer();
|
|
3624
|
+
init_env();
|
|
3625
|
+
init_debug();
|
|
3626
|
+
debug3 = createDebugger("nasti:ssr");
|
|
3627
|
+
NODE_BUILTINS = /* @__PURE__ */ new Set([...builtinModules, ...builtinModules.map((m) => `node:${m}`)]);
|
|
3628
|
+
NastiModuleRunner = class {
|
|
3629
|
+
environment;
|
|
3630
|
+
config;
|
|
3631
|
+
cache = /* @__PURE__ */ new Map();
|
|
3632
|
+
envDefine;
|
|
3633
|
+
require;
|
|
3634
|
+
constructor(environment) {
|
|
3635
|
+
this.environment = environment;
|
|
3636
|
+
this.config = environment.config;
|
|
3637
|
+
this.envDefine = buildEnvDefine(
|
|
3638
|
+
loadEnv(this.config.mode, this.config.root, this.config.envPrefix),
|
|
3639
|
+
this.config.mode,
|
|
3640
|
+
ssrDefineOverrides(environment.consumer)
|
|
3641
|
+
);
|
|
3642
|
+
this.require = createRequire4(path10.join(this.config.root, "package.json"));
|
|
3643
|
+
const handlers = {
|
|
3644
|
+
fetchModule: async (id, importer) => this.fetchModule(id, importer),
|
|
3645
|
+
getBuiltins: () => [/^node:/, ...builtinModules]
|
|
3646
|
+
};
|
|
3647
|
+
environment.hot.setInvokeHandler?.(handlers);
|
|
3648
|
+
}
|
|
3649
|
+
/** 入口:加载并执行一个模块(url 为根相对或绝对路径) */
|
|
3650
|
+
async import(rawUrl) {
|
|
3651
|
+
const id = this.resolveToId(rawUrl);
|
|
3652
|
+
return this.instantiate(id);
|
|
3653
|
+
}
|
|
3654
|
+
/** 文件变更时按文件失效(含其所属的虚拟子模块) */
|
|
3655
|
+
invalidateFile(file) {
|
|
3656
|
+
for (const key of [...this.cache.keys()]) {
|
|
3657
|
+
if (key === file || key.startsWith(file + "?")) {
|
|
3658
|
+
this.cache.delete(key);
|
|
3659
|
+
}
|
|
3660
|
+
}
|
|
3661
|
+
}
|
|
3662
|
+
invalidateAll() {
|
|
3663
|
+
this.cache.clear();
|
|
3664
|
+
}
|
|
3665
|
+
resolveToId(rawUrl) {
|
|
3666
|
+
if (path10.isAbsolute(rawUrl) && fs8.existsSync(rawUrl.split("?")[0])) return rawUrl;
|
|
3667
|
+
const clean = rawUrl.replace(/^\//, "");
|
|
3668
|
+
return path10.resolve(this.config.root, clean);
|
|
3669
|
+
}
|
|
3670
|
+
/**
|
|
3671
|
+
* fetchModule(invoke 契约方法):环境管线产出 runner 可执行代码。
|
|
3672
|
+
* resolve(插件 resolveId → 文件系统)→ load/读盘 → 插件 transform →
|
|
3673
|
+
* oxc(TS/JSX)→ moduleRunnerTransform。
|
|
3674
|
+
*/
|
|
3675
|
+
async fetchModule(id, importer) {
|
|
3676
|
+
if (NODE_BUILTINS.has(id)) return { externalize: id };
|
|
3677
|
+
if (!id.startsWith(".") && !path10.isAbsolute(id) && !id.startsWith("\0")) {
|
|
3678
|
+
return { externalize: id };
|
|
3679
|
+
}
|
|
3680
|
+
const container = this.environment.pluginContainer;
|
|
3681
|
+
let resolvedId = id;
|
|
3682
|
+
if (id.startsWith(".") && importer) {
|
|
3683
|
+
const resolved = await container.resolveId(id, importer);
|
|
3684
|
+
resolvedId = resolved ? typeof resolved === "string" ? resolved : resolved.id : path10.resolve(path10.dirname(importer.split("?")[0]), id);
|
|
3685
|
+
}
|
|
3686
|
+
resolvedId = this.completeExtension(resolvedId);
|
|
3687
|
+
const cleanId = resolvedId.split("?")[0];
|
|
3688
|
+
let code;
|
|
3689
|
+
const loaded = await container.load(resolvedId);
|
|
3690
|
+
if (loaded != null) {
|
|
3691
|
+
code = typeof loaded === "string" ? loaded : loaded.code;
|
|
3692
|
+
} else if (fs8.existsSync(cleanId)) {
|
|
3693
|
+
code = fs8.readFileSync(cleanId, "utf-8");
|
|
3694
|
+
} else {
|
|
3695
|
+
throw new Error(`[nasti:ssr] cannot load module: ${resolvedId}`);
|
|
3696
|
+
}
|
|
3697
|
+
const transformed = await container.transform(code, resolvedId);
|
|
3698
|
+
if (transformed != null) {
|
|
3699
|
+
code = typeof transformed === "string" ? transformed : transformed.code;
|
|
3700
|
+
}
|
|
3701
|
+
if (shouldTransform(cleanId)) {
|
|
3702
|
+
const result = transformCode(cleanId, code, {
|
|
3703
|
+
sourcemap: false,
|
|
3704
|
+
jsxRuntime: "automatic",
|
|
3705
|
+
jsxImportSource: this.config.framework === "vue" ? "vue" : "react"
|
|
3706
|
+
});
|
|
3707
|
+
code = result.code;
|
|
3708
|
+
}
|
|
3709
|
+
code = replaceEnvInCode(code, this.envDefine);
|
|
3710
|
+
let moduleRunnerTransform;
|
|
3711
|
+
try {
|
|
3712
|
+
;
|
|
3713
|
+
({ moduleRunnerTransform } = await import("rolldown/experimental"));
|
|
3714
|
+
} catch (err) {
|
|
3715
|
+
throw new Error(
|
|
3716
|
+
`[nasti:ssr] rolldown/experimental moduleRunnerTransform unavailable (installed rolldown incompatible?): ${err.message}`
|
|
3717
|
+
);
|
|
3718
|
+
}
|
|
3719
|
+
const runnerResult = await moduleRunnerTransform(resolvedId, code);
|
|
3720
|
+
debug3?.(`fetchModule ${resolvedId} (${runnerResult.deps?.length ?? 0} deps)`);
|
|
3721
|
+
return { id: resolvedId, code: runnerResult.code };
|
|
3722
|
+
}
|
|
3723
|
+
completeExtension(id) {
|
|
3724
|
+
const clean = id.split("?")[0];
|
|
3725
|
+
const query = id.includes("?") ? id.slice(id.indexOf("?")) : "";
|
|
3726
|
+
if (fs8.existsSync(clean) && fs8.statSync(clean).isFile()) return id;
|
|
3727
|
+
const jsMatch = clean.match(/^(.*)\.([mc]?)jsx?$/);
|
|
3728
|
+
if (jsMatch) {
|
|
3729
|
+
for (const tsExt of [`.${jsMatch[2]}ts`, `.${jsMatch[2]}tsx`]) {
|
|
3730
|
+
if (fs8.existsSync(jsMatch[1] + tsExt)) return jsMatch[1] + tsExt + query;
|
|
3731
|
+
}
|
|
3732
|
+
}
|
|
3733
|
+
for (const ext of this.config.resolve.extensions) {
|
|
3734
|
+
if (fs8.existsSync(clean + ext)) return clean + ext + query;
|
|
3735
|
+
}
|
|
3736
|
+
for (const ext of this.config.resolve.extensions) {
|
|
3737
|
+
const indexPath = path10.join(clean, `index${ext}`);
|
|
3738
|
+
if (fs8.existsSync(indexPath)) return indexPath;
|
|
3739
|
+
}
|
|
3740
|
+
return id;
|
|
3741
|
+
}
|
|
3742
|
+
async instantiate(id) {
|
|
3743
|
+
const cached2 = this.cache.get(id);
|
|
3744
|
+
if (cached2) return cached2.promise ?? Promise.resolve(cached2.exports);
|
|
3745
|
+
const entry = { exports: {}, promise: null };
|
|
3746
|
+
this.cache.set(id, entry);
|
|
3747
|
+
entry.promise = this.evaluate(id, entry).then(() => {
|
|
3748
|
+
entry.promise = null;
|
|
3749
|
+
return entry.exports;
|
|
3750
|
+
}).catch((err) => {
|
|
3751
|
+
this.cache.delete(id);
|
|
3752
|
+
throw err;
|
|
3753
|
+
});
|
|
3754
|
+
return entry.promise;
|
|
3755
|
+
}
|
|
3756
|
+
async evaluate(id, entry) {
|
|
3757
|
+
const fetched = await this.fetchModule(id);
|
|
3758
|
+
if ("externalize" in fetched) {
|
|
3759
|
+
const spec = fetched.externalize;
|
|
3760
|
+
const mod = await this.importExternal(spec);
|
|
3761
|
+
entry.exports = mod;
|
|
3762
|
+
return;
|
|
3763
|
+
}
|
|
3764
|
+
const ssrImport = async (dep) => {
|
|
3765
|
+
if (NODE_BUILTINS.has(dep) || !dep.startsWith(".") && !path10.isAbsolute(dep) && !dep.startsWith("\0")) {
|
|
3766
|
+
return this.importExternal(dep);
|
|
3767
|
+
}
|
|
3768
|
+
const depId = dep.startsWith(".") ? this.completeExtension(path10.resolve(path10.dirname(fetched.id.split("?")[0]), dep)) : this.completeExtension(dep);
|
|
3769
|
+
return this.instantiate(depId);
|
|
3770
|
+
};
|
|
3771
|
+
const ssrExportAll = (sourceModule) => {
|
|
3772
|
+
for (const key of Object.keys(sourceModule)) {
|
|
3773
|
+
if (key !== "default" && !(key in entry.exports)) {
|
|
3774
|
+
Object.defineProperty(entry.exports, key, {
|
|
3775
|
+
enumerable: true,
|
|
3776
|
+
configurable: true,
|
|
3777
|
+
get: () => sourceModule[key]
|
|
3778
|
+
});
|
|
3779
|
+
}
|
|
3780
|
+
}
|
|
3781
|
+
};
|
|
3782
|
+
const importMeta = {
|
|
3783
|
+
url: pathToFileURL4(fetched.id.split("?")[0]).href,
|
|
3784
|
+
env: { SSR: true, MODE: this.config.mode, DEV: this.config.mode !== "production", PROD: this.config.mode === "production" },
|
|
3785
|
+
hot: void 0
|
|
3786
|
+
};
|
|
3787
|
+
const fn = new AsyncFunction(
|
|
3788
|
+
"__vite_ssr_exports__",
|
|
3789
|
+
"__vite_ssr_import__",
|
|
3790
|
+
"__vite_ssr_dynamic_import__",
|
|
3791
|
+
"__vite_ssr_exportAll__",
|
|
3792
|
+
"__vite_ssr_import_meta__",
|
|
3793
|
+
`"use strict";${fetched.code}
|
|
3794
|
+
//# sourceURL=${fetched.id}`
|
|
3795
|
+
);
|
|
3796
|
+
await fn(entry.exports, ssrImport, ssrImport, ssrExportAll, importMeta);
|
|
3797
|
+
}
|
|
3798
|
+
async importExternal(spec) {
|
|
3799
|
+
try {
|
|
3800
|
+
return await (spec.startsWith("node:") || !path10.isAbsolute(spec) ? import(this.resolveExternalSpecifier(spec)) : import(pathToFileURL4(spec).href));
|
|
3801
|
+
} catch (err) {
|
|
3802
|
+
throw new Error(`[nasti:ssr] failed to import external "${spec}": ${err.message}`);
|
|
3803
|
+
}
|
|
3804
|
+
}
|
|
3805
|
+
/** bare specifier → 项目 node_modules 的绝对 URL(避免相对 Nasti 自身解析) */
|
|
3806
|
+
resolveExternalSpecifier(spec) {
|
|
3807
|
+
if (spec.startsWith("node:")) return spec;
|
|
3808
|
+
if (NODE_BUILTINS.has(spec)) return `node:${spec}`;
|
|
3809
|
+
try {
|
|
3810
|
+
return pathToFileURL4(this.require.resolve(spec)).href;
|
|
3811
|
+
} catch {
|
|
3812
|
+
return spec;
|
|
3813
|
+
}
|
|
3814
|
+
}
|
|
3815
|
+
};
|
|
3816
|
+
AsyncFunction = Object.getPrototypeOf(async function() {
|
|
3817
|
+
}).constructor;
|
|
3818
|
+
}
|
|
3819
|
+
});
|
|
3820
|
+
|
|
3821
|
+
// src/build/reporter.ts
|
|
3822
|
+
import path11 from "path";
|
|
3823
|
+
import { gzipSync } from "zlib";
|
|
3824
|
+
import pc5 from "picocolors";
|
|
3825
|
+
async function tryNativeReporterPlugin(config, logger) {
|
|
3826
|
+
try {
|
|
3827
|
+
const { viteReporterPlugin } = await import("rolldown/experimental");
|
|
3828
|
+
if (typeof viteReporterPlugin !== "function") return null;
|
|
3829
|
+
return viteReporterPlugin({
|
|
3830
|
+
root: config.root,
|
|
3831
|
+
isTty: process.stdout.isTTY ?? false,
|
|
3832
|
+
isLib: false,
|
|
3833
|
+
assetsDir: config.build.assetsDir,
|
|
3834
|
+
chunkLimit: config.build.chunkSizeWarningLimit,
|
|
3835
|
+
// 大 chunk 警告由 JS 侧 warnLargeChunks() 经 logger.warn 输出,
|
|
3836
|
+
// 原生侧只产 info 级表格,避免警告被 logLevel 过滤吞掉
|
|
3837
|
+
warnLargeChunks: false,
|
|
3838
|
+
reportCompressedSize: config.build.reportCompressedSize,
|
|
3839
|
+
logInfo: (msg) => logger.info(msg)
|
|
3840
|
+
});
|
|
3841
|
+
} catch (err) {
|
|
3842
|
+
debug4?.(`native viteReporterPlugin unavailable, falling back to JS table: ${err}`);
|
|
3843
|
+
return null;
|
|
3844
|
+
}
|
|
3845
|
+
}
|
|
3846
|
+
function displaySize(bytes) {
|
|
3847
|
+
return `${numberFormatter.format(bytes / 1e3)} kB`;
|
|
3848
|
+
}
|
|
3849
|
+
function byteLength(content) {
|
|
3850
|
+
if (content == null) return 0;
|
|
3851
|
+
return typeof content === "string" ? Buffer.byteLength(content) : content.byteLength;
|
|
3852
|
+
}
|
|
3853
|
+
function reportBuildOutput(output, config, logger) {
|
|
3854
|
+
const entries = [];
|
|
3855
|
+
const compressed = config.build.reportCompressedSize;
|
|
3856
|
+
for (const file of output) {
|
|
3857
|
+
const content = file.type === "chunk" ? file.code : file.source;
|
|
3858
|
+
const size = byteLength(content);
|
|
3859
|
+
let gzip = null;
|
|
3860
|
+
if (compressed && content != null) {
|
|
3861
|
+
gzip = gzipSync(typeof content === "string" ? Buffer.from(content) : content).byteLength;
|
|
3862
|
+
}
|
|
3863
|
+
const ext = path11.extname(file.fileName);
|
|
3864
|
+
const group = file.type === "chunk" ? "js" : ext === ".css" ? "css" : "assets";
|
|
3865
|
+
entries.push({ name: file.fileName, size, gzip, group });
|
|
3866
|
+
}
|
|
3867
|
+
const groupOrder = { assets: 0, css: 1, js: 2 };
|
|
3868
|
+
entries.sort((a, b) => groupOrder[a.group] - groupOrder[b.group] || a.size - b.size);
|
|
3869
|
+
const outDirPrefix = `${config.build.outDir.replace(/\/$/, "")}/`;
|
|
3870
|
+
const maxNameLen = Math.max(...entries.map((e) => (outDirPrefix + e.name).length), 0);
|
|
3871
|
+
const maxSizeLen = Math.max(...entries.map((e) => displaySize(e.size).length), 0);
|
|
3872
|
+
const groupColor = { assets: pc5.green, css: pc5.magenta, js: pc5.cyan };
|
|
3873
|
+
for (const e of entries) {
|
|
3874
|
+
const color = groupColor[e.group];
|
|
3875
|
+
const namePart = pc5.dim(outDirPrefix) + color(e.name.padEnd(maxNameLen - outDirPrefix.length));
|
|
3876
|
+
const sizePart = pc5.dim(pc5.bold(displaySize(e.size).padStart(maxSizeLen)));
|
|
3877
|
+
const gzipPart = e.gzip != null ? pc5.dim(` \u2502 gzip: ${displaySize(e.gzip)}`) : "";
|
|
3878
|
+
logger.info(`${namePart} ${sizePart}${gzipPart}`);
|
|
3879
|
+
}
|
|
3880
|
+
}
|
|
3881
|
+
function warnLargeChunks(output, config, logger) {
|
|
3882
|
+
const limit = config.build.chunkSizeWarningLimit;
|
|
3883
|
+
const large = output.filter(
|
|
3884
|
+
(f) => f.type === "chunk" && byteLength(f.code) / 1e3 > limit
|
|
3885
|
+
);
|
|
3886
|
+
if (large.length === 0) return;
|
|
3887
|
+
logger.warn(
|
|
3888
|
+
pc5.yellow(
|
|
3889
|
+
`
|
|
3890
|
+
(!) Some chunks are larger than ${limit} kB after minification. Consider:
|
|
3891
|
+
- Using dynamic import() to code-split the application
|
|
3892
|
+
- Configuring build.rolldownOptions.output.advancedChunks to isolate large dependencies
|
|
3893
|
+
- Adjusting build.chunkSizeWarningLimit to silence this warning`
|
|
3894
|
+
)
|
|
3895
|
+
);
|
|
3896
|
+
}
|
|
3897
|
+
var debug4, numberFormatter;
|
|
3898
|
+
var init_reporter = __esm({
|
|
3899
|
+
"src/build/reporter.ts"() {
|
|
3900
|
+
"use strict";
|
|
3901
|
+
init_debug();
|
|
3902
|
+
debug4 = createDebugger("nasti:reporter");
|
|
3903
|
+
numberFormatter = new Intl.NumberFormat("en", {
|
|
3904
|
+
maximumFractionDigits: 2,
|
|
3905
|
+
minimumFractionDigits: 2
|
|
3906
|
+
});
|
|
3907
|
+
}
|
|
3908
|
+
});
|
|
3909
|
+
|
|
3910
|
+
// src/build/index.ts
|
|
3911
|
+
var build_exports = {};
|
|
3912
|
+
__export(build_exports, {
|
|
3913
|
+
build: () => build,
|
|
3914
|
+
getRolldownOptions: () => getRolldownOptions,
|
|
3915
|
+
resolveClientEntries: () => resolveClientEntries,
|
|
3916
|
+
toRolldownPlugins: () => toRolldownPlugins
|
|
3917
|
+
});
|
|
3918
|
+
import path12 from "path";
|
|
3919
|
+
import fs9 from "fs";
|
|
3920
|
+
import { builtinModules as builtinModules2 } from "module";
|
|
3921
|
+
import { rolldown } from "rolldown";
|
|
3922
|
+
import pc6 from "picocolors";
|
|
3923
|
+
function getRolldownOptions(environment, entryPoints, rolldownPlugins) {
|
|
3924
|
+
const config = environment.config;
|
|
3925
|
+
const envOptions = environment.options;
|
|
3926
|
+
const isServer = environment.consumer === "server";
|
|
3927
|
+
const outDir = path12.resolve(config.root, envOptions.build.outDir);
|
|
3928
|
+
const assetsDir = envOptions.build.assetsDir;
|
|
3929
|
+
const { output: userOutput, transform: userTransform, ...restInputOptions } = envOptions.build.rolldownOptions;
|
|
3930
|
+
const vueDefine = config.framework === "vue" ? {
|
|
3931
|
+
__VUE_OPTIONS_API__: "true",
|
|
3932
|
+
__VUE_PROD_DEVTOOLS__: "false",
|
|
3933
|
+
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: "false"
|
|
3934
|
+
} : {};
|
|
3935
|
+
const env = loadEnv(config.mode, config.root, config.envPrefix);
|
|
3936
|
+
const envDefine = buildEnvDefine(env, config.mode, ssrDefineOverrides(environment.consumer));
|
|
3937
|
+
const mergedDefine = { ...vueDefine, ...userTransform?.define ?? {}, ...envDefine };
|
|
3938
|
+
const inputOptions = {
|
|
3939
|
+
...restInputOptions,
|
|
3940
|
+
input: entryPoints,
|
|
3941
|
+
transform: { ...userTransform, define: mergedDefine },
|
|
3942
|
+
plugins: rolldownPlugins,
|
|
3943
|
+
...isServer ? {
|
|
3944
|
+
platform: restInputOptions.platform ?? "node",
|
|
3945
|
+
resolve: {
|
|
3946
|
+
conditionNames: envOptions.resolve.conditions,
|
|
3947
|
+
mainFields: envOptions.resolve.mainFields,
|
|
3948
|
+
...restInputOptions.resolve
|
|
3949
|
+
},
|
|
3950
|
+
// server 产物:node 内建恒外部化;bare specifier 默认外部化
|
|
3951
|
+
//(同 Vite ssr.external 默认 —— 依赖由 node_modules 运行时解析),
|
|
3952
|
+
// 相对/绝对/虚拟模块照常打包。需要内联依赖时经 rolldownOptions.external 覆盖。
|
|
3953
|
+
external: restInputOptions.external ?? ((id) => {
|
|
3954
|
+
if (NODE_BUILTINS2.has(id)) return true;
|
|
3955
|
+
return !id.startsWith(".") && !path12.isAbsolute(id) && !id.startsWith("\0");
|
|
3956
|
+
})
|
|
3957
|
+
} : {}
|
|
3958
|
+
};
|
|
3959
|
+
const outputOptions = isServer ? {
|
|
3960
|
+
format: "esm",
|
|
3961
|
+
sourcemap: !!envOptions.build.sourcemap,
|
|
3962
|
+
minify: !!envOptions.build.minify,
|
|
3963
|
+
entryFileNames: "[name].js",
|
|
3964
|
+
chunkFileNames: "chunks/[name]-[hash].js",
|
|
3965
|
+
assetFileNames: `${assetsDir}/[name].[hash][extname]`,
|
|
3966
|
+
...userOutput,
|
|
3967
|
+
dir: outDir
|
|
3968
|
+
} : {
|
|
3969
|
+
format: "esm",
|
|
3970
|
+
sourcemap: !!envOptions.build.sourcemap,
|
|
3971
|
+
minify: !!envOptions.build.minify,
|
|
3972
|
+
entryFileNames: `${assetsDir}/[name].[hash].js`,
|
|
3973
|
+
chunkFileNames: `${assetsDir}/[name].[hash].js`,
|
|
3974
|
+
assetFileNames: `${assetsDir}/[name].[hash][extname]`,
|
|
3975
|
+
// 用户可覆盖默认输出:代码拆分(advancedChunks / codeSplitting)、chunk 命名等
|
|
3976
|
+
...userOutput,
|
|
3977
|
+
// dir 始终由 Nasti 掌管 —— HTML 改写依赖固定的产物目录,故放在最后强制生效
|
|
3978
|
+
dir: outDir
|
|
3979
|
+
};
|
|
3980
|
+
return { inputOptions, outputOptions, outDir };
|
|
3981
|
+
}
|
|
3982
|
+
function toRolldownPlugins(plugins) {
|
|
3983
|
+
return plugins.map((p) => ({
|
|
3984
|
+
name: p.name,
|
|
3985
|
+
resolveId: p.resolveId,
|
|
3986
|
+
load: p.load,
|
|
3987
|
+
transform: p.transform,
|
|
3988
|
+
buildStart: p.buildStart,
|
|
3989
|
+
buildEnd: p.buildEnd,
|
|
3990
|
+
// closeBundle 在 bundle.close() 时触发 —— PWA manifest/SW 等终态产物依赖
|
|
3991
|
+
closeBundle: p.closeBundle,
|
|
3992
|
+
renderChunk: p.renderChunk,
|
|
3993
|
+
augmentChunkHash: p.augmentChunkHash,
|
|
3994
|
+
generateBundle: p.generateBundle
|
|
3995
|
+
}));
|
|
3996
|
+
}
|
|
3997
|
+
function resolveClientEntries(config, html) {
|
|
3998
|
+
const entryPoints = [];
|
|
3999
|
+
if (html) {
|
|
4000
|
+
const scriptMatches = html.matchAll(/<script[^>]+src=["']([^"']+)["'][^>]*>/gi);
|
|
4001
|
+
for (const match of scriptMatches) {
|
|
4002
|
+
const src = match[1];
|
|
4003
|
+
if (src && !src.startsWith("http")) {
|
|
4004
|
+
entryPoints.push(path12.resolve(config.root, src.replace(/^\//, "")));
|
|
4005
|
+
}
|
|
4006
|
+
}
|
|
4007
|
+
}
|
|
4008
|
+
if (entryPoints.length === 0) {
|
|
4009
|
+
const fallbackEntries = ["src/main.ts", "src/main.tsx", "src/main.js", "src/index.ts", "src/index.tsx", "src/index.js"];
|
|
4010
|
+
for (const entry of fallbackEntries) {
|
|
4011
|
+
const fullPath = path12.resolve(config.root, entry);
|
|
4012
|
+
if (fs9.existsSync(fullPath)) {
|
|
4013
|
+
entryPoints.push(fullPath);
|
|
4014
|
+
break;
|
|
4015
|
+
}
|
|
4016
|
+
}
|
|
4017
|
+
}
|
|
4018
|
+
return entryPoints;
|
|
4019
|
+
}
|
|
4020
|
+
function createOxcTransformPlugin(config, environment) {
|
|
4021
|
+
return {
|
|
4022
|
+
name: "nasti:oxc-transform",
|
|
4023
|
+
transform(code, id) {
|
|
4024
|
+
if (!shouldTransform(id)) return null;
|
|
4025
|
+
const result = transformCode(id, code, {
|
|
4026
|
+
sourcemap: !!environment.options.build.sourcemap,
|
|
4027
|
+
jsxRuntime: "automatic",
|
|
4028
|
+
jsxImportSource: config.framework === "vue" ? "vue" : "react"
|
|
4029
|
+
});
|
|
4030
|
+
return { code: result.code, map: result.map ? JSON.parse(result.map) : void 0 };
|
|
4031
|
+
}
|
|
4032
|
+
};
|
|
4033
|
+
}
|
|
4034
|
+
async function build(inlineConfig = {}) {
|
|
4035
|
+
const config = await resolveConfig(inlineConfig, "build");
|
|
4036
|
+
const logger = config.logger;
|
|
4037
|
+
const startTime = performance.now();
|
|
4038
|
+
logger.info(
|
|
4039
|
+
pc6.cyan(`
|
|
4040
|
+
nasti v${"2.0.1"} `) + pc6.green(`building for ${config.mode}...`)
|
|
4041
|
+
);
|
|
4042
|
+
debug5?.(`root: ${config.root}`);
|
|
4043
|
+
const buildableNames = Object.keys(config.environments).filter(
|
|
4044
|
+
(name) => name === "client" || config.environments[name].entry.length > 0
|
|
4045
|
+
);
|
|
4046
|
+
buildableNames.sort((a, b) => a === "client" ? -1 : b === "client" ? 1 : 0);
|
|
4047
|
+
const environments = {};
|
|
4048
|
+
let clientOutput = [];
|
|
4049
|
+
for (const name of buildableNames) {
|
|
4050
|
+
const output = name === "client" ? await buildClientEnvironment(config) : await buildServerEnvironment(config, name);
|
|
4051
|
+
environments[name] = output;
|
|
4052
|
+
if (name === "client") clientOutput = output;
|
|
4053
|
+
if (buildableNames.length > 1) {
|
|
4054
|
+
debug5?.(`environment "${name}" built (${output.length} files)`);
|
|
4055
|
+
}
|
|
4056
|
+
}
|
|
4057
|
+
const elapsed = ((performance.now() - startTime) / 1e3).toFixed(2);
|
|
4058
|
+
const totalSize = Object.values(environments).flat().reduce((sum, chunk) => {
|
|
4059
|
+
const content = chunk.type === "chunk" ? chunk.code : chunk.source;
|
|
4060
|
+
if (content == null) return sum;
|
|
4061
|
+
return sum + (typeof content === "string" ? Buffer.byteLength(content) : content.byteLength);
|
|
4062
|
+
}, 0);
|
|
4063
|
+
const fileCount = Object.values(environments).flat().length;
|
|
4064
|
+
const envSuffix = buildableNames.length > 1 ? ` (${buildableNames.join(" + ")})` : "";
|
|
4065
|
+
logger.info(pc6.green(`\u2713 built in ${elapsed}s`) + pc6.dim(envSuffix));
|
|
4066
|
+
logger.info(pc6.dim(` ${fileCount} files, ${displaySize(totalSize)} total \u2192 ${config.build.outDir}/`));
|
|
4067
|
+
return { output: clientOutput, environments };
|
|
4068
|
+
}
|
|
4069
|
+
async function buildClientEnvironment(config) {
|
|
4070
|
+
const logger = config.logger;
|
|
4071
|
+
const outDir = path12.resolve(config.root, config.build.outDir);
|
|
4072
|
+
if (config.build.emptyOutDir && fs9.existsSync(outDir)) {
|
|
4073
|
+
fs9.rmSync(outDir, { recursive: true, force: true });
|
|
4074
|
+
}
|
|
4075
|
+
fs9.mkdirSync(outDir, { recursive: true });
|
|
4076
|
+
const html = await readHtmlFile(config.root);
|
|
4077
|
+
const entryPoints = resolveClientEntries(config, html);
|
|
4078
|
+
if (entryPoints.length === 0) {
|
|
4079
|
+
throw new Error("No entry point found. Add a <script> tag to index.html or create src/main.ts");
|
|
4080
|
+
}
|
|
4081
|
+
const cssEngine = createCssEngine();
|
|
4082
|
+
const pluginList = resolvePluginList(config, config.plugins, { cssEngine });
|
|
4083
|
+
const clientEnv = new NastiEnvironment("client", { ...config, plugins: pluginList }, {
|
|
4084
|
+
mode: "build",
|
|
4085
|
+
plugins: pluginList
|
|
4086
|
+
});
|
|
4087
|
+
await clientEnv.init();
|
|
4088
|
+
const allPlugins = clientEnv.plugins;
|
|
4089
|
+
const nativeReporter = config.logLevel === "silent" ? null : await tryNativeReporterPlugin(config, logger);
|
|
4090
|
+
const rolldownPlugins = [
|
|
4091
|
+
createOxcTransformPlugin(config, clientEnv),
|
|
4092
|
+
...toRolldownPlugins(allPlugins),
|
|
4093
|
+
...nativeReporter ? [nativeReporter] : []
|
|
4094
|
+
];
|
|
4095
|
+
const { inputOptions, outputOptions } = getRolldownOptions(clientEnv, entryPoints, rolldownPlugins);
|
|
4096
|
+
const bundle2 = await rolldown(inputOptions);
|
|
4097
|
+
const { output } = await bundle2.write(outputOptions);
|
|
4098
|
+
await bundle2.close();
|
|
4099
|
+
if (html) {
|
|
4100
|
+
let processedHtml = html;
|
|
4101
|
+
const htmlPlugins = [...allPlugins.filter((p) => p.transformIndexHtml), htmlPlugin(config)];
|
|
4102
|
+
for (const p of htmlPlugins) {
|
|
4103
|
+
const result = await p.transformIndexHtml(processedHtml);
|
|
4104
|
+
if (typeof result === "string") {
|
|
4105
|
+
processedHtml = result;
|
|
4106
|
+
} else if (result && "html" in result) {
|
|
4107
|
+
processedHtml = processHtml(result.html, result.tags);
|
|
4108
|
+
} else if (Array.isArray(result)) {
|
|
4109
|
+
processedHtml = processHtml(processedHtml, result);
|
|
4110
|
+
}
|
|
1796
4111
|
}
|
|
1797
|
-
|
|
4112
|
+
processedHtml = injectCssLinks(processedHtml, cssEngine, config);
|
|
4113
|
+
for (const chunk of output) {
|
|
4114
|
+
if (chunk.type === "chunk" && chunk.isEntry && chunk.facadeModuleId) {
|
|
4115
|
+
const originalEntry = path12.relative(config.root, chunk.facadeModuleId);
|
|
4116
|
+
processedHtml = processedHtml.replace(
|
|
4117
|
+
new RegExp(`(src=["'])/?(${escapeRegExp(originalEntry)})(["'])`, "g"),
|
|
4118
|
+
`$1${config.base}${chunk.fileName}$3`
|
|
4119
|
+
);
|
|
4120
|
+
}
|
|
4121
|
+
}
|
|
4122
|
+
fs9.writeFileSync(path12.resolve(outDir, "index.html"), processedHtml);
|
|
4123
|
+
}
|
|
4124
|
+
if (!nativeReporter && config.logLevel !== "silent") {
|
|
4125
|
+
reportBuildOutput(output, config, logger);
|
|
4126
|
+
}
|
|
4127
|
+
warnLargeChunks(output, config, logger);
|
|
4128
|
+
return output;
|
|
1798
4129
|
}
|
|
1799
|
-
function
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
4130
|
+
async function buildServerEnvironment(config, name) {
|
|
4131
|
+
const envOptions = config.environments[name];
|
|
4132
|
+
const logger = config.logger;
|
|
4133
|
+
for (const entry of envOptions.entry) {
|
|
4134
|
+
if (!fs9.existsSync(entry)) {
|
|
4135
|
+
throw new Error(`[nasti] environment "${name}" entry not found: ${entry}`);
|
|
1803
4136
|
}
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
4137
|
+
}
|
|
4138
|
+
const pluginList = resolvePluginList(config, config.plugins, { consumer: envOptions.consumer });
|
|
4139
|
+
const environment = new NastiEnvironment(name, { ...config, plugins: pluginList }, {
|
|
4140
|
+
mode: "build",
|
|
4141
|
+
plugins: pluginList
|
|
1807
4142
|
});
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
4143
|
+
await environment.init();
|
|
4144
|
+
const rolldownPlugins = [
|
|
4145
|
+
createOxcTransformPlugin(config, environment),
|
|
4146
|
+
...toRolldownPlugins(environment.plugins)
|
|
4147
|
+
];
|
|
4148
|
+
const { inputOptions, outputOptions, outDir } = getRolldownOptions(
|
|
4149
|
+
environment,
|
|
4150
|
+
envOptions.entry,
|
|
4151
|
+
rolldownPlugins
|
|
4152
|
+
);
|
|
4153
|
+
if (envOptions.build.emptyOutDir && fs9.existsSync(outDir)) {
|
|
4154
|
+
fs9.rmSync(outDir, { recursive: true, force: true });
|
|
1813
4155
|
}
|
|
1814
|
-
});
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
return
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
const file = id.replace(/\?.*$/, "");
|
|
1840
|
-
if (!fs7.existsSync(file)) return null;
|
|
1841
|
-
if (config.command === "serve") {
|
|
1842
|
-
const url = "/" + path9.relative(config.root, file);
|
|
1843
|
-
return `export default ${JSON.stringify(url)}`;
|
|
1844
|
-
}
|
|
1845
|
-
const content = fs7.readFileSync(file);
|
|
1846
|
-
const hash = crypto.createHash("sha256").update(content).digest("hex").slice(0, 8);
|
|
1847
|
-
const basename = path9.basename(file, ext);
|
|
1848
|
-
const hashedName = `${config.build.assetsDir}/${basename}.${hash}${ext}`;
|
|
1849
|
-
return `export default ${JSON.stringify(config.base + hashedName)}`;
|
|
4156
|
+
fs9.mkdirSync(outDir, { recursive: true });
|
|
4157
|
+
const bundle2 = await rolldown(inputOptions);
|
|
4158
|
+
const { output } = await bundle2.write(outputOptions);
|
|
4159
|
+
await bundle2.close();
|
|
4160
|
+
logger.info(
|
|
4161
|
+
pc6.dim(` [${name}] `) + output.map((o) => path12.join(envOptions.build.outDir, o.fileName)).join(pc6.dim(", "))
|
|
4162
|
+
);
|
|
4163
|
+
return output;
|
|
4164
|
+
}
|
|
4165
|
+
function injectCssLinks(html, cssEngine, config) {
|
|
4166
|
+
const cssLinkTags = [];
|
|
4167
|
+
if (cssEngine.singleFileName) {
|
|
4168
|
+
cssLinkTags.push({
|
|
4169
|
+
tag: "link",
|
|
4170
|
+
attrs: { rel: "stylesheet", href: config.base + cssEngine.singleFileName },
|
|
4171
|
+
injectTo: "head"
|
|
4172
|
+
});
|
|
4173
|
+
} else {
|
|
4174
|
+
for (const files of cssEngine.entryCss.values()) {
|
|
4175
|
+
for (const file of files) {
|
|
4176
|
+
cssLinkTags.push({
|
|
4177
|
+
tag: "link",
|
|
4178
|
+
attrs: { rel: "stylesheet", href: config.base + file },
|
|
4179
|
+
injectTo: "head"
|
|
4180
|
+
});
|
|
1850
4181
|
}
|
|
1851
|
-
return null;
|
|
1852
4182
|
}
|
|
1853
|
-
}
|
|
4183
|
+
}
|
|
4184
|
+
return cssLinkTags.length > 0 ? processHtml(html, cssLinkTags) : html;
|
|
1854
4185
|
}
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
4186
|
+
function escapeRegExp(string) {
|
|
4187
|
+
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4188
|
+
}
|
|
4189
|
+
var debug5, NODE_BUILTINS2;
|
|
4190
|
+
var init_build = __esm({
|
|
4191
|
+
"src/build/index.ts"() {
|
|
1858
4192
|
"use strict";
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
".ogg",
|
|
1871
|
-
".mp3",
|
|
1872
|
-
".wav",
|
|
1873
|
-
".flac",
|
|
1874
|
-
".aac",
|
|
1875
|
-
".woff",
|
|
1876
|
-
".woff2",
|
|
1877
|
-
".eot",
|
|
1878
|
-
".ttf",
|
|
1879
|
-
".otf",
|
|
1880
|
-
".pdf",
|
|
1881
|
-
".txt"
|
|
1882
|
-
]);
|
|
4193
|
+
init_config();
|
|
4194
|
+
init_builtins();
|
|
4195
|
+
init_environment();
|
|
4196
|
+
init_css_engine();
|
|
4197
|
+
init_html();
|
|
4198
|
+
init_transformer();
|
|
4199
|
+
init_env();
|
|
4200
|
+
init_reporter();
|
|
4201
|
+
init_debug();
|
|
4202
|
+
debug5 = createDebugger("nasti:build");
|
|
4203
|
+
NODE_BUILTINS2 = /* @__PURE__ */ new Set([...builtinModules2, ...builtinModules2.map((m) => `node:${m}`)]);
|
|
1883
4204
|
}
|
|
1884
4205
|
});
|
|
1885
4206
|
|
|
1886
|
-
// src/
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
4207
|
+
// src/server/bundled/dev-engine.ts
|
|
4208
|
+
var dev_engine_exports = {};
|
|
4209
|
+
__export(dev_engine_exports, {
|
|
4210
|
+
createBundledDevServer: () => createBundledDevServer
|
|
4211
|
+
});
|
|
4212
|
+
import path13 from "path";
|
|
4213
|
+
import crypto3 from "crypto";
|
|
4214
|
+
import { WebSocketServer as WsServer2 } from "ws";
|
|
4215
|
+
import pc7 from "picocolors";
|
|
4216
|
+
async function createBundledDevServer(opts) {
|
|
4217
|
+
const { config, clientEnv, httpServer } = opts;
|
|
4218
|
+
const logger = config.logger;
|
|
4219
|
+
let devFn;
|
|
4220
|
+
let refreshWrapperFn = null;
|
|
1890
4221
|
try {
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
4222
|
+
const experimental = await import("rolldown/experimental");
|
|
4223
|
+
devFn = experimental.dev;
|
|
4224
|
+
if (typeof devFn !== "function") throw new Error("dev() export missing");
|
|
4225
|
+
if (typeof experimental.viteReactRefreshWrapperPlugin === "function") {
|
|
4226
|
+
refreshWrapperFn = experimental.viteReactRefreshWrapperPlugin;
|
|
4227
|
+
}
|
|
4228
|
+
} catch (err) {
|
|
4229
|
+
throw new Error(
|
|
4230
|
+
`[nasti] experimental.bundledDev requires rolldown's experimental dev() API (locked to the installed rc; got: ${err.message}). Remove --bundle / experimental.bundledDev to use the default unbundled dev server.`
|
|
4231
|
+
);
|
|
1895
4232
|
}
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
4233
|
+
const html = await readHtmlFile(config.root);
|
|
4234
|
+
const entryPoints = resolveClientEntries(config, html);
|
|
4235
|
+
if (entryPoints.length === 0) {
|
|
4236
|
+
throw new Error("No entry point found. Add a <script> tag to index.html or create src/main.ts");
|
|
4237
|
+
}
|
|
4238
|
+
const memoryFiles = new MemoryFiles();
|
|
4239
|
+
const patches = new MemoryFiles();
|
|
4240
|
+
const entryFileNames = /* @__PURE__ */ new Map();
|
|
4241
|
+
const bundledClients = /* @__PURE__ */ new Map();
|
|
4242
|
+
const useReactRefresh = config.framework !== "vue" && refreshWrapperFn != null;
|
|
4243
|
+
const rolldownPlugins = [
|
|
4244
|
+
...useReactRefresh ? [
|
|
4245
|
+
createReactRefreshRuntimePlugin(entryPoints),
|
|
4246
|
+
createBundledOxcRefreshPlugin()
|
|
4247
|
+
] : [],
|
|
4248
|
+
...stripCatchAllLoad(toRolldownPlugins(clientEnv.plugins)),
|
|
4249
|
+
...useReactRefresh ? [
|
|
4250
|
+
refreshWrapperFn({
|
|
4251
|
+
cwd: config.root,
|
|
4252
|
+
include: [/\.[jt]sx(\?.*)?$/],
|
|
4253
|
+
exclude: [/node_modules/],
|
|
4254
|
+
jsxImportSource: "react",
|
|
4255
|
+
reactRefreshHost: ""
|
|
4256
|
+
})
|
|
4257
|
+
] : []
|
|
4258
|
+
];
|
|
4259
|
+
const { inputOptions, outputOptions } = getRolldownOptions(clientEnv, entryPoints, rolldownPlugins);
|
|
4260
|
+
let fullReloadTimer = null;
|
|
4261
|
+
const scheduleFullReload = () => {
|
|
4262
|
+
if (fullReloadTimer) clearTimeout(fullReloadTimer);
|
|
4263
|
+
fullReloadTimer = setTimeout(() => {
|
|
4264
|
+
logger.info(pc7.green("page reload ") + pc7.dim("(bundled)"), { timestamp: true });
|
|
4265
|
+
broadcast({ type: "hmr:reload" });
|
|
4266
|
+
}, 30);
|
|
4267
|
+
};
|
|
4268
|
+
const broadcast = (payload) => {
|
|
4269
|
+
const data = JSON.stringify(payload);
|
|
4270
|
+
for (const ws of bundledClients.values()) {
|
|
4271
|
+
if (ws.readyState === 1) ws.send(data);
|
|
4272
|
+
}
|
|
4273
|
+
};
|
|
4274
|
+
const sendTo = (clientId, payload) => {
|
|
4275
|
+
const ws = bundledClients.get(clientId);
|
|
4276
|
+
if (ws && ws.readyState === 1) ws.send(JSON.stringify(payload));
|
|
4277
|
+
};
|
|
4278
|
+
async function processUpdates(updates, changedFiles) {
|
|
4279
|
+
let needsLatestOutput = false;
|
|
4280
|
+
for (const { clientId, update } of updates) {
|
|
4281
|
+
if (update.type === "Noop") continue;
|
|
4282
|
+
if (update.type === "FullReload") {
|
|
4283
|
+
debug6?.(`full reload for ${clientId}: ${update.reason ?? ""}`);
|
|
4284
|
+
needsLatestOutput = true;
|
|
4285
|
+
continue;
|
|
4286
|
+
}
|
|
4287
|
+
const patchPath = `__nasti_patch/${update.filename}`;
|
|
4288
|
+
patches.set(patchPath, update.code + "\n;export {}");
|
|
4289
|
+
if (update.sourcemap && update.sourcemapFilename) {
|
|
4290
|
+
patches.set(`__nasti_patch/${update.sourcemapFilename}`, update.sourcemap);
|
|
4291
|
+
}
|
|
4292
|
+
const url = `/${patchPath}`;
|
|
4293
|
+
logger.info(
|
|
4294
|
+
pc7.green("hmr update ") + pc7.dim(changedFiles.map((f) => path13.relative(config.root, f)).join(", ")),
|
|
4295
|
+
{ timestamp: true }
|
|
4296
|
+
);
|
|
4297
|
+
sendTo(clientId, { type: "hmr:update", path: url, url });
|
|
4298
|
+
}
|
|
4299
|
+
if (needsLatestOutput) {
|
|
4300
|
+
await engine.ensureLatestBuildOutput();
|
|
4301
|
+
scheduleFullReload();
|
|
4302
|
+
}
|
|
4303
|
+
}
|
|
4304
|
+
const engine = await devFn(
|
|
4305
|
+
{
|
|
4306
|
+
...inputOptions,
|
|
4307
|
+
cwd: config.root,
|
|
4308
|
+
// Rolldown bug 规避:inlineConst 与 dev patch 机制冲突(vitejs/vite#21843)
|
|
4309
|
+
optimization: { ...inputOptions.optimization, inlineConst: false },
|
|
4310
|
+
experimental: {
|
|
4311
|
+
...inputOptions.experimental,
|
|
4312
|
+
devMode: {
|
|
4313
|
+
lazy: true,
|
|
4314
|
+
// 默认 DevRuntime 把 ws 地址烤进 bundle:指向 Nasti dev server 本身
|
|
4315
|
+
//(端口被占自动 +1 时 HMR ws 会失联 —— 已知限制,产物仍可服务)
|
|
4316
|
+
host: config.server.host === true ? "localhost" : config.server.host || "localhost",
|
|
4317
|
+
port: config.server.port
|
|
4318
|
+
}
|
|
1906
4319
|
}
|
|
1907
|
-
return null;
|
|
1908
4320
|
},
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
4321
|
+
{
|
|
4322
|
+
...outputOptions,
|
|
4323
|
+
entryFileNames: "assets/[name].js",
|
|
4324
|
+
chunkFileNames: "assets/[name]-[hash].js",
|
|
4325
|
+
minify: false,
|
|
4326
|
+
sourcemap: true
|
|
4327
|
+
},
|
|
4328
|
+
{
|
|
4329
|
+
watch: { skipWrite: true },
|
|
4330
|
+
rebuildStrategy: "auto",
|
|
4331
|
+
onOutput(result) {
|
|
4332
|
+
if (result instanceof Error) {
|
|
4333
|
+
logger.error(pc7.red(`[bundled] build error: ${result.message}`), { error: result });
|
|
4334
|
+
return;
|
|
4335
|
+
}
|
|
4336
|
+
for (const file of result.output) {
|
|
4337
|
+
const content = file.type === "chunk" ? file.code : file.source;
|
|
4338
|
+
if (content != null) memoryFiles.set(file.fileName, content);
|
|
4339
|
+
if (file.type === "chunk" && file.isEntry && file.facadeModuleId) {
|
|
4340
|
+
entryFileNames.set(file.facadeModuleId, file.fileName);
|
|
4341
|
+
}
|
|
4342
|
+
if (file.type === "chunk" && file.map) {
|
|
4343
|
+
memoryFiles.set(`${file.fileName}.map`, JSON.stringify(file.map));
|
|
4344
|
+
}
|
|
4345
|
+
}
|
|
4346
|
+
debug6?.(`bundle output refreshed (${result.output.length} files)`);
|
|
4347
|
+
},
|
|
4348
|
+
async onHmrUpdates(result) {
|
|
4349
|
+
if (result instanceof Error) {
|
|
4350
|
+
logger.error(pc7.red(`[bundled] hmr error: ${result.message}`), { error: result });
|
|
4351
|
+
broadcast({ type: "error", err: { message: result.message, stack: result.stack } });
|
|
4352
|
+
return;
|
|
4353
|
+
}
|
|
4354
|
+
const { updates, changedFiles } = result;
|
|
4355
|
+
debug6?.(
|
|
4356
|
+
`onHmrUpdates(engine watcher): ${changedFiles.length} changed, ${updates.length} updates`
|
|
4357
|
+
);
|
|
4358
|
+
if (changedFiles.length === 0) return;
|
|
4359
|
+
await processUpdates(updates, changedFiles);
|
|
1915
4360
|
}
|
|
1916
|
-
|
|
1917
|
-
|
|
4361
|
+
}
|
|
4362
|
+
);
|
|
4363
|
+
await engine.run();
|
|
4364
|
+
await engine.ensureCurrentBuildFinish();
|
|
4365
|
+
logger.info(pc7.dim(` bundled dev engine ready (${entryPoints.length} entries, in-memory)`));
|
|
4366
|
+
const wss = new WsServer2({ noServer: true });
|
|
4367
|
+
httpServer.on("upgrade", (req, socket, head) => {
|
|
4368
|
+
if (req.headers["sec-websocket-protocol"] === "nasti-hmr") return;
|
|
4369
|
+
const url = new URL(req.url ?? "/", "http://localhost");
|
|
4370
|
+
const clientId = url.searchParams.get("clientId");
|
|
4371
|
+
if (!clientId) return;
|
|
4372
|
+
wss.handleUpgrade(req, socket, head, (ws) => {
|
|
4373
|
+
bundledClients.set(clientId, ws);
|
|
4374
|
+
debug6?.(`bundled client connected: ${clientId}`);
|
|
4375
|
+
ws.send(JSON.stringify({ type: "connected" }));
|
|
4376
|
+
ws.on("message", async (raw) => {
|
|
4377
|
+
try {
|
|
4378
|
+
const msg = JSON.parse(String(raw));
|
|
4379
|
+
if (msg.type === "hmr:module-registered" && Array.isArray(msg.modules)) {
|
|
4380
|
+
await engine.registerModules(clientId, msg.modules);
|
|
4381
|
+
debug6?.(`registered ${msg.modules.length} modules for ${clientId}`);
|
|
4382
|
+
} else if (msg.type === "hmr:invalidate") {
|
|
4383
|
+
scheduleFullReload();
|
|
4384
|
+
}
|
|
4385
|
+
} catch (err) {
|
|
4386
|
+
debug6?.(`bundled ws message error: ${err.message}`);
|
|
4387
|
+
}
|
|
4388
|
+
});
|
|
4389
|
+
ws.on("close", () => {
|
|
4390
|
+
bundledClients.delete(clientId);
|
|
4391
|
+
engine.removeClient(clientId).catch((err) => debug6?.(`removeClient failed for ${clientId}: ${err?.message ?? err}`));
|
|
4392
|
+
});
|
|
4393
|
+
});
|
|
4394
|
+
});
|
|
4395
|
+
const middleware = (req, res, next) => {
|
|
4396
|
+
void (async () => {
|
|
4397
|
+
const rawUrl = req.url ?? "/";
|
|
4398
|
+
const url = new URL(rawUrl, "http://localhost");
|
|
4399
|
+
const pathname = decodeURIComponent(url.pathname);
|
|
4400
|
+
if (pathname === "/@vite/lazy" || pathname === "/@nasti/lazy") {
|
|
4401
|
+
const id = url.searchParams.get("id");
|
|
4402
|
+
const clientId = url.searchParams.get("clientId");
|
|
4403
|
+
if (!id || !clientId) {
|
|
4404
|
+
res.statusCode = 400;
|
|
4405
|
+
res.end("// [nasti] lazy endpoint requires id & clientId");
|
|
4406
|
+
return;
|
|
4407
|
+
}
|
|
4408
|
+
const code = await engine.compileEntry(id, clientId);
|
|
4409
|
+
res.setHeader("Content-Type", "application/javascript");
|
|
4410
|
+
res.setHeader("Cache-Control", "no-store");
|
|
4411
|
+
res.end(code + "\n;export {}");
|
|
4412
|
+
return;
|
|
1918
4413
|
}
|
|
1919
|
-
const
|
|
1920
|
-
if (
|
|
1921
|
-
|
|
1922
|
-
|
|
4414
|
+
const patchHit = patches.get(pathname.replace(/^\//, ""));
|
|
4415
|
+
if (patchHit) {
|
|
4416
|
+
res.setHeader("Content-Type", "application/javascript");
|
|
4417
|
+
res.setHeader("Cache-Control", "no-store");
|
|
4418
|
+
res.end(patchHit.content);
|
|
4419
|
+
return;
|
|
1923
4420
|
}
|
|
1924
|
-
|
|
1925
|
-
const
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
scriptCode = compiled.content;
|
|
4421
|
+
const fileName = pathname.replace(/^\//, "");
|
|
4422
|
+
const hit = memoryFiles.get(fileName);
|
|
4423
|
+
if (hit) {
|
|
4424
|
+
if (req.headers["if-none-match"] === hit.etag) {
|
|
4425
|
+
res.statusCode = 304;
|
|
4426
|
+
res.end();
|
|
4427
|
+
return;
|
|
4428
|
+
}
|
|
4429
|
+
res.setHeader("ETag", hit.etag);
|
|
4430
|
+
res.setHeader("Content-Type", MIME_TYPES[path13.extname(fileName)] ?? "application/octet-stream");
|
|
4431
|
+
res.setHeader("Cache-Control", "no-cache");
|
|
4432
|
+
res.end(hit.content);
|
|
4433
|
+
return;
|
|
1938
4434
|
}
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
}
|
|
1947
|
-
templateCode = compiled.code;
|
|
4435
|
+
if (pathname === "/" || pathname.endsWith(".html")) {
|
|
4436
|
+
const rawHtml = await readHtmlFile(config.root);
|
|
4437
|
+
if (rawHtml) {
|
|
4438
|
+
res.setHeader("Content-Type", "text/html");
|
|
4439
|
+
res.setHeader("Cache-Control", "no-store");
|
|
4440
|
+
res.end(await renderBundledIndexHtml(rawHtml, config, entryFileNames));
|
|
4441
|
+
return;
|
|
4442
|
+
}
|
|
1948
4443
|
}
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
4444
|
+
next();
|
|
4445
|
+
})().catch((err) => {
|
|
4446
|
+
config.logger.error(pc7.red(`[bundled] ${err.message}`), { error: err });
|
|
4447
|
+
res.statusCode = 500;
|
|
4448
|
+
res.end(`[nasti bundled] ${err.message}`);
|
|
4449
|
+
});
|
|
4450
|
+
};
|
|
4451
|
+
return {
|
|
4452
|
+
middleware,
|
|
4453
|
+
async close() {
|
|
4454
|
+
if (fullReloadTimer) clearTimeout(fullReloadTimer);
|
|
4455
|
+
wss.close();
|
|
4456
|
+
await engine.close();
|
|
4457
|
+
}
|
|
4458
|
+
};
|
|
4459
|
+
}
|
|
4460
|
+
function stripCatchAllLoad(plugins) {
|
|
4461
|
+
return plugins.map(
|
|
4462
|
+
(p) => p?.name === "nasti:resolve" ? { ...p, load: void 0 } : p
|
|
4463
|
+
);
|
|
4464
|
+
}
|
|
4465
|
+
function createReactRefreshRuntimePlugin(entryPoints) {
|
|
4466
|
+
const entryIds = new Set(entryPoints.map((p) => path13.resolve(p)));
|
|
4467
|
+
return {
|
|
4468
|
+
name: "nasti:bundled-react-refresh",
|
|
4469
|
+
resolveId(source) {
|
|
4470
|
+
if (source === REFRESH_RUNTIME_URL) return REFRESH_RUNTIME_URL;
|
|
4471
|
+
if (source === PREAMBLE_SPEC) return RESOLVED_PREAMBLE_ID;
|
|
4472
|
+
return null;
|
|
4473
|
+
},
|
|
4474
|
+
load(id) {
|
|
4475
|
+
if (id === REFRESH_RUNTIME_URL) {
|
|
4476
|
+
return { code: getReactRefreshRuntimeEsm() + WRAPPER_RUNTIME_HELPERS, moduleType: "js" };
|
|
1957
4477
|
}
|
|
1958
|
-
if (
|
|
1959
|
-
|
|
1960
|
-
const style = descriptor.styles[i];
|
|
1961
|
-
const lang2 = style.lang ?? "css";
|
|
1962
|
-
output += `
|
|
1963
|
-
import "${id}?vue&type=style&index=${i}&lang=${lang2}"
|
|
1964
|
-
`;
|
|
1965
|
-
}
|
|
4478
|
+
if (id === RESOLVED_PREAMBLE_ID) {
|
|
4479
|
+
return { code: BUNDLED_PREAMBLE_CODE, moduleType: "js" };
|
|
1966
4480
|
}
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
if (
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
4481
|
+
return null;
|
|
4482
|
+
},
|
|
4483
|
+
transform(code, id) {
|
|
4484
|
+
if (!entryIds.has(path13.resolve(id.split("?")[0]))) return null;
|
|
4485
|
+
return { code: `import ${JSON.stringify(PREAMBLE_SPEC)};
|
|
4486
|
+
${code}`, map: null };
|
|
4487
|
+
}
|
|
4488
|
+
};
|
|
1975
4489
|
}
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
4490
|
+
function createBundledOxcRefreshPlugin() {
|
|
4491
|
+
return {
|
|
4492
|
+
name: "nasti:bundled-oxc-refresh",
|
|
4493
|
+
transform(code, id) {
|
|
4494
|
+
const clean = id.split("?")[0];
|
|
4495
|
+
if (!/\.[jt]sx$/.test(clean) || clean.includes("/node_modules/")) return null;
|
|
4496
|
+
const result = transformCode(clean, code, {
|
|
4497
|
+
sourcemap: true,
|
|
4498
|
+
jsxRuntime: "automatic",
|
|
4499
|
+
jsxImportSource: "react",
|
|
4500
|
+
reactRefresh: true
|
|
4501
|
+
});
|
|
4502
|
+
return { code: result.code, map: result.map ? JSON.parse(result.map) : void 0 };
|
|
1982
4503
|
}
|
|
1983
|
-
}
|
|
4504
|
+
};
|
|
1984
4505
|
}
|
|
1985
|
-
|
|
4506
|
+
async function renderBundledIndexHtml(html, config, entryFileNames) {
|
|
4507
|
+
let processed = html;
|
|
4508
|
+
for (const plugin of config.plugins) {
|
|
4509
|
+
if (!plugin.transformIndexHtml || plugin.name === "nasti:html") continue;
|
|
4510
|
+
const result = await plugin.transformIndexHtml(processed);
|
|
4511
|
+
if (typeof result === "string") {
|
|
4512
|
+
processed = result;
|
|
4513
|
+
} else if (result && "html" in result) {
|
|
4514
|
+
processed = processHtml(result.html, result.tags);
|
|
4515
|
+
} else if (Array.isArray(result)) {
|
|
4516
|
+
processed = processHtml(processed, result);
|
|
4517
|
+
}
|
|
4518
|
+
}
|
|
4519
|
+
for (const [facadeModuleId, fileName] of entryFileNames) {
|
|
4520
|
+
const originalEntry = path13.relative(config.root, facadeModuleId);
|
|
4521
|
+
processed = processed.replace(
|
|
4522
|
+
new RegExp(`(src=["'])/?(${originalEntry.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")})(["'])`, "g"),
|
|
4523
|
+
`$1/${fileName}$3`
|
|
4524
|
+
);
|
|
4525
|
+
}
|
|
4526
|
+
return processed;
|
|
4527
|
+
}
|
|
4528
|
+
var debug6, MIME_TYPES, MemoryFiles, PREAMBLE_SPEC, RESOLVED_PREAMBLE_ID, REFRESH_RUNTIME_URL, BUNDLED_PREAMBLE_CODE, WRAPPER_RUNTIME_HELPERS;
|
|
4529
|
+
var init_dev_engine = __esm({
|
|
4530
|
+
"src/server/bundled/dev-engine.ts"() {
|
|
4531
|
+
"use strict";
|
|
4532
|
+
init_build();
|
|
4533
|
+
init_html();
|
|
4534
|
+
init_transformer();
|
|
4535
|
+
init_middleware();
|
|
4536
|
+
init_debug();
|
|
4537
|
+
debug6 = createDebugger("nasti:bundled");
|
|
4538
|
+
MIME_TYPES = {
|
|
4539
|
+
".js": "application/javascript",
|
|
4540
|
+
".mjs": "application/javascript",
|
|
4541
|
+
".css": "text/css",
|
|
4542
|
+
".html": "text/html",
|
|
4543
|
+
".json": "application/json",
|
|
4544
|
+
".map": "application/json",
|
|
4545
|
+
".svg": "image/svg+xml",
|
|
4546
|
+
".png": "image/png",
|
|
4547
|
+
".jpg": "image/jpeg",
|
|
4548
|
+
".wasm": "application/wasm"
|
|
4549
|
+
};
|
|
4550
|
+
MemoryFiles = class {
|
|
4551
|
+
files = /* @__PURE__ */ new Map();
|
|
4552
|
+
set(fileName, content) {
|
|
4553
|
+
const etag = `"${crypto3.createHash("sha1").update(content).digest("base64").slice(0, 27)}"`;
|
|
4554
|
+
this.files.set(fileName, { content, etag });
|
|
1986
4555
|
}
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
`;
|
|
1990
|
-
const lang = descriptor.scriptSetup?.lang ?? descriptor.script?.lang;
|
|
1991
|
-
if (lang === "ts") {
|
|
1992
|
-
const transpiled = transformCode(`${id}.ts`, output, { sourcemap: false });
|
|
1993
|
-
return { code: transpiled.code };
|
|
4556
|
+
get(fileName) {
|
|
4557
|
+
return this.files.get(fileName);
|
|
1994
4558
|
}
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
4559
|
+
clear() {
|
|
4560
|
+
this.files.clear();
|
|
4561
|
+
}
|
|
4562
|
+
};
|
|
4563
|
+
PREAMBLE_SPEC = "nasti:react-preamble";
|
|
4564
|
+
RESOLVED_PREAMBLE_ID = "\0nasti:react-preamble";
|
|
4565
|
+
REFRESH_RUNTIME_URL = "/@react-refresh";
|
|
4566
|
+
BUNDLED_PREAMBLE_CODE = `
|
|
4567
|
+
import __rt from ${JSON.stringify(REFRESH_RUNTIME_URL)};
|
|
4568
|
+
__rt.injectIntoGlobalHook(window);
|
|
4569
|
+
window.$RefreshReg$ = () => {};
|
|
4570
|
+
window.$RefreshSig$ = () => (type) => type;
|
|
4571
|
+
window.__vite_plugin_react_preamble_installed__ = true;
|
|
4572
|
+
`;
|
|
4573
|
+
WRAPPER_RUNTIME_HELPERS = `
|
|
4574
|
+
// \u2500\u2500 viteReactRefreshWrapperPlugin \u8FD0\u884C\u65F6\u5951\u7EA6\uFF08@vitejs/plugin-react \u540C\u6B3E\uFF09\u2500\u2500
|
|
4575
|
+
function __isPlainObject(obj) {
|
|
4576
|
+
return Object.prototype.toString.call(obj) === '[object Object]' &&
|
|
4577
|
+
(obj.constructor === Object || obj.constructor === undefined);
|
|
4578
|
+
}
|
|
4579
|
+
function __isCompoundComponent(type) {
|
|
4580
|
+
if (!__isPlainObject(type)) return false;
|
|
4581
|
+
for (const key in type) {
|
|
4582
|
+
if (!isLikelyComponentType(type[key])) return false;
|
|
4583
|
+
}
|
|
4584
|
+
return true;
|
|
4585
|
+
}
|
|
4586
|
+
export function registerExportsForReactRefresh(filename, moduleExports) {
|
|
4587
|
+
for (const key in moduleExports) {
|
|
4588
|
+
if (key === '__esModule') continue;
|
|
4589
|
+
const exportValue = moduleExports[key];
|
|
4590
|
+
if (isLikelyComponentType(exportValue)) {
|
|
4591
|
+
register(exportValue, filename + ' export ' + key);
|
|
4592
|
+
} else if (__isCompoundComponent(exportValue)) {
|
|
4593
|
+
for (const subKey in exportValue) {
|
|
4594
|
+
register(exportValue[subKey], filename + ' export ' + key + '-' + subKey);
|
|
2004
4595
|
}
|
|
2005
|
-
return modules;
|
|
2006
4596
|
}
|
|
2007
|
-
}
|
|
4597
|
+
}
|
|
2008
4598
|
}
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
if (!style) return null;
|
|
2019
|
-
const scopeId = hashId(filePath);
|
|
2020
|
-
const result = await sfc.compileStyleAsync({
|
|
2021
|
-
source: style.content,
|
|
2022
|
-
filename: filePath,
|
|
2023
|
-
id: `data-v-${scopeId}`,
|
|
2024
|
-
scoped: style.scoped ?? false
|
|
2025
|
-
});
|
|
2026
|
-
const cssCode = JSON.stringify(result.code);
|
|
2027
|
-
return {
|
|
2028
|
-
code: `
|
|
2029
|
-
const css = ${cssCode};
|
|
2030
|
-
const style = document.createElement('style');
|
|
2031
|
-
style.setAttribute('data-v-${scopeId}', '');
|
|
2032
|
-
style.textContent = css;
|
|
2033
|
-
document.head.appendChild(style);
|
|
2034
|
-
|
|
2035
|
-
if (import.meta.hot) {
|
|
2036
|
-
import.meta.hot.accept();
|
|
2037
|
-
import.meta.hot.prune(() => style.remove());
|
|
4599
|
+
let __enqueueTimer;
|
|
4600
|
+
const __hooks = [];
|
|
4601
|
+
window.__registerBeforePerformReactRefresh = (cb) => { __hooks.push(cb); };
|
|
4602
|
+
function __enqueueUpdate() {
|
|
4603
|
+
clearTimeout(__enqueueTimer);
|
|
4604
|
+
__enqueueTimer = setTimeout(async () => {
|
|
4605
|
+
if (__hooks.length) await Promise.all(__hooks.map((cb) => cb()));
|
|
4606
|
+
performReactRefresh();
|
|
4607
|
+
}, 16);
|
|
2038
4608
|
}
|
|
2039
|
-
|
|
2040
|
-
|
|
4609
|
+
function __predicateOnExport(ignoredExports, moduleExports, predicate) {
|
|
4610
|
+
for (const key in moduleExports) {
|
|
4611
|
+
if (ignoredExports.includes(key)) continue;
|
|
4612
|
+
if (!predicate(key, moduleExports[key])) return key;
|
|
2041
4613
|
}
|
|
2042
|
-
return
|
|
4614
|
+
return true;
|
|
2043
4615
|
}
|
|
2044
|
-
function
|
|
2045
|
-
|
|
4616
|
+
export function validateRefreshBoundaryAndEnqueueUpdate(id, prevExports, nextExports) {
|
|
4617
|
+
const ignoredExports = window.__getReactRefreshIgnoredExports?.({ id }) ?? [];
|
|
4618
|
+
if (__predicateOnExport(ignoredExports, prevExports, (key) => key in nextExports) !== true) {
|
|
4619
|
+
return 'Could not Fast Refresh (export removed)';
|
|
4620
|
+
}
|
|
4621
|
+
if (__predicateOnExport(ignoredExports, nextExports, (key) => key in prevExports) !== true) {
|
|
4622
|
+
return 'Could not Fast Refresh (new export)';
|
|
4623
|
+
}
|
|
4624
|
+
let hasExports = false;
|
|
4625
|
+
const allExportsAreComponentsOrUnchanged = __predicateOnExport(
|
|
4626
|
+
ignoredExports,
|
|
4627
|
+
nextExports,
|
|
4628
|
+
(key, value) => {
|
|
4629
|
+
hasExports = true;
|
|
4630
|
+
if (isLikelyComponentType(value)) return true;
|
|
4631
|
+
if (__isCompoundComponent(value)) return true;
|
|
4632
|
+
return prevExports[key] === nextExports[key];
|
|
4633
|
+
},
|
|
4634
|
+
);
|
|
4635
|
+
if (hasExports && allExportsAreComponentsOrUnchanged === true) {
|
|
4636
|
+
__enqueueUpdate();
|
|
4637
|
+
} else {
|
|
4638
|
+
return 'Could not Fast Refresh ("' + allExportsAreComponentsOrUnchanged + '" export is incompatible)';
|
|
4639
|
+
}
|
|
2046
4640
|
}
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
"src/plugins/vue.ts"() {
|
|
2050
|
-
"use strict";
|
|
2051
|
-
init_transformer();
|
|
2052
|
-
VUE_FILE_RE = /\.vue$/;
|
|
2053
|
-
VUE_QUERY_RE = /\.vue\?vue&type=(script|template|style)(&index=\d+)?(&lang=\w+)?/;
|
|
2054
|
-
compiler = null;
|
|
4641
|
+
export const __hmr_import = (module) => import(/* @vite-ignore */ module);
|
|
4642
|
+
`;
|
|
2055
4643
|
}
|
|
2056
4644
|
});
|
|
2057
4645
|
|
|
@@ -2061,45 +4649,78 @@ __export(server_exports, {
|
|
|
2061
4649
|
createServer: () => createServer
|
|
2062
4650
|
});
|
|
2063
4651
|
import http from "http";
|
|
2064
|
-
import
|
|
4652
|
+
import path14 from "path";
|
|
2065
4653
|
import os from "os";
|
|
2066
4654
|
import connect from "connect";
|
|
2067
4655
|
import sirv from "sirv";
|
|
2068
4656
|
import { watch } from "chokidar";
|
|
2069
|
-
import
|
|
4657
|
+
import pc8 from "picocolors";
|
|
2070
4658
|
async function createServer(inlineConfig = {}) {
|
|
4659
|
+
const startTime = performance.now();
|
|
2071
4660
|
const config = await resolveConfig(inlineConfig, "serve");
|
|
2072
|
-
const
|
|
2073
|
-
|
|
2074
|
-
resolvePlugin(config),
|
|
2075
|
-
cssPlugin(config),
|
|
2076
|
-
assetsPlugin(config),
|
|
2077
|
-
htmlPlugin(config),
|
|
2078
|
-
...config.plugins
|
|
2079
|
-
];
|
|
4661
|
+
const logger = config.logger;
|
|
4662
|
+
const allPlugins = resolvePluginList(config, config.plugins);
|
|
2080
4663
|
const configWithPlugins = { ...config, plugins: allPlugins };
|
|
2081
|
-
const moduleGraph = new ModuleGraph();
|
|
2082
|
-
const pluginContainer = new PluginContainer(configWithPlugins);
|
|
2083
4664
|
const app = connect();
|
|
4665
|
+
const httpServer = http.createServer(app);
|
|
4666
|
+
const ws = createWebSocketServer(httpServer);
|
|
4667
|
+
const clientEnv = new NastiEnvironment("client", configWithPlugins, {
|
|
4668
|
+
hot: createWsHotChannel(ws),
|
|
4669
|
+
mode: "dev",
|
|
4670
|
+
plugins: allPlugins
|
|
4671
|
+
});
|
|
4672
|
+
await clientEnv.init();
|
|
4673
|
+
const environments = { client: clientEnv };
|
|
4674
|
+
for (const name of Object.keys(config.environments)) {
|
|
4675
|
+
if (name === "client") continue;
|
|
4676
|
+
const consumer = config.environments[name].consumer;
|
|
4677
|
+
const envPlugins = resolvePluginList(config, config.plugins, { consumer });
|
|
4678
|
+
environments[name] = new NastiEnvironment(name, { ...config, plugins: envPlugins }, {
|
|
4679
|
+
mode: "dev",
|
|
4680
|
+
plugins: envPlugins
|
|
4681
|
+
});
|
|
4682
|
+
}
|
|
4683
|
+
let ssrRunner = null;
|
|
4684
|
+
async function getSsrRunner() {
|
|
4685
|
+
if (ssrRunner) return ssrRunner;
|
|
4686
|
+
const ssrEnv = environments.ssr;
|
|
4687
|
+
if (!ssrEnv) {
|
|
4688
|
+
throw new Error('[nasti] no "ssr" environment configured (config.environments.ssr)');
|
|
4689
|
+
}
|
|
4690
|
+
await ssrEnv.init();
|
|
4691
|
+
const { createModuleRunner: createModuleRunner2 } = await Promise.resolve().then(() => (init_runnable_environment(), runnable_environment_exports));
|
|
4692
|
+
ssrRunner = createModuleRunner2(ssrEnv);
|
|
4693
|
+
return ssrRunner;
|
|
4694
|
+
}
|
|
4695
|
+
const moduleGraph = clientEnv.moduleGraph;
|
|
4696
|
+
const pluginContainer = clientEnv.pluginContainer;
|
|
4697
|
+
let bundledServer = null;
|
|
4698
|
+
if (config.experimental.bundledDev) {
|
|
4699
|
+
const { createBundledDevServer: createBundledDevServer2 } = await Promise.resolve().then(() => (init_dev_engine(), dev_engine_exports));
|
|
4700
|
+
bundledServer = await createBundledDevServer2({
|
|
4701
|
+
config: configWithPlugins,
|
|
4702
|
+
clientEnv,
|
|
4703
|
+
httpServer
|
|
4704
|
+
});
|
|
4705
|
+
app.use(bundledServer.middleware);
|
|
4706
|
+
}
|
|
2084
4707
|
app.use(transformMiddleware({
|
|
2085
4708
|
config: configWithPlugins,
|
|
2086
4709
|
pluginContainer,
|
|
2087
4710
|
moduleGraph
|
|
2088
4711
|
}));
|
|
2089
|
-
const publicDir =
|
|
4712
|
+
const publicDir = path14.resolve(config.root, "public");
|
|
2090
4713
|
app.use(sirv(publicDir, { dev: true, etag: true }));
|
|
2091
4714
|
app.use(sirv(config.root, { dev: true, etag: true }));
|
|
2092
|
-
const httpServer = http.createServer(app);
|
|
2093
|
-
const ws = createWebSocketServer(httpServer);
|
|
2094
4715
|
const ignoredSegments = /* @__PURE__ */ new Set(["node_modules", ".git", ".nasti"]);
|
|
2095
|
-
const outDirAbs =
|
|
4716
|
+
const outDirAbs = path14.resolve(config.root, config.build.outDir);
|
|
2096
4717
|
const watcher = watch(config.root, {
|
|
2097
4718
|
ignored: (filePath) => {
|
|
2098
4719
|
if (filePath === config.root) return false;
|
|
2099
|
-
if (filePath === outDirAbs || filePath.startsWith(outDirAbs +
|
|
2100
|
-
const rel =
|
|
2101
|
-
if (!rel || rel.startsWith("..") ||
|
|
2102
|
-
for (const seg of rel.split(
|
|
4720
|
+
if (filePath === outDirAbs || filePath.startsWith(outDirAbs + path14.sep)) return true;
|
|
4721
|
+
const rel = path14.relative(config.root, filePath);
|
|
4722
|
+
if (!rel || rel.startsWith("..") || path14.isAbsolute(rel)) return false;
|
|
4723
|
+
for (const seg of rel.split(path14.sep)) {
|
|
2103
4724
|
if (ignoredSegments.has(seg)) return true;
|
|
2104
4725
|
}
|
|
2105
4726
|
return false;
|
|
@@ -2108,9 +4729,11 @@ async function createServer(inlineConfig = {}) {
|
|
|
2108
4729
|
});
|
|
2109
4730
|
let server;
|
|
2110
4731
|
watcher.on("change", (file) => {
|
|
4732
|
+
ssrRunner?.invalidateFile(file);
|
|
2111
4733
|
handleFileChange(file, server);
|
|
2112
4734
|
});
|
|
2113
4735
|
watcher.on("add", (file) => {
|
|
4736
|
+
ssrRunner?.invalidateFile(file);
|
|
2114
4737
|
handleFileChange(file, server);
|
|
2115
4738
|
});
|
|
2116
4739
|
server = {
|
|
@@ -2119,6 +4742,7 @@ async function createServer(inlineConfig = {}) {
|
|
|
2119
4742
|
moduleGraph,
|
|
2120
4743
|
watcher,
|
|
2121
4744
|
ws,
|
|
4745
|
+
environments,
|
|
2122
4746
|
async listen(port) {
|
|
2123
4747
|
const finalPort = port ?? config.server.port;
|
|
2124
4748
|
const host = config.server.host === true ? "0.0.0.0" : config.server.host;
|
|
@@ -2128,23 +4752,27 @@ async function createServer(inlineConfig = {}) {
|
|
|
2128
4752
|
const onListening = () => {
|
|
2129
4753
|
const actualPort = httpServer.address()?.port ?? currentPort;
|
|
2130
4754
|
config.server.port = actualPort;
|
|
2131
|
-
const localUrl = `http://localhost:${actualPort}
|
|
2132
|
-
const networkUrl = host === "0.0.0.0" ? `http://${getNetworkAddress()}:${actualPort}
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
4755
|
+
const localUrl = `http://localhost:${actualPort}/`;
|
|
4756
|
+
const networkUrl = host === "0.0.0.0" ? `http://${getNetworkAddress()}:${actualPort}/` : null;
|
|
4757
|
+
logger.clearScreen("info");
|
|
4758
|
+
const readyIn = Math.ceil(performance.now() - startTime);
|
|
4759
|
+
logger.info(
|
|
4760
|
+
`
|
|
4761
|
+
${pc8.cyan(pc8.bold("NASTI"))} ${pc8.cyan(`v${"2.0.1"}`)} ${pc8.dim("ready in")} ${pc8.bold(readyIn)} ${pc8.dim("ms")}
|
|
4762
|
+
`
|
|
4763
|
+
);
|
|
4764
|
+
printServerUrls(
|
|
4765
|
+
{ local: [localUrl], network: networkUrl ? [networkUrl] : [] },
|
|
4766
|
+
logger.info
|
|
4767
|
+
);
|
|
4768
|
+
logger.info("");
|
|
2141
4769
|
resolve(server);
|
|
2142
4770
|
};
|
|
2143
4771
|
httpServer.on("listening", onListening);
|
|
2144
4772
|
httpServer.on("error", (err) => {
|
|
2145
4773
|
if (err.code === "EADDRINUSE") {
|
|
2146
4774
|
currentPort++;
|
|
2147
|
-
|
|
4775
|
+
logger.info(pc8.yellow(`Port ${currentPort - 1} is in use, trying ${currentPort}...`));
|
|
2148
4776
|
httpServer.listen(currentPort, host);
|
|
2149
4777
|
} else {
|
|
2150
4778
|
reject(err);
|
|
@@ -2157,8 +4785,13 @@ async function createServer(inlineConfig = {}) {
|
|
|
2157
4785
|
const { transformRequest: transformRequest2 } = await Promise.resolve().then(() => (init_middleware(), middleware_exports));
|
|
2158
4786
|
return transformRequest2(url, { config: configWithPlugins, pluginContainer, moduleGraph });
|
|
2159
4787
|
},
|
|
4788
|
+
async ssrLoadModule(url) {
|
|
4789
|
+
const runner = await getSsrRunner();
|
|
4790
|
+
return runner.import(url);
|
|
4791
|
+
},
|
|
2160
4792
|
async close() {
|
|
2161
4793
|
await pluginContainer.buildEnd();
|
|
4794
|
+
await bundledServer?.close();
|
|
2162
4795
|
watcher.close();
|
|
2163
4796
|
ws.close();
|
|
2164
4797
|
httpServer.close();
|
|
@@ -2191,25 +4824,22 @@ var init_server = __esm({
|
|
|
2191
4824
|
"src/server/index.ts"() {
|
|
2192
4825
|
"use strict";
|
|
2193
4826
|
init_config();
|
|
2194
|
-
|
|
2195
|
-
|
|
4827
|
+
init_environment();
|
|
4828
|
+
init_hot_channel();
|
|
4829
|
+
init_logger();
|
|
2196
4830
|
init_ws();
|
|
2197
4831
|
init_middleware();
|
|
2198
4832
|
init_hmr();
|
|
2199
|
-
|
|
2200
|
-
init_css();
|
|
2201
|
-
init_assets();
|
|
2202
|
-
init_vue();
|
|
2203
|
-
init_html();
|
|
4833
|
+
init_builtins();
|
|
2204
4834
|
}
|
|
2205
4835
|
});
|
|
2206
4836
|
|
|
2207
4837
|
// src/plugins/electron.ts
|
|
2208
|
-
import { builtinModules } from "module";
|
|
4838
|
+
import { builtinModules as builtinModules3 } from "module";
|
|
2209
4839
|
function electronPlugin(config) {
|
|
2210
4840
|
const external = /* @__PURE__ */ new Set([
|
|
2211
4841
|
...ELECTRON_MODULES,
|
|
2212
|
-
...
|
|
4842
|
+
...NODE_BUILTINS3,
|
|
2213
4843
|
...config.electron.external ?? []
|
|
2214
4844
|
]);
|
|
2215
4845
|
return {
|
|
@@ -2226,13 +4856,13 @@ function electronPlugin(config) {
|
|
|
2226
4856
|
}
|
|
2227
4857
|
};
|
|
2228
4858
|
}
|
|
2229
|
-
var
|
|
4859
|
+
var NODE_BUILTINS3, ELECTRON_MODULES;
|
|
2230
4860
|
var init_electron = __esm({
|
|
2231
4861
|
"src/plugins/electron.ts"() {
|
|
2232
4862
|
"use strict";
|
|
2233
|
-
|
|
2234
|
-
...
|
|
2235
|
-
...
|
|
4863
|
+
NODE_BUILTINS3 = /* @__PURE__ */ new Set([
|
|
4864
|
+
...builtinModules3,
|
|
4865
|
+
...builtinModules3.map((m) => `node:${m}`)
|
|
2236
4866
|
]);
|
|
2237
4867
|
ELECTRON_MODULES = /* @__PURE__ */ new Set([
|
|
2238
4868
|
"electron",
|
|
@@ -2243,179 +4873,6 @@ var init_electron = __esm({
|
|
|
2243
4873
|
}
|
|
2244
4874
|
});
|
|
2245
4875
|
|
|
2246
|
-
// src/build/index.ts
|
|
2247
|
-
var build_exports = {};
|
|
2248
|
-
__export(build_exports, {
|
|
2249
|
-
build: () => build
|
|
2250
|
-
});
|
|
2251
|
-
import path11 from "path";
|
|
2252
|
-
import fs8 from "fs";
|
|
2253
|
-
import { rolldown } from "rolldown";
|
|
2254
|
-
import pc2 from "picocolors";
|
|
2255
|
-
async function build(inlineConfig = {}) {
|
|
2256
|
-
const config = await resolveConfig(inlineConfig, "build");
|
|
2257
|
-
const startTime = performance.now();
|
|
2258
|
-
console.log(pc2.cyan("\n\u{1F528} nasti build") + pc2.dim(` v${"1.7.1"}`));
|
|
2259
|
-
console.log(pc2.dim(` root: ${config.root}`));
|
|
2260
|
-
console.log(pc2.dim(` mode: ${config.mode}`));
|
|
2261
|
-
const outDir = path11.resolve(config.root, config.build.outDir);
|
|
2262
|
-
if (config.build.emptyOutDir && fs8.existsSync(outDir)) {
|
|
2263
|
-
fs8.rmSync(outDir, { recursive: true, force: true });
|
|
2264
|
-
}
|
|
2265
|
-
fs8.mkdirSync(outDir, { recursive: true });
|
|
2266
|
-
const html = await readHtmlFile(config.root);
|
|
2267
|
-
let entryPoints = [];
|
|
2268
|
-
if (html) {
|
|
2269
|
-
const scriptMatches = html.matchAll(/<script[^>]+src=["']([^"']+)["'][^>]*>/gi);
|
|
2270
|
-
for (const match of scriptMatches) {
|
|
2271
|
-
const src = match[1];
|
|
2272
|
-
if (src && !src.startsWith("http")) {
|
|
2273
|
-
entryPoints.push(path11.resolve(config.root, src.replace(/^\//, "")));
|
|
2274
|
-
}
|
|
2275
|
-
}
|
|
2276
|
-
}
|
|
2277
|
-
if (entryPoints.length === 0) {
|
|
2278
|
-
const fallbackEntries = ["src/main.ts", "src/main.tsx", "src/main.js", "src/index.ts", "src/index.tsx", "src/index.js"];
|
|
2279
|
-
for (const entry of fallbackEntries) {
|
|
2280
|
-
const fullPath = path11.resolve(config.root, entry);
|
|
2281
|
-
if (fs8.existsSync(fullPath)) {
|
|
2282
|
-
entryPoints.push(fullPath);
|
|
2283
|
-
break;
|
|
2284
|
-
}
|
|
2285
|
-
}
|
|
2286
|
-
}
|
|
2287
|
-
if (entryPoints.length === 0) {
|
|
2288
|
-
throw new Error("No entry point found. Add a <script> tag to index.html or create src/main.ts");
|
|
2289
|
-
}
|
|
2290
|
-
const builtinPlugins = [
|
|
2291
|
-
...config.framework === "vue" ? [vuePlugin(config)] : [],
|
|
2292
|
-
resolvePlugin(config),
|
|
2293
|
-
cssPlugin(config),
|
|
2294
|
-
assetsPlugin(config)
|
|
2295
|
-
];
|
|
2296
|
-
const allPlugins = [...builtinPlugins, ...config.plugins];
|
|
2297
|
-
const pluginContainer = new PluginContainer(config);
|
|
2298
|
-
await pluginContainer.buildStart();
|
|
2299
|
-
const oxcTransformPlugin = {
|
|
2300
|
-
name: "nasti:oxc-transform",
|
|
2301
|
-
transform(code, id) {
|
|
2302
|
-
if (!shouldTransform(id)) return null;
|
|
2303
|
-
const result = transformCode(id, code, {
|
|
2304
|
-
sourcemap: !!config.build.sourcemap,
|
|
2305
|
-
jsxRuntime: "automatic",
|
|
2306
|
-
jsxImportSource: config.framework === "vue" ? "vue" : "react"
|
|
2307
|
-
});
|
|
2308
|
-
return { code: result.code, map: result.map ? JSON.parse(result.map) : void 0 };
|
|
2309
|
-
}
|
|
2310
|
-
};
|
|
2311
|
-
const env = loadEnv(config.mode, config.root, config.envPrefix);
|
|
2312
|
-
const envDefine = buildEnvDefine(env, config.mode);
|
|
2313
|
-
const { output: userOutput, transform: userTransform, ...restInputOptions } = config.build.rolldownOptions;
|
|
2314
|
-
const vueDefine = config.framework === "vue" ? {
|
|
2315
|
-
__VUE_OPTIONS_API__: "true",
|
|
2316
|
-
__VUE_PROD_DEVTOOLS__: "false",
|
|
2317
|
-
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: "false"
|
|
2318
|
-
} : {};
|
|
2319
|
-
const mergedDefine = { ...vueDefine, ...userTransform?.define ?? {}, ...envDefine };
|
|
2320
|
-
const bundle = await rolldown({
|
|
2321
|
-
...restInputOptions,
|
|
2322
|
-
input: entryPoints,
|
|
2323
|
-
transform: { ...userTransform, define: mergedDefine },
|
|
2324
|
-
plugins: [
|
|
2325
|
-
oxcTransformPlugin,
|
|
2326
|
-
// 转换 Nasti 插件为 Rolldown 插件格式
|
|
2327
|
-
...allPlugins.map((p) => ({
|
|
2328
|
-
name: p.name,
|
|
2329
|
-
resolveId: p.resolveId,
|
|
2330
|
-
load: p.load,
|
|
2331
|
-
transform: p.transform,
|
|
2332
|
-
buildStart: p.buildStart,
|
|
2333
|
-
buildEnd: p.buildEnd,
|
|
2334
|
-
// Forward `closeBundle` to Rolldown — it invokes the hook during
|
|
2335
|
-
// `bundle.close()` below. This is the hook Vite plugins (e.g. PWA
|
|
2336
|
-
// manifest/SW writers) rely on for final-stage artifact emission.
|
|
2337
|
-
closeBundle: p.closeBundle
|
|
2338
|
-
}))
|
|
2339
|
-
]
|
|
2340
|
-
});
|
|
2341
|
-
const { output } = await bundle.write({
|
|
2342
|
-
format: "esm",
|
|
2343
|
-
sourcemap: !!config.build.sourcemap,
|
|
2344
|
-
minify: !!config.build.minify,
|
|
2345
|
-
entryFileNames: "assets/[name].[hash].js",
|
|
2346
|
-
chunkFileNames: "assets/[name].[hash].js",
|
|
2347
|
-
assetFileNames: "assets/[name].[hash][extname]",
|
|
2348
|
-
// 用户可覆盖默认输出:代码拆分(advancedChunks / codeSplitting)、chunk 命名等
|
|
2349
|
-
...userOutput,
|
|
2350
|
-
// dir 始终由 Nasti 掌管 —— 下方 HTML 改写依赖固定的产物目录,故放在最后强制生效
|
|
2351
|
-
dir: outDir
|
|
2352
|
-
});
|
|
2353
|
-
await bundle.close();
|
|
2354
|
-
await pluginContainer.buildEnd();
|
|
2355
|
-
for (const ef of pluginContainer.getEmittedFiles()) {
|
|
2356
|
-
const dest = path11.resolve(outDir, ef.fileName);
|
|
2357
|
-
fs8.mkdirSync(path11.dirname(dest), { recursive: true });
|
|
2358
|
-
fs8.writeFileSync(dest, ef.source);
|
|
2359
|
-
}
|
|
2360
|
-
if (html) {
|
|
2361
|
-
let processedHtml = html;
|
|
2362
|
-
const htmlPlugin_ = htmlPlugin(config);
|
|
2363
|
-
if (htmlPlugin_.transformIndexHtml) {
|
|
2364
|
-
const result = await htmlPlugin_.transformIndexHtml(processedHtml);
|
|
2365
|
-
if (typeof result === "string") {
|
|
2366
|
-
processedHtml = result;
|
|
2367
|
-
} else if (result && "html" in result) {
|
|
2368
|
-
processedHtml = processHtml(result.html, result.tags);
|
|
2369
|
-
} else if (Array.isArray(result)) {
|
|
2370
|
-
processedHtml = processHtml(processedHtml, result);
|
|
2371
|
-
}
|
|
2372
|
-
}
|
|
2373
|
-
for (const chunk of output) {
|
|
2374
|
-
if (chunk.type === "chunk" && chunk.isEntry && chunk.facadeModuleId) {
|
|
2375
|
-
const originalEntry = path11.relative(config.root, chunk.facadeModuleId);
|
|
2376
|
-
processedHtml = processedHtml.replace(
|
|
2377
|
-
new RegExp(`(src=["'])/?(${escapeRegExp(originalEntry)})(["'])`, "g"),
|
|
2378
|
-
`$1${config.base}${chunk.fileName}$3`
|
|
2379
|
-
);
|
|
2380
|
-
}
|
|
2381
|
-
}
|
|
2382
|
-
fs8.writeFileSync(path11.resolve(outDir, "index.html"), processedHtml);
|
|
2383
|
-
}
|
|
2384
|
-
const elapsed = ((performance.now() - startTime) / 1e3).toFixed(2);
|
|
2385
|
-
const totalSize = output.reduce((sum, chunk) => {
|
|
2386
|
-
if (chunk.type === "chunk" && chunk.code) return sum + chunk.code.length;
|
|
2387
|
-
return sum;
|
|
2388
|
-
}, 0);
|
|
2389
|
-
console.log(pc2.green(`
|
|
2390
|
-
\u2713 Built in ${elapsed}s`));
|
|
2391
|
-
console.log(pc2.dim(` ${output.length} files, ${formatSize(totalSize)} total`));
|
|
2392
|
-
console.log(pc2.dim(` output: ${config.build.outDir}/
|
|
2393
|
-
`));
|
|
2394
|
-
return { output };
|
|
2395
|
-
}
|
|
2396
|
-
function formatSize(bytes) {
|
|
2397
|
-
if (bytes < 1024) return `${bytes} B`;
|
|
2398
|
-
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(2)} kB`;
|
|
2399
|
-
return `${(bytes / 1024 / 1024).toFixed(2)} MB`;
|
|
2400
|
-
}
|
|
2401
|
-
function escapeRegExp(string) {
|
|
2402
|
-
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2403
|
-
}
|
|
2404
|
-
var init_build = __esm({
|
|
2405
|
-
"src/build/index.ts"() {
|
|
2406
|
-
"use strict";
|
|
2407
|
-
init_config();
|
|
2408
|
-
init_resolve();
|
|
2409
|
-
init_css();
|
|
2410
|
-
init_assets();
|
|
2411
|
-
init_vue();
|
|
2412
|
-
init_html();
|
|
2413
|
-
init_transformer();
|
|
2414
|
-
init_env();
|
|
2415
|
-
init_plugin_container();
|
|
2416
|
-
}
|
|
2417
|
-
});
|
|
2418
|
-
|
|
2419
4876
|
// src/build/electron.ts
|
|
2420
4877
|
var electron_exports = {};
|
|
2421
4878
|
__export(electron_exports, {
|
|
@@ -2423,24 +4880,24 @@ __export(electron_exports, {
|
|
|
2423
4880
|
detectInstalledElectron: () => detectInstalledElectron,
|
|
2424
4881
|
normalizePreload: () => normalizePreload
|
|
2425
4882
|
});
|
|
2426
|
-
import
|
|
2427
|
-
import
|
|
4883
|
+
import path15 from "path";
|
|
4884
|
+
import fs10 from "fs";
|
|
2428
4885
|
import { rolldown as rolldown2 } from "rolldown";
|
|
2429
|
-
import
|
|
4886
|
+
import pc9 from "picocolors";
|
|
2430
4887
|
async function buildElectron(inlineConfig = {}) {
|
|
2431
4888
|
const config = await resolveConfig({ ...inlineConfig, target: "electron" }, "build");
|
|
2432
4889
|
const startTime = performance.now();
|
|
2433
4890
|
assertElectronVersion(config);
|
|
2434
|
-
console.log(
|
|
2435
|
-
console.log(
|
|
2436
|
-
console.log(
|
|
2437
|
-
console.log(
|
|
2438
|
-
const outDir =
|
|
2439
|
-
if (config.build.emptyOutDir &&
|
|
2440
|
-
|
|
4891
|
+
console.log(pc9.cyan("\n\u26A1 nasti build (electron)") + pc9.dim(` v${"2.0.1"}`));
|
|
4892
|
+
console.log(pc9.dim(` root: ${config.root}`));
|
|
4893
|
+
console.log(pc9.dim(` mode: ${config.mode}`));
|
|
4894
|
+
console.log(pc9.dim(` target: electron (\u2265 ${config.electron.minVersion})`));
|
|
4895
|
+
const outDir = path15.resolve(config.root, config.build.outDir);
|
|
4896
|
+
if (config.build.emptyOutDir && fs10.existsSync(outDir)) {
|
|
4897
|
+
fs10.rmSync(outDir, { recursive: true, force: true });
|
|
2441
4898
|
}
|
|
2442
|
-
|
|
2443
|
-
const rendererOutDir =
|
|
4899
|
+
fs10.mkdirSync(outDir, { recursive: true });
|
|
4900
|
+
const rendererOutDir = path15.join(outDir, "renderer");
|
|
2444
4901
|
const { build: build2 } = await Promise.resolve().then(() => (init_build(), build_exports));
|
|
2445
4902
|
await build2({
|
|
2446
4903
|
...inlineConfig,
|
|
@@ -2451,8 +4908,8 @@ async function buildElectron(inlineConfig = {}) {
|
|
|
2451
4908
|
emptyOutDir: false
|
|
2452
4909
|
}
|
|
2453
4910
|
});
|
|
2454
|
-
const mainEntry =
|
|
2455
|
-
if (!
|
|
4911
|
+
const mainEntry = path15.resolve(config.root, config.electron.main);
|
|
4912
|
+
if (!fs10.existsSync(mainEntry)) {
|
|
2456
4913
|
throw new Error(
|
|
2457
4914
|
`Electron main entry not found: ${config.electron.main}
|
|
2458
4915
|
\u5728 nasti.config.ts \u7684 electron.main \u6307\u5B9A\u4E3B\u8FDB\u7A0B\u5165\u53E3\u6587\u4EF6\u3002`
|
|
@@ -2466,11 +4923,11 @@ async function buildElectron(inlineConfig = {}) {
|
|
|
2466
4923
|
const preloadEntries = normalizePreload(config.electron.preload, config.root);
|
|
2467
4924
|
const preloadFiles = [];
|
|
2468
4925
|
for (const entry of preloadEntries) {
|
|
2469
|
-
if (!
|
|
2470
|
-
console.warn(
|
|
4926
|
+
if (!fs10.existsSync(entry)) {
|
|
4927
|
+
console.warn(pc9.yellow(` \u26A0 preload entry not found, skipped: ${entry}`));
|
|
2471
4928
|
continue;
|
|
2472
4929
|
}
|
|
2473
|
-
const base =
|
|
4930
|
+
const base = path15.basename(entry).replace(/\.[^.]+$/, "");
|
|
2474
4931
|
const out = outFileName(outDir, base, config.electron.preloadFormat);
|
|
2475
4932
|
await bundleNode(config, entry, {
|
|
2476
4933
|
outFile: out,
|
|
@@ -2480,12 +4937,12 @@ async function buildElectron(inlineConfig = {}) {
|
|
|
2480
4937
|
preloadFiles.push(out);
|
|
2481
4938
|
}
|
|
2482
4939
|
const elapsed = ((performance.now() - startTime) / 1e3).toFixed(2);
|
|
2483
|
-
console.log(
|
|
4940
|
+
console.log(pc9.green(`
|
|
2484
4941
|
\u2713 Electron build complete in ${elapsed}s`));
|
|
2485
|
-
console.log(
|
|
2486
|
-
console.log(
|
|
4942
|
+
console.log(pc9.dim(` renderer: ${path15.relative(config.root, rendererOutDir)}/`));
|
|
4943
|
+
console.log(pc9.dim(` main: ${path15.relative(config.root, mainFile)}`));
|
|
2487
4944
|
for (const pf of preloadFiles) {
|
|
2488
|
-
console.log(
|
|
4945
|
+
console.log(pc9.dim(` preload: ${path15.relative(config.root, pf)}`));
|
|
2489
4946
|
}
|
|
2490
4947
|
console.log();
|
|
2491
4948
|
return { rendererOutDir, mainFile, preloadFiles };
|
|
@@ -2511,15 +4968,15 @@ async function bundleNode(config, entry, opts) {
|
|
|
2511
4968
|
};
|
|
2512
4969
|
const { output: userOutput, transform: userTransform, ...restInputOptions } = config.build.rolldownOptions;
|
|
2513
4970
|
const mergedDefine = { ...userTransform?.define ?? {}, ...envDefine };
|
|
2514
|
-
const
|
|
4971
|
+
const bundle2 = await rolldown2({
|
|
2515
4972
|
...restInputOptions,
|
|
2516
4973
|
input: entry,
|
|
2517
4974
|
platform: "node",
|
|
2518
4975
|
transform: { ...userTransform, define: mergedDefine },
|
|
2519
4976
|
plugins: [oxcTransformPlugin, electronPlugin(config), resolvePlugin(config)]
|
|
2520
4977
|
});
|
|
2521
|
-
|
|
2522
|
-
await
|
|
4978
|
+
fs10.mkdirSync(path15.dirname(opts.outFile), { recursive: true });
|
|
4979
|
+
await bundle2.write({
|
|
2523
4980
|
sourcemap: !!config.build.sourcemap,
|
|
2524
4981
|
minify: !!config.build.minify,
|
|
2525
4982
|
// 允许用户微调 output;但主进程 / preload 的单文件约束由下方键强制保证
|
|
@@ -2528,24 +4985,24 @@ async function bundleNode(config, entry, opts) {
|
|
|
2528
4985
|
format: opts.format === "cjs" ? "cjs" : "esm",
|
|
2529
4986
|
codeSplitting: false
|
|
2530
4987
|
});
|
|
2531
|
-
await
|
|
2532
|
-
console.log(
|
|
4988
|
+
await bundle2.close();
|
|
4989
|
+
console.log(pc9.dim(` \u2713 ${opts.label} \u2192 ${path15.relative(config.root, opts.outFile)}`));
|
|
2533
4990
|
return opts.outFile;
|
|
2534
4991
|
}
|
|
2535
4992
|
function outFileName(outDir, base, format) {
|
|
2536
4993
|
const ext = format === "cjs" ? ".cjs" : ".mjs";
|
|
2537
|
-
return
|
|
4994
|
+
return path15.join(outDir, base + ext);
|
|
2538
4995
|
}
|
|
2539
4996
|
function normalizePreload(preload, root) {
|
|
2540
4997
|
const list = Array.isArray(preload) ? preload : preload ? [preload] : [];
|
|
2541
|
-
return list.map((p) =>
|
|
4998
|
+
return list.map((p) => path15.resolve(root, p));
|
|
2542
4999
|
}
|
|
2543
5000
|
function assertElectronVersion(config) {
|
|
2544
5001
|
const min = config.electron.minVersion;
|
|
2545
5002
|
const installed = detectInstalledElectron(config.root);
|
|
2546
5003
|
if (installed && installed < min) {
|
|
2547
5004
|
console.warn(
|
|
2548
|
-
|
|
5005
|
+
pc9.yellow(
|
|
2549
5006
|
` \u26A0 \u68C0\u6D4B\u5230 Electron ${installed}\uFF0CNasti \u8981\u6C42 \u2265 ${min}\u3002\u65E7\u7248\u672C\u53EF\u80FD\u7F3A\u5C11 ESM \u4E3B\u8FDB\u7A0B\u652F\u6301\u3002`
|
|
2550
5007
|
)
|
|
2551
5008
|
);
|
|
@@ -2553,9 +5010,9 @@ function assertElectronVersion(config) {
|
|
|
2553
5010
|
}
|
|
2554
5011
|
function detectInstalledElectron(root) {
|
|
2555
5012
|
try {
|
|
2556
|
-
const pkgPath =
|
|
2557
|
-
if (!
|
|
2558
|
-
const pkg = JSON.parse(
|
|
5013
|
+
const pkgPath = path15.resolve(root, "node_modules/electron/package.json");
|
|
5014
|
+
if (!fs10.existsSync(pkgPath)) return null;
|
|
5015
|
+
const pkg = JSON.parse(fs10.readFileSync(pkgPath, "utf-8"));
|
|
2559
5016
|
const major = parseInt(String(pkg.version).split(".")[0], 10);
|
|
2560
5017
|
return Number.isFinite(major) ? major : null;
|
|
2561
5018
|
} catch {
|
|
@@ -2578,28 +5035,28 @@ var electron_dev_exports = {};
|
|
|
2578
5035
|
__export(electron_dev_exports, {
|
|
2579
5036
|
startElectronDev: () => startElectronDev
|
|
2580
5037
|
});
|
|
2581
|
-
import
|
|
2582
|
-
import
|
|
2583
|
-
import { createRequire as
|
|
5038
|
+
import path16 from "path";
|
|
5039
|
+
import fs11 from "fs";
|
|
5040
|
+
import { createRequire as createRequire5 } from "module";
|
|
2584
5041
|
import { spawn } from "child_process";
|
|
2585
5042
|
import chokidar from "chokidar";
|
|
2586
|
-
import
|
|
5043
|
+
import pc10 from "picocolors";
|
|
2587
5044
|
import { rolldown as rolldown3 } from "rolldown";
|
|
2588
5045
|
async function startElectronDev(inlineConfig = {}) {
|
|
2589
5046
|
const { noSpawn, ...rest } = inlineConfig;
|
|
2590
5047
|
const config = await resolveConfig({ ...rest, target: "electron" }, "serve");
|
|
2591
5048
|
warnElectronVersion(config);
|
|
2592
|
-
console.log(
|
|
5049
|
+
console.log(pc10.cyan("\n\u26A1 nasti electron dev") + pc10.dim(` v${"2.0.1"}`));
|
|
2593
5050
|
const { createServer: createServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
|
|
2594
5051
|
const server = await createServer2({ ...rest, target: "electron" });
|
|
2595
5052
|
await server.listen();
|
|
2596
5053
|
const devUrl = `http://localhost:${server.config.server.port}/`;
|
|
2597
|
-
console.log(
|
|
2598
|
-
const stageDir =
|
|
2599
|
-
|
|
2600
|
-
const mainEntry =
|
|
5054
|
+
console.log(pc10.dim(` renderer: ${devUrl}`));
|
|
5055
|
+
const stageDir = path16.resolve(config.root, ".nasti");
|
|
5056
|
+
fs11.mkdirSync(stageDir, { recursive: true });
|
|
5057
|
+
const mainEntry = path16.resolve(config.root, config.electron.main);
|
|
2601
5058
|
const preloadEntries = normalizePreload(config.electron.preload, config.root);
|
|
2602
|
-
const builtMainFile =
|
|
5059
|
+
const builtMainFile = path16.join(stageDir, "main" + extFor(config.electron.mainFormat));
|
|
2603
5060
|
const builtPreloadFiles = [];
|
|
2604
5061
|
const compileAll = async () => {
|
|
2605
5062
|
await compileNode(config, mainEntry, {
|
|
@@ -2609,9 +5066,9 @@ async function startElectronDev(inlineConfig = {}) {
|
|
|
2609
5066
|
});
|
|
2610
5067
|
builtPreloadFiles.length = 0;
|
|
2611
5068
|
for (const entry of preloadEntries) {
|
|
2612
|
-
if (!
|
|
2613
|
-
const base =
|
|
2614
|
-
const out =
|
|
5069
|
+
if (!fs11.existsSync(entry)) continue;
|
|
5070
|
+
const base = path16.basename(entry).replace(/\.[^.]+$/, "");
|
|
5071
|
+
const out = path16.join(stageDir, base + extFor(config.electron.preloadFormat));
|
|
2615
5072
|
await compileNode(config, entry, {
|
|
2616
5073
|
outFile: out,
|
|
2617
5074
|
format: config.electron.preloadFormat,
|
|
@@ -2622,13 +5079,13 @@ async function startElectronDev(inlineConfig = {}) {
|
|
|
2622
5079
|
};
|
|
2623
5080
|
await compileAll();
|
|
2624
5081
|
if (noSpawn) {
|
|
2625
|
-
console.log(
|
|
5082
|
+
console.log(pc10.dim(" (noSpawn) \u5DF2\u7F16\u8BD1\u4E3B/preload\uFF0C\u8DF3\u8FC7\u542F\u52A8 Electron\u3002"));
|
|
2626
5083
|
return;
|
|
2627
5084
|
}
|
|
2628
5085
|
const electronBin = resolveElectronBinary(config);
|
|
2629
5086
|
if (!electronBin) {
|
|
2630
5087
|
console.warn(
|
|
2631
|
-
|
|
5088
|
+
pc10.yellow(
|
|
2632
5089
|
" \u26A0 \u672A\u627E\u5230 Electron \u53EF\u6267\u884C\u6587\u4EF6\uFF0C\u8BF7\u5148\u5B89\u88C5\uFF1Anpm install -D electron\n \u5DF2\u7F16\u8BD1\u4E3B/preload \u81F3 .nasti/\uFF0C\u53EF\u624B\u52A8\u8FD0\u884C\u3002"
|
|
2633
5090
|
)
|
|
2634
5091
|
);
|
|
@@ -2643,14 +5100,14 @@ async function startElectronDev(inlineConfig = {}) {
|
|
|
2643
5100
|
});
|
|
2644
5101
|
child.on("exit", (code) => {
|
|
2645
5102
|
if (code !== null && child && child.__nastiKilled !== true) {
|
|
2646
|
-
console.log(
|
|
5103
|
+
console.log(pc10.dim(` Electron exited (${code}).`));
|
|
2647
5104
|
process.exit(code ?? 0);
|
|
2648
5105
|
}
|
|
2649
5106
|
});
|
|
2650
5107
|
};
|
|
2651
5108
|
spawnElectron();
|
|
2652
5109
|
if (config.electron.autoRestart) {
|
|
2653
|
-
const watchTargets = [mainEntry, ...preloadEntries].filter(
|
|
5110
|
+
const watchTargets = [mainEntry, ...preloadEntries].filter(fs11.existsSync);
|
|
2654
5111
|
const watcher = chokidar.watch(watchTargets, { ignoreInitial: true });
|
|
2655
5112
|
let restarting = null;
|
|
2656
5113
|
let pending = false;
|
|
@@ -2662,7 +5119,7 @@ async function startElectronDev(inlineConfig = {}) {
|
|
|
2662
5119
|
restarting = (async () => {
|
|
2663
5120
|
do {
|
|
2664
5121
|
pending = false;
|
|
2665
|
-
console.log(
|
|
5122
|
+
console.log(pc10.cyan("\n \u267B \u4E3B/preload \u53D8\u66F4\uFF0C\u91CD\u542F Electron..."));
|
|
2666
5123
|
if (child && !child.killed) {
|
|
2667
5124
|
;
|
|
2668
5125
|
child.__nastiKilled = true;
|
|
@@ -2680,7 +5137,7 @@ async function startElectronDev(inlineConfig = {}) {
|
|
|
2680
5137
|
await compileAll();
|
|
2681
5138
|
spawnElectron();
|
|
2682
5139
|
} catch (e) {
|
|
2683
|
-
console.warn(
|
|
5140
|
+
console.warn(pc10.yellow(` \u26A0 \u91CD\u542F\u7F16\u8BD1\u5931\u8D25\uFF0C\u4FDD\u7559\u4E0A\u4E00\u6B21\u8FDB\u7A0B: ${e.message}`));
|
|
2684
5141
|
}
|
|
2685
5142
|
} while (pending);
|
|
2686
5143
|
restarting = null;
|
|
@@ -2720,14 +5177,14 @@ async function compileNode(config, entry, opts) {
|
|
|
2720
5177
|
return { code: result.code, map: result.map ? JSON.parse(result.map) : void 0 };
|
|
2721
5178
|
}
|
|
2722
5179
|
};
|
|
2723
|
-
const
|
|
5180
|
+
const bundle2 = await rolldown3({
|
|
2724
5181
|
input: entry,
|
|
2725
5182
|
transform: { define: envDefine },
|
|
2726
5183
|
platform: "node",
|
|
2727
5184
|
plugins: [oxcTransformPlugin, electronPlugin(config), resolvePlugin(config)]
|
|
2728
5185
|
});
|
|
2729
|
-
|
|
2730
|
-
await
|
|
5186
|
+
fs11.mkdirSync(path16.dirname(opts.outFile), { recursive: true });
|
|
5187
|
+
await bundle2.write({
|
|
2731
5188
|
file: opts.outFile,
|
|
2732
5189
|
format: opts.format === "cjs" ? "cjs" : "esm",
|
|
2733
5190
|
sourcemap: false,
|
|
@@ -2736,17 +5193,17 @@ async function compileNode(config, entry, opts) {
|
|
|
2736
5193
|
// 同样语义(单 chunk、内联 dynamic import)
|
|
2737
5194
|
codeSplitting: false
|
|
2738
5195
|
});
|
|
2739
|
-
await
|
|
5196
|
+
await bundle2.close();
|
|
2740
5197
|
}
|
|
2741
5198
|
function resolveElectronBinary(config) {
|
|
2742
|
-
if (config.electron.electronPath &&
|
|
5199
|
+
if (config.electron.electronPath && fs11.existsSync(config.electron.electronPath)) {
|
|
2743
5200
|
return config.electron.electronPath;
|
|
2744
5201
|
}
|
|
2745
5202
|
try {
|
|
2746
|
-
const require2 =
|
|
5203
|
+
const require2 = createRequire5(path16.resolve(config.root, "package.json"));
|
|
2747
5204
|
const pathFile = require2.resolve("electron");
|
|
2748
5205
|
const electronModule = require2(pathFile);
|
|
2749
|
-
if (typeof electronModule === "string" &&
|
|
5206
|
+
if (typeof electronModule === "string" && fs11.existsSync(electronModule)) {
|
|
2750
5207
|
return electronModule;
|
|
2751
5208
|
}
|
|
2752
5209
|
} catch {
|
|
@@ -2757,7 +5214,7 @@ function warnElectronVersion(config) {
|
|
|
2757
5214
|
const installed = detectInstalledElectron(config.root);
|
|
2758
5215
|
if (installed === null) {
|
|
2759
5216
|
console.warn(
|
|
2760
|
-
|
|
5217
|
+
pc10.yellow(
|
|
2761
5218
|
` \u26A0 \u672A\u68C0\u6D4B\u5230 Electron\uFF0C\u8BF7\u5B89\u88C5\uFF1Anpm install -D electron@^${config.electron.minVersion}`
|
|
2762
5219
|
)
|
|
2763
5220
|
);
|
|
@@ -2765,7 +5222,7 @@ function warnElectronVersion(config) {
|
|
|
2765
5222
|
}
|
|
2766
5223
|
if (installed < config.electron.minVersion) {
|
|
2767
5224
|
console.warn(
|
|
2768
|
-
|
|
5225
|
+
pc10.yellow(
|
|
2769
5226
|
` \u26A0 Electron ${installed} \u4F4E\u4E8E Nasti \u8981\u6C42\u7684 ${config.electron.minVersion}\uFF0C\u67D0\u4E9B\u7279\u6027\uFF08\u5982 ESM \u4E3B\u8FDB\u7A0B\uFF09\u4E0D\u53EF\u7528\u3002`
|
|
2770
5227
|
)
|
|
2771
5228
|
);
|
|
@@ -2784,15 +5241,48 @@ var init_electron_dev = __esm({
|
|
|
2784
5241
|
});
|
|
2785
5242
|
|
|
2786
5243
|
// src/cli.ts
|
|
5244
|
+
init_logger();
|
|
2787
5245
|
import { cac } from "cac";
|
|
2788
|
-
import
|
|
5246
|
+
import pc11 from "picocolors";
|
|
2789
5247
|
var cli = cac("nasti");
|
|
2790
|
-
|
|
5248
|
+
function setupDebug(options) {
|
|
5249
|
+
if (options.debug || options.verbose) {
|
|
5250
|
+
const namespaces = typeof options.debug === "string" ? options.debug.split(",").map((s) => s.includes(":") ? s : `nasti:${s}`).join(",") : "nasti:*";
|
|
5251
|
+
process.env.DEBUG = process.env.DEBUG ? `${process.env.DEBUG},${namespaces}` : namespaces;
|
|
5252
|
+
}
|
|
5253
|
+
if (options.filter) {
|
|
5254
|
+
process.env.NASTI_DEBUG_FILTER = options.filter;
|
|
5255
|
+
}
|
|
5256
|
+
}
|
|
5257
|
+
function createCliLogger(options) {
|
|
5258
|
+
return createLogger(options.logLevel ?? "info", {
|
|
5259
|
+
allowClearScreen: options.clearScreen !== false
|
|
5260
|
+
});
|
|
5261
|
+
}
|
|
5262
|
+
function logCliError(logger, prefix, err) {
|
|
5263
|
+
const error = err instanceof Error ? err : new Error(typeof err === "string" ? err : String(err));
|
|
5264
|
+
if (!logger.hasErrorLogged(error)) {
|
|
5265
|
+
logger.error(pc11.red(`
|
|
5266
|
+
${prefix}:
|
|
5267
|
+
${error.message}
|
|
5268
|
+
`), { error });
|
|
5269
|
+
if (error.stack) logger.error(pc11.dim(error.stack));
|
|
5270
|
+
}
|
|
5271
|
+
process.exit(1);
|
|
5272
|
+
}
|
|
5273
|
+
cli.option("--logLevel <level>", "Log level: info | warn | error | silent").option("--clearScreen", "Allow/disable clear screen when logging", { default: true }).option("-d, --debug [namespaces]", "Show debug logs (e.g. -d build,hmr)").option("-f, --filter <filter>", "Filter debug logs by content").option("--verbose", "Shorthand for --debug (all nasti:* namespaces)");
|
|
5274
|
+
cli.command("[root]", "Start dev server").alias("dev").option("--port <port>", "Port number", { default: 3e3 }).option("--host [host]", "Hostname").option("--open [path]", "Open browser on startup").option("--mode <mode>", "Set env mode").option("--bundle", "Experimental: serve a full in-memory bundle via the Rolldown dev engine").action(async (root, options) => {
|
|
5275
|
+
setupDebug(options);
|
|
5276
|
+
const logger = createCliLogger(options);
|
|
2791
5277
|
try {
|
|
2792
5278
|
const { createServer: createServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
|
|
2793
5279
|
const server = await createServer2({
|
|
2794
5280
|
root: root ?? ".",
|
|
2795
5281
|
mode: options.mode ?? "development",
|
|
5282
|
+
logLevel: options.logLevel,
|
|
5283
|
+
clearScreen: options.clearScreen,
|
|
5284
|
+
customLogger: logger,
|
|
5285
|
+
...options.bundle ? { experimental: { bundledDev: true } } : {},
|
|
2796
5286
|
server: {
|
|
2797
5287
|
port: options.port,
|
|
2798
5288
|
host: options.host,
|
|
@@ -2801,15 +5291,12 @@ cli.command("[root]", "Start dev server").alias("dev").option("--port <port>", "
|
|
|
2801
5291
|
});
|
|
2802
5292
|
await server.listen();
|
|
2803
5293
|
} catch (err) {
|
|
2804
|
-
|
|
2805
|
-
Error starting dev server:
|
|
2806
|
-
${err.message}
|
|
2807
|
-
`));
|
|
2808
|
-
if (err.stack) console.error(pc5.dim(err.stack));
|
|
2809
|
-
process.exit(1);
|
|
5294
|
+
logCliError(logger, "Error starting dev server", err);
|
|
2810
5295
|
}
|
|
2811
5296
|
});
|
|
2812
5297
|
cli.command("build [root]", "Build for production").option("--outDir <dir>", "Output directory", { default: "dist" }).option("--sourcemap", "Generate source map").option("--minify", "Minify output", { default: true }).option("--mode <mode>", "Set env mode").option("--target <target>", "Build target: web | electron", { default: "web" }).action(async (root, options) => {
|
|
5298
|
+
setupDebug(options);
|
|
5299
|
+
const logger = createCliLogger(options);
|
|
2813
5300
|
try {
|
|
2814
5301
|
const target = options.target;
|
|
2815
5302
|
if (target !== "web" && target !== "electron") {
|
|
@@ -2819,6 +5306,9 @@ cli.command("build [root]", "Build for production").option("--outDir <dir>", "Ou
|
|
|
2819
5306
|
root: root ?? ".",
|
|
2820
5307
|
mode: options.mode ?? "production",
|
|
2821
5308
|
target,
|
|
5309
|
+
logLevel: options.logLevel,
|
|
5310
|
+
clearScreen: options.clearScreen,
|
|
5311
|
+
customLogger: logger,
|
|
2822
5312
|
build: {
|
|
2823
5313
|
outDir: options.outDir,
|
|
2824
5314
|
sourcemap: options.sourcemap,
|
|
@@ -2833,21 +5323,21 @@ cli.command("build [root]", "Build for production").option("--outDir <dir>", "Ou
|
|
|
2833
5323
|
await build2(inline);
|
|
2834
5324
|
}
|
|
2835
5325
|
} catch (err) {
|
|
2836
|
-
|
|
2837
|
-
Build failed:
|
|
2838
|
-
${err.message}
|
|
2839
|
-
`));
|
|
2840
|
-
if (err.stack) console.error(pc5.dim(err.stack));
|
|
2841
|
-
process.exit(1);
|
|
5326
|
+
logCliError(logger, "Build failed", err);
|
|
2842
5327
|
}
|
|
2843
5328
|
});
|
|
2844
5329
|
cli.command("electron [root]", "Start Electron dev mode (requires electron ^41)").alias("electron-dev").option("--port <port>", "Renderer dev server port", { default: 3e3 }).option("--host [host]", "Hostname").option("--mode <mode>", "Set env mode").option("--no-spawn", "Compile main/preload but do not spawn Electron").option("--no-restart", "Disable auto-restart on main/preload changes").action(async (root, options) => {
|
|
5330
|
+
setupDebug(options);
|
|
5331
|
+
const logger = createCliLogger(options);
|
|
2845
5332
|
try {
|
|
2846
5333
|
const { startElectronDev: startElectronDev2 } = await Promise.resolve().then(() => (init_electron_dev(), electron_dev_exports));
|
|
2847
5334
|
await startElectronDev2({
|
|
2848
5335
|
root: root ?? ".",
|
|
2849
5336
|
mode: options.mode ?? "development",
|
|
2850
5337
|
target: "electron",
|
|
5338
|
+
logLevel: options.logLevel,
|
|
5339
|
+
clearScreen: options.clearScreen,
|
|
5340
|
+
customLogger: logger,
|
|
2851
5341
|
server: {
|
|
2852
5342
|
port: options.port,
|
|
2853
5343
|
host: options.host
|
|
@@ -2858,21 +5348,21 @@ cli.command("electron [root]", "Start Electron dev mode (requires electron ^41)"
|
|
|
2858
5348
|
noSpawn: options.spawn === false
|
|
2859
5349
|
});
|
|
2860
5350
|
} catch (err) {
|
|
2861
|
-
|
|
2862
|
-
Electron dev failed:
|
|
2863
|
-
${err.message}
|
|
2864
|
-
`));
|
|
2865
|
-
if (err.stack) console.error(pc5.dim(err.stack));
|
|
2866
|
-
process.exit(1);
|
|
5351
|
+
logCliError(logger, "Electron dev failed", err);
|
|
2867
5352
|
}
|
|
2868
5353
|
});
|
|
2869
5354
|
cli.command("electron-build [root]", "Build Electron app for production").option("--outDir <dir>", "Output directory", { default: "dist" }).option("--sourcemap", "Generate source map").option("--minify", "Minify output", { default: true }).option("--mode <mode>", "Set env mode").action(async (root, options) => {
|
|
5355
|
+
setupDebug(options);
|
|
5356
|
+
const logger = createCliLogger(options);
|
|
2870
5357
|
try {
|
|
2871
5358
|
const { buildElectron: buildElectron2 } = await Promise.resolve().then(() => (init_electron2(), electron_exports));
|
|
2872
5359
|
await buildElectron2({
|
|
2873
5360
|
root: root ?? ".",
|
|
2874
5361
|
mode: options.mode ?? "production",
|
|
2875
5362
|
target: "electron",
|
|
5363
|
+
logLevel: options.logLevel,
|
|
5364
|
+
clearScreen: options.clearScreen,
|
|
5365
|
+
customLogger: logger,
|
|
2876
5366
|
build: {
|
|
2877
5367
|
outDir: options.outDir,
|
|
2878
5368
|
sourcemap: options.sourcemap,
|
|
@@ -2880,42 +5370,44 @@ cli.command("electron-build [root]", "Build Electron app for production").option
|
|
|
2880
5370
|
}
|
|
2881
5371
|
});
|
|
2882
5372
|
} catch (err) {
|
|
2883
|
-
|
|
2884
|
-
Electron build failed:
|
|
2885
|
-
${err.message}
|
|
2886
|
-
`));
|
|
2887
|
-
if (err.stack) console.error(pc5.dim(err.stack));
|
|
2888
|
-
process.exit(1);
|
|
5373
|
+
logCliError(logger, "Electron build failed", err);
|
|
2889
5374
|
}
|
|
2890
5375
|
});
|
|
2891
5376
|
cli.command("preview [root]", "Preview production build").option("--port <port>", "Port number", { default: 4173 }).option("--host [host]", "Hostname").option("--outDir <dir>", "Output directory to serve", { default: "dist" }).action(async (root, options) => {
|
|
5377
|
+
setupDebug(options);
|
|
5378
|
+
const logger = createCliLogger(options);
|
|
2892
5379
|
try {
|
|
2893
5380
|
const http2 = await import("http");
|
|
2894
|
-
const
|
|
5381
|
+
const path17 = await import("path");
|
|
5382
|
+
const os2 = await import("os");
|
|
2895
5383
|
const sirv2 = (await import("sirv")).default;
|
|
2896
5384
|
const connect2 = (await import("connect")).default;
|
|
2897
|
-
const
|
|
2898
|
-
const
|
|
5385
|
+
const { printServerUrls: printServerUrls2 } = await Promise.resolve().then(() => (init_logger(), logger_exports));
|
|
5386
|
+
const resolvedRoot = path17.resolve(root ?? ".");
|
|
5387
|
+
const outDir = path17.resolve(resolvedRoot, options.outDir);
|
|
2899
5388
|
const app = connect2();
|
|
2900
5389
|
app.use(sirv2(outDir, { single: true, etag: true, gzip: true, brotli: true }));
|
|
2901
5390
|
const port = options.port;
|
|
2902
5391
|
const host = options.host === true ? "0.0.0.0" : options.host ?? "localhost";
|
|
2903
5392
|
http2.createServer(app).listen(port, host, () => {
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
5393
|
+
logger.info(`
|
|
5394
|
+
${pc11.cyan(pc11.bold("NASTI"))} ${pc11.cyan(`v${"2.0.1"}`)} ${pc11.dim("preview")}
|
|
5395
|
+
`);
|
|
5396
|
+
printServerUrls2(
|
|
5397
|
+
{
|
|
5398
|
+
local: [`http://localhost:${port}/`],
|
|
5399
|
+
// 0.0.0.0 本身不可访问:枚举真实网卡的非内网 IPv4 地址
|
|
5400
|
+
network: host === "0.0.0.0" ? Object.values(os2.networkInterfaces()).flat().filter((i) => i && i.family === "IPv4" && !i.internal).map((i) => `http://${i.address}:${port}/`) : []
|
|
5401
|
+
},
|
|
5402
|
+
logger.info
|
|
5403
|
+
);
|
|
5404
|
+
logger.info("");
|
|
2909
5405
|
});
|
|
2910
5406
|
} catch (err) {
|
|
2911
|
-
|
|
2912
|
-
Preview failed:
|
|
2913
|
-
${err.message}
|
|
2914
|
-
`));
|
|
2915
|
-
process.exit(1);
|
|
5407
|
+
logCliError(logger, "Preview failed", err);
|
|
2916
5408
|
}
|
|
2917
5409
|
});
|
|
2918
5410
|
cli.help();
|
|
2919
|
-
cli.version("
|
|
5411
|
+
cli.version("2.0.1");
|
|
2920
5412
|
cli.parse();
|
|
2921
5413
|
//# sourceMappingURL=cli.js.map
|