weapp-vite 7.4.0 → 7.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -3
- package/THIRD_PARTY_NOTICES.md +60 -0
- package/bin/bootstrap.js +14 -1
- package/dist/action-B3YZMA-h.mjs +255 -0
- package/dist/action-BELcDNNv.mjs +139 -0
- package/dist/action-BOk3vGI7.mjs +1110 -0
- package/dist/action-DlC6JYpt.mjs +95 -0
- package/dist/action-zEDY7oh_.mjs +247 -0
- package/dist/adapters-CcHrsYaj.mjs +1 -0
- package/dist/analyze-DN79YOAH.mjs +184 -0
- package/dist/artifacts-BOyC9Fy-.mjs +106 -0
- package/dist/assets-C5_YYXNk.mjs +637 -0
- package/dist/auto-import-components/resolvers.mjs +1 -2
- package/dist/auto-import-presets/wevu-router.mjs +1 -2
- package/dist/auto-import-presets/wevu.mjs +1 -2
- package/dist/auto-routes.mjs +2 -1
- package/dist/budget-CTLOHwgI.d.mts +177 -0
- package/dist/budget-EOeEycc_.mjs +65 -0
- package/dist/builtProject-C29udgXY.mjs +541 -0
- package/dist/chunkStrategy-DY_LZIIe.mjs +1448 -0
- package/dist/classifier-DBJY__kg.mjs +88 -0
- package/dist/cli-acceptance.d.mts +1 -0
- package/dist/cli-acceptance.mjs +21 -0
- package/dist/cli.mjs +519 -5049
- package/dist/compatibility.mjs +1 -2
- package/dist/{config-Dbvj5yK7.d.mts → config-Bf6DWhyb.d.mts} +220 -76
- package/dist/config.d.mts +3 -3
- package/dist/config.mjs +1 -1
- package/dist/{constants-WOsG3Eqd.mjs → constants-DEZdcsMn.mjs} +1 -1
- package/dist/{createContext-UOEgeYnA.mjs → createCompilerContextInstance-aYwi8wQt.mjs} +36862 -32020
- package/dist/createContext-tApLtII-.mjs +15 -0
- package/dist/dashboard/analyze.d.mts +48 -0
- package/dist/dashboard/analyze.mjs +3 -0
- package/dist/dashboard/vite.d.mts +1 -1
- package/dist/dashboard.d.mts +3 -2
- package/dist/dashboard.mjs +1748 -1
- package/dist/dashboardTransport-C_Y6jMp-.mjs +16 -0
- package/dist/dashboardViteBridge-DCGR43aM.mjs +302 -0
- package/dist/dev-C2fgr_Xd.mjs +67 -0
- package/dist/devProvider-D-hTfsEO.mjs +3027 -0
- package/dist/docs/README.md +59 -3
- package/dist/docs/ai-workflows.md +4 -0
- package/dist/docs/doctor.md +38 -0
- package/dist/docs/getting-started.md +3 -1
- package/dist/docs/index.md +3 -1
- package/dist/docs/mcp.md +104 -1
- package/dist/docs/testing.md +29 -2
- package/dist/docs/troubleshooting.md +16 -0
- package/dist/docs/uni-app-component-libraries.md +8 -7
- package/dist/docs/upload.md +40 -3
- package/dist/docs/vite-plugin.md +171 -0
- package/dist/docs/vue-sfc.md +42 -0
- package/dist/docs/weapp-config.md +54 -0
- package/dist/docs/wevu-authoring.md +10 -0
- package/dist/doctor-worker.d.mts +1 -0
- package/dist/doctor-worker.mjs +60 -0
- package/dist/doctor.d.mts +144 -0
- package/dist/doctor.mjs +850 -0
- package/dist/engine-C66J0HLz.mjs +54 -0
- package/dist/eslint.mjs +1 -2
- package/dist/{file-giE9UMZa.mjs → file-CcIOmqhC.mjs} +58 -24
- package/dist/file-DtcteQ4G.mjs +1 -0
- package/dist/files-BqxFIPRp.mjs +45 -0
- package/dist/forwardConsole-B0Reo8Lf.mjs +511 -0
- package/dist/getInstance-BAIaU2y9.mjs +1 -0
- package/dist/getInstance-Dt9IQDKr.mjs +28 -0
- package/dist/history-BIiRCzbq.mjs +784 -0
- package/dist/i18n.d.mts +1 -1
- package/dist/index-D5rgBzYZ.d.mts +740 -0
- package/dist/index.d.mts +12 -10
- package/dist/index.mjs +3 -2
- package/dist/json.d.mts +1 -1
- package/dist/json.mjs +1 -2
- package/dist/lib-DjccSI1B.mjs +143 -0
- package/dist/lifecycle-C36WSbQS.mjs +413 -0
- package/dist/loadConfig-BWIsDXR4.mjs +59 -0
- package/dist/loadConfig-D-BpBgsk.mjs +1 -0
- package/dist/logBuildAppFinish-ChjwATMv.mjs +57 -0
- package/dist/logger-DGn5iEVN.mjs +1 -0
- package/dist/mcp-CYgX9HpO.mjs +86 -0
- package/dist/{mcp-BG6TliEg.mjs → mcp-Cj8Maqo6.mjs} +16 -7
- package/dist/mcp.d.mts +6 -3
- package/dist/mcp.mjs +1 -2
- package/dist/mcpClient-DVLvFLZv.mjs +287 -0
- package/dist/metadata-hwF7QRcS.mjs +59 -0
- package/dist/nodeEnv-BmH8UZPR.mjs +7 -0
- package/dist/openIde-CroqOgk5.mjs +648 -0
- package/dist/options-jqFwfD1G.mjs +34 -0
- package/dist/package-Cmakyy3J.mjs +4 -0
- package/dist/path-CYYIQGS7.mjs +44 -0
- package/dist/{platform-DTWs5QRi.mjs → platform-CnkySBKz.mjs} +1 -1
- package/dist/processCleanup-BQn2kTcK.mjs +19 -0
- package/dist/protocol-Cg6Jdlvb.mjs +141 -0
- package/dist/reader-sh_POQ9-.mjs +93 -0
- package/dist/realpathScope-Tf9mz-fh.mjs +23 -0
- package/dist/report-hyonPGbZ.mjs +107 -0
- package/dist/resolvedId-CiDl7SC1.mjs +60 -0
- package/dist/{resolvers-icNxkpcy.mjs → resolvers-Dod-euqX.mjs} +4 -1
- package/dist/resolvers.mjs +1 -2
- package/dist/runtime-CLUhQsdA.mjs +43 -0
- package/dist/{runtime-Ee2HY6gR.d.mts → runtime-DpVf714f.d.mts} +1 -1
- package/dist/runtime.d.mts +1 -1
- package/dist/runtime.mjs +1 -2
- package/dist/schematics-kO26eQRT.mjs +91 -0
- package/dist/session-D3zsdzIy.mjs +452 -0
- package/dist/test.d.mts +1 -0
- package/dist/test.mjs +204 -45
- package/dist/{types-CgZn5X6j.d.mts → types-D-kfuyVa.d.mts} +1 -2
- package/dist/types-D0FFexRF.d.mts +39 -0
- package/dist/types.d.mts +3 -3
- package/dist/{upload-D0RcEWrq.mjs → upload-DozK8UdN.mjs} +278 -15
- package/dist/upload-worker.mjs +136 -3
- package/dist/utils-Dy51PYAC.mjs +1034 -0
- package/dist/vite.d.mts +9 -0
- package/dist/vite.mjs +309 -0
- package/dist/volar.d.mts +2 -2
- package/dist/web-apis.mjs +1 -2
- package/dist/wxs-BT8btflA.mjs +112 -0
- package/dist/wxs-Z4VQDeJ_.mjs +1 -0
- package/package.json +80 -48
- package/dist/adapters-BwnMMIZR.mjs +0 -2
- package/dist/dashboard-BzaVesmQ.mjs +0 -558
- package/dist/file-D19nbDoN.mjs +0 -2
- package/dist/getInstance-CYF1vl5l.mjs +0 -2
- package/dist/index-DbqVupg0.d.mts +0 -246
- package/dist/logger-mt4mSTqV.mjs +0 -2
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { r as logger_default } from "./logger-DGn5iEVN.mjs";
|
|
2
|
+
import process from "node:process";
|
|
3
|
+
import path from "pathe";
|
|
4
|
+
import { defu } from "@weapp-core/shared";
|
|
5
|
+
import { fs } from "@weapp-core/shared/fs";
|
|
6
|
+
import { generateJs, generateJson, generateWxml, generateWxss } from "@weapp-core/schematics";
|
|
7
|
+
//#region src/schematics.ts
|
|
8
|
+
function composePath(outDir, filename) {
|
|
9
|
+
return `${outDir}${outDir ? "/" : ""}${filename}`;
|
|
10
|
+
}
|
|
11
|
+
const defaultExtensions = {
|
|
12
|
+
js: "js",
|
|
13
|
+
json: "json",
|
|
14
|
+
wxml: "wxml",
|
|
15
|
+
wxss: "wxss"
|
|
16
|
+
};
|
|
17
|
+
function resolveExtension(extension) {
|
|
18
|
+
return extension ? extension.startsWith(".") ? extension : `.${extension}` : "";
|
|
19
|
+
}
|
|
20
|
+
async function readTemplateFile(templatePath, context) {
|
|
21
|
+
const absolutePath = path.isAbsolute(templatePath) ? templatePath : path.resolve(context.cwd, templatePath);
|
|
22
|
+
return fs.readFile(absolutePath, "utf8");
|
|
23
|
+
}
|
|
24
|
+
async function loadTemplate(template, context) {
|
|
25
|
+
if (template === void 0) return;
|
|
26
|
+
if (typeof template === "function") {
|
|
27
|
+
const result = await template(context);
|
|
28
|
+
return result == null ? void 0 : String(result);
|
|
29
|
+
}
|
|
30
|
+
if (typeof template === "string") return readTemplateFile(template, context);
|
|
31
|
+
if ("content" in template && typeof template.content === "string") return template.content;
|
|
32
|
+
if ("path" in template && typeof template.path === "string") return readTemplateFile(template.path, context);
|
|
33
|
+
}
|
|
34
|
+
function resolveTemplate(templates, type, fileType) {
|
|
35
|
+
const scoped = templates?.[type]?.[fileType];
|
|
36
|
+
if (scoped !== void 0) return scoped;
|
|
37
|
+
return templates?.shared?.[fileType];
|
|
38
|
+
}
|
|
39
|
+
async function generate(options) {
|
|
40
|
+
let { fileName, outDir, extensions, type, cwd, templates } = defu(options, {
|
|
41
|
+
type: "component",
|
|
42
|
+
extensions: { ...defaultExtensions },
|
|
43
|
+
cwd: process.cwd(),
|
|
44
|
+
templates: void 0
|
|
45
|
+
});
|
|
46
|
+
if (fileName === void 0) fileName = path.basename(outDir);
|
|
47
|
+
const basepath = path.resolve(cwd, outDir);
|
|
48
|
+
const targetFileTypes = type === "app" ? [
|
|
49
|
+
"js",
|
|
50
|
+
"wxss",
|
|
51
|
+
"json"
|
|
52
|
+
] : [
|
|
53
|
+
"js",
|
|
54
|
+
"wxss",
|
|
55
|
+
"json",
|
|
56
|
+
"wxml"
|
|
57
|
+
];
|
|
58
|
+
const files = [];
|
|
59
|
+
for (const fileType of targetFileTypes) {
|
|
60
|
+
const configuredExt = extensions[fileType] ?? defaultExtensions[fileType];
|
|
61
|
+
let resolvedExt = configuredExt;
|
|
62
|
+
let defaultCode;
|
|
63
|
+
if (fileType === "js") defaultCode = generateJs(type);
|
|
64
|
+
else if (fileType === "wxss") defaultCode = generateWxss();
|
|
65
|
+
else if (fileType === "wxml") defaultCode = generateWxml(path.join(outDir, fileName));
|
|
66
|
+
else if (fileType === "json") {
|
|
67
|
+
defaultCode = generateJson(type, configuredExt);
|
|
68
|
+
if (configuredExt === "js" || configuredExt === "ts") resolvedExt = `json.${configuredExt}`;
|
|
69
|
+
}
|
|
70
|
+
const context = {
|
|
71
|
+
type,
|
|
72
|
+
fileType,
|
|
73
|
+
fileName,
|
|
74
|
+
outDir,
|
|
75
|
+
extension: resolvedExt,
|
|
76
|
+
cwd,
|
|
77
|
+
defaultCode
|
|
78
|
+
};
|
|
79
|
+
const finalCode = await loadTemplate(resolveTemplate(templates, type, fileType), context) ?? defaultCode;
|
|
80
|
+
if (finalCode !== void 0) files.push({
|
|
81
|
+
fileName: `${fileName}${resolveExtension(resolvedExt)}`,
|
|
82
|
+
code: finalCode
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
for (const { code, fileName } of files) if (code !== void 0) {
|
|
86
|
+
await fs.outputFile(path.resolve(basepath, fileName), code, "utf8");
|
|
87
|
+
logger_default.success(`${composePath(outDir, fileName)} 创建成功!`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//#endregion
|
|
91
|
+
export { generate };
|
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
import { B as resolveHmrRuntimeDecision, D as getStatefulHmrHost, E as createStatefulHmrHostPlugins, F as prepareClassicIdeConfig, I as attachHmrRuntimeSession, L as createHmrRuntimeSession, N as syncManagedTsconfigFiles, O as createSharedBuildConfig, P as getInitialBuildInputObservation, S as createOxcRuntimeSupport, T as attachStatefulHmrHost, _ as clearStatefulHmrSnapshot, b as createPackageBuilder, d as buildStatefulHmrSnapshot, f as prepareStatefulHmrSnapshot, g as StatefulHmrSnapshotHandoff, h as prepareStatefulClassicHandoff, k as getHmrRuntimeCapabilityFallback, m as captureWatchDependencies, p as checkAppWorkersOptions, u as CompilerSession, v as offerStatefulHmrSnapshot, x as settlePackageBuilds, y as getPackNpmRelationList, z as findSkylineRendererFiles } from "./createCompilerContextInstance-aYwi8wQt.mjs";
|
|
2
|
+
import { t as resolveRealpath } from "./realpathScope-Tf9mz-fh.mjs";
|
|
3
|
+
import { F as resolveNpmDistDirName, L as resolveTargetDependencies, M as resolveMainBuildDependencyPatterns, N as resolveNpmBuildCandidateDependenciesSync, f as attachDevModuleGraphHost } from "./devProvider-D-hTfsEO.mjs";
|
|
4
|
+
import { g as pruneOwnedAssetFiles } from "./utils-Dy51PYAC.mjs";
|
|
5
|
+
import { n as loadHostRolldownBuild } from "./engine-C66J0HLz.mjs";
|
|
6
|
+
import path from "pathe";
|
|
7
|
+
import { mkdtemp, readFile, readdir, rm } from "node:fs/promises";
|
|
8
|
+
import { build } from "vite";
|
|
9
|
+
import { createHash } from "node:crypto";
|
|
10
|
+
import os from "node:os";
|
|
11
|
+
import { Buffer } from "node:buffer";
|
|
12
|
+
//#region src/vite/npm/sourcemap.ts
|
|
13
|
+
const URL_SCHEME = /^[a-z][a-z\d+.-]*:/i;
|
|
14
|
+
const INLINE_MAP = /(\/\/[#@]\s*sourceMappingURL=data:application\/json(?:;charset=[^;,]*)?;base64,)([a-z\d+/=]+)/gi;
|
|
15
|
+
/** npm 镜像目录深度可能不同,重定位相对源码路径但保持 URL 与绝对来源不变。 */
|
|
16
|
+
function relocateNpmSourcemap(source, from, to) {
|
|
17
|
+
if (!from.endsWith(".map")) {
|
|
18
|
+
if (/\.[cm]?js$/.test(from)) return (typeof source === "string" ? source : Buffer.from(source).toString("utf8")).replace(INLINE_MAP, (_match, prefix, encoded) => {
|
|
19
|
+
const map = relocateNpmSourcemap(Buffer.from(encoded, "base64"), `${from}.map`, `${to}.map`);
|
|
20
|
+
return `${prefix}${Buffer.from(map).toString("base64")}`;
|
|
21
|
+
});
|
|
22
|
+
return source;
|
|
23
|
+
}
|
|
24
|
+
let value;
|
|
25
|
+
try {
|
|
26
|
+
value = JSON.parse(typeof source === "string" ? source : Buffer.from(source).toString("utf8"));
|
|
27
|
+
} catch {
|
|
28
|
+
return source;
|
|
29
|
+
}
|
|
30
|
+
if (!value || typeof value !== "object" || !("sources" in value) || !Array.isArray(value.sources) || !value.sources.every((item) => typeof item === "string")) return source;
|
|
31
|
+
const sourceRoot = "sourceRoot" in value && typeof value.sourceRoot === "string" ? value.sourceRoot : "";
|
|
32
|
+
if (URL_SCHEME.test(sourceRoot)) return source;
|
|
33
|
+
const sources = value.sources.map((item) => {
|
|
34
|
+
if (URL_SCHEME.test(item) || path.isAbsolute(item)) return item;
|
|
35
|
+
return path.relative(path.dirname(to), path.resolve(path.dirname(from), sourceRoot, item));
|
|
36
|
+
});
|
|
37
|
+
return JSON.stringify({
|
|
38
|
+
...value,
|
|
39
|
+
sourceRoot: "",
|
|
40
|
+
sources
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
//#endregion
|
|
44
|
+
//#region src/vite/npm/output.ts
|
|
45
|
+
function relativeOutput(root, target) {
|
|
46
|
+
const relative = path.relative(root, target);
|
|
47
|
+
return relative !== ".." && !relative.startsWith("../") && !path.isAbsolute(relative) ? relative : void 0;
|
|
48
|
+
}
|
|
49
|
+
/** 依赖回调只决定逻辑路径,bundle 保持内存,原生包复制只进入本会话的临时目录。 */
|
|
50
|
+
function createNpmOutput(temporaryRoot, targetRoots) {
|
|
51
|
+
const directories = /* @__PURE__ */ new Map();
|
|
52
|
+
const roots = new Set(targetRoots);
|
|
53
|
+
const files = /* @__PURE__ */ new Map();
|
|
54
|
+
const watchFiles = /* @__PURE__ */ new Set();
|
|
55
|
+
function addFile(fileName, source) {
|
|
56
|
+
const existing = files.get(fileName);
|
|
57
|
+
if (existing !== void 0 && !Buffer.from(existing).equals(Buffer.from(source))) throw new Error(`[weapp-vite] 多个 npm 依赖产生了不同内容的同名文件:${fileName}`);
|
|
58
|
+
files.set(fileName, source);
|
|
59
|
+
}
|
|
60
|
+
const output = {
|
|
61
|
+
watchFile(fileName) {
|
|
62
|
+
watchFiles.add(fileName);
|
|
63
|
+
},
|
|
64
|
+
directory(outDir) {
|
|
65
|
+
roots.add(outDir);
|
|
66
|
+
const parent = [...directories.keys()].filter((root) => relativeOutput(root, outDir) !== void 0).sort((a, b) => b.length - a.length)[0];
|
|
67
|
+
if (parent) return path.join(directories.get(parent), relativeOutput(parent, outDir));
|
|
68
|
+
const directory = path.join(temporaryRoot, String(directories.size));
|
|
69
|
+
directories.set(outDir, directory);
|
|
70
|
+
return directory;
|
|
71
|
+
},
|
|
72
|
+
async bundle(options, outDir) {
|
|
73
|
+
roots.add(outDir);
|
|
74
|
+
const result = await build({
|
|
75
|
+
...options,
|
|
76
|
+
build: {
|
|
77
|
+
...options.build,
|
|
78
|
+
write: false,
|
|
79
|
+
watch: null
|
|
80
|
+
},
|
|
81
|
+
plugins: [
|
|
82
|
+
...options.plugins ?? [],
|
|
83
|
+
captureWatchDependencies((file) => watchFiles.add(file)),
|
|
84
|
+
{
|
|
85
|
+
name: "weapp-vite:npm-inputs",
|
|
86
|
+
configResolved(config) {
|
|
87
|
+
for (const file of config.configFileDependencies) watchFiles.add(file);
|
|
88
|
+
},
|
|
89
|
+
buildEnd() {
|
|
90
|
+
for (const file of this.getModuleIds()) if (!file.includes("\0")) watchFiles.add(file.split("?")[0]);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
]
|
|
94
|
+
});
|
|
95
|
+
for (const bundle of Array.isArray(result) ? result : [result]) {
|
|
96
|
+
if (!("output" in bundle)) throw new Error("[weapp-vite] npm 子构建必须返回内存产物。");
|
|
97
|
+
for (const item of bundle.output) addFile(path.resolve(outDir, item.fileName), item.type === "chunk" ? item.code : item.source);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
for (const root of targetRoots) output.directory(root);
|
|
102
|
+
async function collect(directory, logicalRoot) {
|
|
103
|
+
let entries;
|
|
104
|
+
try {
|
|
105
|
+
entries = await readdir(directory, { withFileTypes: true });
|
|
106
|
+
} catch (error) {
|
|
107
|
+
if (error.code === "ENOENT") return;
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
110
|
+
for (const entry of entries) {
|
|
111
|
+
const source = path.join(directory, entry.name);
|
|
112
|
+
const destination = path.join(logicalRoot, entry.name);
|
|
113
|
+
if (entry.isDirectory()) await collect(source, destination);
|
|
114
|
+
else if (entry.isFile()) addFile(destination, await readFile(source));
|
|
115
|
+
else throw new Error(`[weapp-vite] npm 中间目录含有无法发布的文件类型:${destination}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
output,
|
|
120
|
+
async finish(hostOutDir, mainOutDir, mirrors) {
|
|
121
|
+
for (const [logicalRoot, directory] of directories) await collect(directory, logicalRoot);
|
|
122
|
+
const mainFiles = [...files].filter(([fileName]) => relativeOutput(mainOutDir, fileName) !== void 0);
|
|
123
|
+
for (const mirror of mirrors) {
|
|
124
|
+
roots.add(mirror);
|
|
125
|
+
for (const [fileName, source] of mainFiles) {
|
|
126
|
+
const mirroredFile = path.join(mirror, relativeOutput(mainOutDir, fileName));
|
|
127
|
+
addFile(mirroredFile, relocateNpmSourcemap(source, fileName, mirroredFile));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
const result = {
|
|
131
|
+
assets: [],
|
|
132
|
+
external: /* @__PURE__ */ new Map(),
|
|
133
|
+
watchFiles: [...watchFiles]
|
|
134
|
+
};
|
|
135
|
+
for (const [absolutePath, source] of files) {
|
|
136
|
+
const relative = relativeOutput(hostOutDir, absolutePath);
|
|
137
|
+
if (relative !== void 0) {
|
|
138
|
+
result.assets.push({
|
|
139
|
+
type: "asset",
|
|
140
|
+
fileName: relative,
|
|
141
|
+
source
|
|
142
|
+
});
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
const directory = [...roots].filter((root) => relativeOutput(root, absolutePath) !== void 0).sort((a, b) => a.length - b.length)[0];
|
|
146
|
+
const assets = result.external.get(directory) ?? [];
|
|
147
|
+
assets.push({
|
|
148
|
+
type: "asset",
|
|
149
|
+
fileName: relativeOutput(directory, absolutePath),
|
|
150
|
+
source
|
|
151
|
+
});
|
|
152
|
+
result.external.set(directory, assets);
|
|
153
|
+
}
|
|
154
|
+
return result;
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
//#endregion
|
|
159
|
+
//#region src/vite/npm/index.ts
|
|
160
|
+
/** 复用依赖编译器和 npm 关联配置,最终输出统一交给宿主 emit/write。 */
|
|
161
|
+
async function prepareNpmAssets(ctx) {
|
|
162
|
+
const config = ctx.configService;
|
|
163
|
+
const empty = {
|
|
164
|
+
assets: [],
|
|
165
|
+
external: /* @__PURE__ */ new Map(),
|
|
166
|
+
watchFiles: []
|
|
167
|
+
};
|
|
168
|
+
if (config.weappLibConfig?.enabled || !config.weappViteConfig.npm?.enable) return empty;
|
|
169
|
+
const [main, ...mirrors] = getPackNpmRelationList(ctx, { defaultOutputRoot: config.outDir });
|
|
170
|
+
if (!main) return empty;
|
|
171
|
+
const packageJsonPath = path.resolve(config.cwd, main.packageJsonPath);
|
|
172
|
+
const resolveFrom = path.dirname(packageJsonPath);
|
|
173
|
+
let packageJson;
|
|
174
|
+
try {
|
|
175
|
+
packageJson = JSON.parse(await readFile(packageJsonPath, "utf8"));
|
|
176
|
+
} catch (error) {
|
|
177
|
+
if (error.code === "ENOENT") return empty;
|
|
178
|
+
throw error;
|
|
179
|
+
}
|
|
180
|
+
const candidates = resolveNpmBuildCandidateDependenciesSync(ctx, packageJson, resolveFrom);
|
|
181
|
+
ctx.scanService.loadSubPackages();
|
|
182
|
+
const npmDirName = resolveNpmDistDirName(config);
|
|
183
|
+
const mainOutDir = path.resolve(config.cwd, main.miniprogramNpmDistDir, npmDirName);
|
|
184
|
+
const targets = [{
|
|
185
|
+
outDir: mainOutDir,
|
|
186
|
+
dependencies: resolveTargetDependencies(candidates, resolveMainBuildDependencyPatterns(ctx))
|
|
187
|
+
}, ...[...ctx.scanService.subPackageMap.values()].filter((entry) => entry.subPackage.dependencies?.length).map((entry) => ({
|
|
188
|
+
outDir: path.join(config.outDir, entry.subPackage.root, npmDirName),
|
|
189
|
+
dependencies: resolveTargetDependencies(candidates, entry.subPackage.dependencies)
|
|
190
|
+
}))];
|
|
191
|
+
const temporaryRoot = await mkdtemp(path.join(os.tmpdir(), "weapp-vite-npm-"));
|
|
192
|
+
const capture = createNpmOutput(temporaryRoot, targets.map((target) => target.outDir));
|
|
193
|
+
capture.output.watchFile?.(packageJsonPath);
|
|
194
|
+
const builder = createPackageBuilder(ctx, createOxcRuntimeSupport().vitePlugin, capture.output);
|
|
195
|
+
try {
|
|
196
|
+
for (const target of targets) await settlePackageBuilds(target.dependencies.map((dep) => builder.buildPackage({
|
|
197
|
+
dep,
|
|
198
|
+
resolveFrom,
|
|
199
|
+
outDir: target.outDir,
|
|
200
|
+
isDependenciesCacheOutdate: true
|
|
201
|
+
})));
|
|
202
|
+
const result = await capture.finish(config.outDir, mainOutDir, mirrors.map((relation) => path.resolve(config.cwd, relation.miniprogramNpmDistDir, npmDirName)));
|
|
203
|
+
if (result.external.size && config.inlineConfig.build?.write === false) throw new Error("[weapp-vite] build.write=false 无法表示宿主输出目录之外的 npm 产物;请使用 write=true 或将 npm 输出映射到宿主 outDir 内。");
|
|
204
|
+
return result;
|
|
205
|
+
} finally {
|
|
206
|
+
await rm(temporaryRoot, {
|
|
207
|
+
recursive: true,
|
|
208
|
+
force: true
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
//#endregion
|
|
213
|
+
//#region src/vite/npm/publish.ts
|
|
214
|
+
/** 手工映射到主目录外的依赖仍由宿主配套引擎写出,只清理上轮实际拥有的文件。 */
|
|
215
|
+
async function publishNpmAssets(outDir, assets, obsolete) {
|
|
216
|
+
const virtualEntry = "\0weapp-vite-npm-output";
|
|
217
|
+
const plugin = {
|
|
218
|
+
name: "weapp-vite:npm-output-writer",
|
|
219
|
+
resolveId: (id) => id === virtualEntry ? id : void 0,
|
|
220
|
+
load: (id) => id === virtualEntry ? "export {}" : void 0,
|
|
221
|
+
buildStart() {
|
|
222
|
+
for (const asset of assets) this.emitFile(asset);
|
|
223
|
+
},
|
|
224
|
+
generateBundle(_options, bundle) {
|
|
225
|
+
for (const [fileName, item] of Object.entries(bundle)) if (item.type === "chunk" && item.facadeModuleId === virtualEntry) delete bundle[fileName];
|
|
226
|
+
},
|
|
227
|
+
async writeBundle() {
|
|
228
|
+
await pruneOwnedAssetFiles(outDir, obsolete);
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
const { rolldown } = await loadHostRolldownBuild();
|
|
232
|
+
const bundle = await rolldown({
|
|
233
|
+
input: virtualEntry,
|
|
234
|
+
logLevel: "silent",
|
|
235
|
+
plugins: [plugin]
|
|
236
|
+
});
|
|
237
|
+
try {
|
|
238
|
+
await bundle.write({
|
|
239
|
+
dir: outDir,
|
|
240
|
+
format: "es"
|
|
241
|
+
});
|
|
242
|
+
} finally {
|
|
243
|
+
await bundle.close();
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
//#endregion
|
|
247
|
+
//#region src/vite/npm/ownership.ts
|
|
248
|
+
async function readOwnership(fileName) {
|
|
249
|
+
let value;
|
|
250
|
+
try {
|
|
251
|
+
value = JSON.parse(await readFile(fileName, "utf8"));
|
|
252
|
+
} catch (error) {
|
|
253
|
+
if (error.code === "ENOENT") return /* @__PURE__ */ new Map();
|
|
254
|
+
throw error;
|
|
255
|
+
}
|
|
256
|
+
if (!Array.isArray(value) || !value.every((entry) => Array.isArray(entry) && entry.length === 2 && typeof entry[0] === "string" && Array.isArray(entry[1]) && entry[1].every((file) => typeof file === "string"))) throw new Error("[weapp-vite] npm 输出归属记录损坏,请移除 .weapp-vite/native-npm-output 后重建。");
|
|
257
|
+
return new Map(value);
|
|
258
|
+
}
|
|
259
|
+
/** 保存外部产物的实际归属,使独立 build 也能删除旧依赖而保留非构建文件。 */
|
|
260
|
+
async function publishOwnedNpmAssets(cwd, hostOutDir, external) {
|
|
261
|
+
const key = createHash("sha256").update(hostOutDir).digest("hex").slice(0, 20);
|
|
262
|
+
const metadataRoot = path.join(cwd, ".weapp-vite/native-npm-output");
|
|
263
|
+
const metadataName = `${key}.json`;
|
|
264
|
+
const previous = await readOwnership(path.join(metadataRoot, metadataName));
|
|
265
|
+
const current = /* @__PURE__ */ new Map();
|
|
266
|
+
const currentFiles = /* @__PURE__ */ new Set();
|
|
267
|
+
for (const [directory, assets] of external) if (assets.length) {
|
|
268
|
+
const names = assets.map((asset) => asset.fileName);
|
|
269
|
+
current.set(directory, names);
|
|
270
|
+
for (const file of names) currentFiles.add(path.resolve(directory, file));
|
|
271
|
+
}
|
|
272
|
+
for (const directory of /* @__PURE__ */ new Set([...external.keys(), ...previous.keys()])) await publishNpmAssets(directory, external.get(directory) ?? [], (previous.get(directory) ?? []).filter((file) => !currentFiles.has(path.resolve(directory, file))));
|
|
273
|
+
if (current.size || previous.size) await publishNpmAssets(metadataRoot, [{
|
|
274
|
+
type: "asset",
|
|
275
|
+
fileName: metadataName,
|
|
276
|
+
source: JSON.stringify([...current])
|
|
277
|
+
}], []);
|
|
278
|
+
}
|
|
279
|
+
//#endregion
|
|
280
|
+
//#region src/vite/session.ts
|
|
281
|
+
const runtimeOwners = /* @__PURE__ */ new WeakMap();
|
|
282
|
+
/** 标准插件的目标校验和依赖准备,共享底层编译会话生命周期。 */
|
|
283
|
+
var WeappBuildSession = class extends CompilerSession {
|
|
284
|
+
hmrRuntimeSession;
|
|
285
|
+
dependencyBuild;
|
|
286
|
+
validating;
|
|
287
|
+
hostClosing;
|
|
288
|
+
terminalClosing;
|
|
289
|
+
isWeb = false;
|
|
290
|
+
statefulController;
|
|
291
|
+
constructor(hmrRuntimeSession = createHmrRuntimeSession()) {
|
|
292
|
+
super();
|
|
293
|
+
this.hmrRuntimeSession = hmrRuntimeSession;
|
|
294
|
+
runtimeOwners.set(hmrRuntimeSession, this);
|
|
295
|
+
this.onClose(attachHmrRuntimeSession(this.context, hmrRuntimeSession));
|
|
296
|
+
this.onClose(() => clearStatefulHmrSnapshot(this.context));
|
|
297
|
+
}
|
|
298
|
+
async prepare(config, cwd, mode, isDev = false) {
|
|
299
|
+
if (!config.resolve?.preserveSymlinks) try {
|
|
300
|
+
cwd = resolveRealpath(cwd);
|
|
301
|
+
} catch {}
|
|
302
|
+
this.isWeb = config.weapp?.platform === "web";
|
|
303
|
+
await this.initialize({
|
|
304
|
+
cwd,
|
|
305
|
+
mode,
|
|
306
|
+
isDev,
|
|
307
|
+
emitDefaultAutoImportOutputs: false,
|
|
308
|
+
hostConfig: { config: {
|
|
309
|
+
...config,
|
|
310
|
+
root: cwd
|
|
311
|
+
} },
|
|
312
|
+
cliPlatform: this.isWeb ? "web" : void 0,
|
|
313
|
+
syncSupportFiles: false,
|
|
314
|
+
preloadAppEntry: false
|
|
315
|
+
});
|
|
316
|
+
const service = this.context.configService;
|
|
317
|
+
if (this.isWeb) {
|
|
318
|
+
const merged = service.mergeWeb();
|
|
319
|
+
if (!merged) throw new Error("[weapp-vite] Web 目标不能禁用 weapp.web。");
|
|
320
|
+
return merged;
|
|
321
|
+
}
|
|
322
|
+
await prepareClassicIdeConfig(this.context);
|
|
323
|
+
if (isDev && this.hmrRuntimeSession.resolve(resolveHmrRuntimeDecision({
|
|
324
|
+
platform: service.platform,
|
|
325
|
+
configured: service.weappViteConfig.hmr?.runtime,
|
|
326
|
+
compileHotReLoad: service.projectPrivateConfig.setting?.compileHotReLoad
|
|
327
|
+
})).runtime === "stateful-experimental") {
|
|
328
|
+
if (service.platform !== "weapp") this.hmrRuntimeSession.requestClassic({
|
|
329
|
+
code: "platform",
|
|
330
|
+
message: "当前小程序平台不支持状态保持热更新。"
|
|
331
|
+
});
|
|
332
|
+
else await this.run(async () => {
|
|
333
|
+
try {
|
|
334
|
+
const snapshot = prepareStatefulHmrSnapshot(await buildStatefulHmrSnapshot(service.loadOptions, void 0, this.context, void 0, []));
|
|
335
|
+
const skylineFiles = findSkylineRendererFiles(snapshot.output);
|
|
336
|
+
if (skylineFiles.length) {
|
|
337
|
+
this.hmrRuntimeSession.requestClassic({
|
|
338
|
+
code: "skyline",
|
|
339
|
+
message: "微信 Skyline 暂不支持状态保持 HMR。",
|
|
340
|
+
files: skylineFiles
|
|
341
|
+
});
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
await offerStatefulHmrSnapshot(this.context, new StatefulHmrSnapshotHandoff(snapshot, snapshot.inputs));
|
|
345
|
+
this.statefulController = createStatefulHmrHostPlugins(this.context);
|
|
346
|
+
} catch (error) {
|
|
347
|
+
const fallback = getHmrRuntimeCapabilityFallback(error);
|
|
348
|
+
if (!fallback) throw error;
|
|
349
|
+
this.hmrRuntimeSession.requestClassic(fallback);
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
return this.context.configService.merge(void 0, createSharedBuildConfig(this.context.configService, this.context.scanService));
|
|
354
|
+
}
|
|
355
|
+
/** 只关闭本代资源;宿主负责在原生 watcher 和服务器均退出后恢复 IDE 设置。 */
|
|
356
|
+
closeHostGeneration(reason) {
|
|
357
|
+
if (!this.hostClosing) {
|
|
358
|
+
if (reason === "restart" && this.hmrRuntimeSession.fallback) prepareStatefulClassicHandoff(this.context);
|
|
359
|
+
this.hostClosing = super.close();
|
|
360
|
+
}
|
|
361
|
+
return this.hostClosing;
|
|
362
|
+
}
|
|
363
|
+
/** 无宿主的构建或首次配置失败可直接释放,已绑定宿主必须走其关闭门禁。 */
|
|
364
|
+
close(reason = "close") {
|
|
365
|
+
return reason === "restart" ? this.closeHostGeneration(reason) : this.terminalClosing ??= this.closeHostGeneration(reason).then(() => this.releaseClassicIdeConfig());
|
|
366
|
+
}
|
|
367
|
+
/** 只释放仍未被替换宿主接管的 owner,初始化失败和遗弃交接使用同一关闭门禁。 */
|
|
368
|
+
async releaseClassicIdeConfig() {
|
|
369
|
+
await super.close();
|
|
370
|
+
if (runtimeOwners.get(this.hmrRuntimeSession) === this) await this.hmrRuntimeSession.classicIdeConfig.close();
|
|
371
|
+
}
|
|
372
|
+
/** 原生宿主链已完全退出后,连同尚未绑定宿主的失败替换代一起释放。 */
|
|
373
|
+
async releaseHostClassicIdeConfig() {
|
|
374
|
+
await runtimeOwners.get(this.hmrRuntimeSession)?.closeHostGeneration("close");
|
|
375
|
+
await this.hmrRuntimeSession.classicIdeConfig.close();
|
|
376
|
+
}
|
|
377
|
+
validateEntries() {
|
|
378
|
+
if (this.validating && !this.isClosing) return this.validating;
|
|
379
|
+
if (this.state !== "ready" && this.state !== "building") return Promise.reject(/* @__PURE__ */ new Error(`[weapp-vite] 无法从 ${this.state} 状态开始构建。`));
|
|
380
|
+
this.dependencyBuild = void 0;
|
|
381
|
+
return this.validating = this.run(async () => {
|
|
382
|
+
if (!this.isWeb && !this.context.configService.weappLibConfig?.enabled) {
|
|
383
|
+
const app = await this.context.scanService.loadAppEntry();
|
|
384
|
+
checkAppWorkersOptions("app", this.context.configService, app);
|
|
385
|
+
}
|
|
386
|
+
if (this.isClosing) throw new Error("[weapp-vite] 构建会话已关闭。");
|
|
387
|
+
await syncManagedTsconfigFiles(this.context);
|
|
388
|
+
if (this.isClosing) throw new Error("[weapp-vite] 构建会话已关闭。");
|
|
389
|
+
this.state = "building";
|
|
390
|
+
}).catch((error) => {
|
|
391
|
+
getInitialBuildInputObservation(this.context.configService)?.close();
|
|
392
|
+
throw error;
|
|
393
|
+
}).finally(() => {
|
|
394
|
+
this.validating = void 0;
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
async startDev(server) {
|
|
398
|
+
if (this.isWeb) {
|
|
399
|
+
await this.run(() => syncManagedTsconfigFiles(this.context));
|
|
400
|
+
this.state = "watching";
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
let started = false;
|
|
404
|
+
let successful = false;
|
|
405
|
+
let reportedReady = false;
|
|
406
|
+
const reportReady = () => {
|
|
407
|
+
if (started && successful && !reportedReady && !this.isClosing) {
|
|
408
|
+
if (this.statefulController && this.hmrRuntimeSession.phase === "switching") return;
|
|
409
|
+
reportedReady = true;
|
|
410
|
+
if (!this.statefulController) this.hmrRuntimeSession.markClassic();
|
|
411
|
+
server.config.logger.info(`[weapp-vite] 小程序开发产物已就绪 (${this.statefulController ? "stateful-experimental" : "classic"})`);
|
|
412
|
+
}
|
|
413
|
+
};
|
|
414
|
+
if (this.statefulController) this.onClose(attachStatefulHmrHost(this.context, {
|
|
415
|
+
server,
|
|
416
|
+
controller: this.statefulController
|
|
417
|
+
}));
|
|
418
|
+
this.onClose(attachDevModuleGraphHost(this.context, server, (result) => {
|
|
419
|
+
successful = result;
|
|
420
|
+
reportReady();
|
|
421
|
+
}));
|
|
422
|
+
this.onClose(() => this.context.watcherService.closeAll());
|
|
423
|
+
await this.validateEntries();
|
|
424
|
+
await this.run(() => this.context.buildService.build({}));
|
|
425
|
+
if (!this.isClosing) {
|
|
426
|
+
this.state = "watching";
|
|
427
|
+
if (this.statefulController) successful = true;
|
|
428
|
+
started = true;
|
|
429
|
+
reportReady();
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
async refreshHostControl() {
|
|
433
|
+
await getStatefulHmrHost(this.context)?.refreshControl?.();
|
|
434
|
+
}
|
|
435
|
+
buildDependencies() {
|
|
436
|
+
if (this.isWeb) return Promise.resolve({
|
|
437
|
+
assets: [],
|
|
438
|
+
external: /* @__PURE__ */ new Map(),
|
|
439
|
+
watchFiles: []
|
|
440
|
+
});
|
|
441
|
+
if (this.state !== "building") throw new Error("[weapp-vite] 依赖构建需要活动的构建会话。");
|
|
442
|
+
return this.dependencyBuild ??= this.run(() => prepareNpmAssets(this.context));
|
|
443
|
+
}
|
|
444
|
+
async publishDependencies() {
|
|
445
|
+
if (!this.dependencyBuild) return;
|
|
446
|
+
const { external } = await this.dependencyBuild;
|
|
447
|
+
const { cwd, outDir } = this.context.configService;
|
|
448
|
+
await this.run(() => publishOwnedNpmAssets(cwd, outDir, external));
|
|
449
|
+
}
|
|
450
|
+
};
|
|
451
|
+
//#endregion
|
|
452
|
+
export { WeappBuildSession };
|
package/dist/test.d.mts
CHANGED
|
@@ -22,6 +22,7 @@ export interface WeappViteTestArtifactWatcher {
|
|
|
22
22
|
close: () => Promise<void>;
|
|
23
23
|
rebuild: () => Promise<WeappViteTestArtifact>;
|
|
24
24
|
}
|
|
25
|
+
export declare function isTestArtifactCurrent(artifact: WeappViteTestArtifact): Promise<boolean>;
|
|
25
26
|
export declare function buildTestArtifact(options?: BuildTestArtifactOptions): Promise<{
|
|
26
27
|
appConfigPath: string;
|
|
27
28
|
miniprogramRootPath: string;
|