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