@open-wxa/wxa-runner-core 0.5.0 → 0.7.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/index.d.mts +26 -8
- package/dist/index.d.ts +26 -8
- package/dist/index.js +316 -87
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +310 -81
- package/dist/index.mjs.map +1 -1
- package/dist/runtime/frame.js +50 -1
- package/dist/runtime/frame.js.map +1 -1
- package/dist/runtime/host.js +32 -12
- package/dist/runtime/host.js.map +1 -1
- package/dist/runtime/worker.js +42 -0
- package/dist/runtime/worker.js.map +1 -0
- package/dist/{setup-Cv340Lvj.d.mts → setup-DZ5FeKay.d.mts} +2 -1
- package/dist/{setup-Cv340Lvj.d.ts → setup-DZ5FeKay.d.ts} +2 -1
- package/dist/setup.d.mts +1 -1
- package/dist/setup.d.ts +1 -1
- package/dist/test-api.d.mts +2 -2
- package/dist/test-api.d.ts +2 -2
- package/dist/{testApi-nKsjjEhz.d.ts → testApi-BLozOgCt.d.ts} +1 -1
- package/dist/{testApi-DO2FyR78.d.mts → testApi-CnZOLyWw.d.mts} +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -45,7 +45,7 @@ var import_http = __toESM(require("http"));
|
|
|
45
45
|
var import_path4 = __toESM(require("path"));
|
|
46
46
|
var import_express2 = __toESM(require("express"));
|
|
47
47
|
var import_ws2 = require("ws");
|
|
48
|
-
var
|
|
48
|
+
var import_wxa_runner_extractor5 = require("@open-wxa/wxa-runner-extractor");
|
|
49
49
|
|
|
50
50
|
// src/project/AppBuilder.ts
|
|
51
51
|
var import_wxa_runner_compiler = require("@open-wxa/wxa-runner-compiler");
|
|
@@ -226,8 +226,10 @@ var AppBuilder = class {
|
|
|
226
226
|
]);
|
|
227
227
|
this.wxmlCache = wxml;
|
|
228
228
|
this.wxssCache = wxss;
|
|
229
|
-
const workersDir =
|
|
230
|
-
const
|
|
229
|
+
const workersDir = this.project.workersDir(app);
|
|
230
|
+
const inWorkers = (file) => workersDir !== null && file.startsWith(workersDir + "/");
|
|
231
|
+
const scripts = this.project.listFiles([".js"]);
|
|
232
|
+
const modules = scripts.filter((file) => !inWorkers(file));
|
|
231
233
|
const serviceTemplates = this.createTemplates(app, units, unitJson, wxml.cut);
|
|
232
234
|
const pageTemplates = this.createTemplates(app, units, unitJson, wxml.full);
|
|
233
235
|
const pageStyles = createStyles(units, wxss);
|
|
@@ -241,6 +243,7 @@ var AppBuilder = class {
|
|
|
241
243
|
subPackages: this.project.subPackages(app)
|
|
242
244
|
}),
|
|
243
245
|
modules,
|
|
246
|
+
workerModules: scripts.filter(inWorkers),
|
|
244
247
|
serviceTemplates,
|
|
245
248
|
serviceBootstrap: this.createServiceBootstrap(serviceTemplates, units, modules),
|
|
246
249
|
pageFrame: `${pageTemplates}
|
|
@@ -262,7 +265,7 @@ ${pageStyles}`,
|
|
|
262
265
|
const files = this.project.listFiles([".wxml", ".wxs"]).map((f) => "./" + f);
|
|
263
266
|
const components = units.filter((id) => this.project.exists(id + ".wxml")).map((id) => {
|
|
264
267
|
const json = unitJson.get(id);
|
|
265
|
-
return { path: id, tags: Object.keys({ ...json.usingComponents, ...json.componentGenerics
|
|
268
|
+
return { path: id, tags: Object.keys({ ...json.usingComponents, ...json.componentGenerics }) };
|
|
266
269
|
});
|
|
267
270
|
const cwd = this.project.root;
|
|
268
271
|
const [full, cut] = await Promise.all([
|
|
@@ -355,6 +358,11 @@ var MiniProgram = class {
|
|
|
355
358
|
subPackages(app) {
|
|
356
359
|
return app.subPackages || app.subpackages || [];
|
|
357
360
|
}
|
|
361
|
+
/** Worker 代码所在目录,不带首尾的 /;没有配置 workers 时为 null */
|
|
362
|
+
workersDir(app) {
|
|
363
|
+
const dir = typeof app.workers === "string" ? app.workers : app.workers?.path;
|
|
364
|
+
return dir ? import_path.default.posix.normalize(dir).replace(/^\/+|\/+$/g, "") : null;
|
|
365
|
+
}
|
|
358
366
|
/** 主包页面 + 分包页面(带 root 前缀) */
|
|
359
367
|
allPages(app) {
|
|
360
368
|
const pages = [...app.pages];
|
|
@@ -368,8 +376,8 @@ var MiniProgram = class {
|
|
|
368
376
|
}
|
|
369
377
|
/** 读取并预处理页面/组件 json,id 不带扩展名 */
|
|
370
378
|
readUnitJson(id, app) {
|
|
371
|
-
const json = { ...readJsonFile(import_path.default.join(this.root, id + ".json"))
|
|
372
|
-
json.usingComponents = { ...json.usingComponents
|
|
379
|
+
const json = { ...readJsonFile(import_path.default.join(this.root, id + ".json")) };
|
|
380
|
+
json.usingComponents = { ...json.usingComponents };
|
|
373
381
|
if (!id.startsWith("miniprogram_npm/") && !this.isInIndependentSubPackage(id, app)) {
|
|
374
382
|
for (const [tag, ref] of Object.entries(app.usingComponents || {})) {
|
|
375
383
|
if (json.usingComponents[tag]) continue;
|
|
@@ -436,15 +444,14 @@ var MiniProgram = class {
|
|
|
436
444
|
return { pages, components };
|
|
437
445
|
}
|
|
438
446
|
/** 列出代码根目录下指定扩展名的文件,返回 posix 风格的相对路径 */
|
|
439
|
-
listFiles(extensions
|
|
447
|
+
listFiles(extensions) {
|
|
440
448
|
const result = [];
|
|
441
|
-
const excluded = new Set(excludeDirs.map((dir) => dir.replace(/^\/|\/$/g, "")));
|
|
442
449
|
const walk = (dir, rel) => {
|
|
443
450
|
for (const entry of import_fs.default.readdirSync(dir, { withFileTypes: true })) {
|
|
444
451
|
if (entry.name.startsWith(".") || IGNORED_DIRS.has(entry.name)) continue;
|
|
445
452
|
const childRel = rel ? `${rel}/${entry.name}` : entry.name;
|
|
446
453
|
if (entry.isDirectory()) {
|
|
447
|
-
|
|
454
|
+
walk(import_path.default.join(dir, entry.name), childRel);
|
|
448
455
|
} else if (extensions.some((ext) => entry.name.endsWith(ext))) {
|
|
449
456
|
if (!rel && PROJECT_FILES.has(entry.name)) continue;
|
|
450
457
|
result.push(childRel);
|
|
@@ -474,6 +481,178 @@ function readJsonFile(file) {
|
|
|
474
481
|
}
|
|
475
482
|
}
|
|
476
483
|
|
|
484
|
+
// src/server/plugins.ts
|
|
485
|
+
var import_wxa_runner_extractor2 = require("@open-wxa/wxa-runner-extractor");
|
|
486
|
+
|
|
487
|
+
// src/server/wechatDev.ts
|
|
488
|
+
var import_wxa_runner_extractor = require("@open-wxa/wxa-runner-extractor");
|
|
489
|
+
var BASE_URL = "https://servicewechat.com";
|
|
490
|
+
var CLIENT_VERSION = "1021810240";
|
|
491
|
+
var DEFAULT_TIMEOUT = 1e4;
|
|
492
|
+
var ERROR_HINTS = {
|
|
493
|
+
// 40001:开发者工具刷新过 ticket,旧的随即作废
|
|
494
|
+
40001: "\uFF08\u767B\u5F55\u6001\u5DF2\u5931\u6548\uFF0C\u8BF7\u5728\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u91CC\u91CD\u65B0\u767B\u5F55\uFF09",
|
|
495
|
+
40029: "\uFF08\u767B\u5F55\u6001\u5DF2\u5931\u6548\uFF0C\u8BF7\u5728\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u91CC\u91CD\u65B0\u767B\u5F55\uFF09",
|
|
496
|
+
85023: "\uFF08\u5F53\u524D\u5FAE\u4FE1\u8D26\u53F7\u4E0D\u662F\u8BE5\u5C0F\u7A0B\u5E8F\u7684\u5F00\u53D1\u8005\uFF09"
|
|
497
|
+
};
|
|
498
|
+
function requireUsableTicket(ticket) {
|
|
499
|
+
if (!ticket) throw new Error(`\u672A\u627E\u5230\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u7684\u767B\u5F55\u6001\uFF0C\u8BF7\u767B\u5F55\u5F00\u53D1\u8005\u5DE5\u5177\uFF0C\u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF ${import_wxa_runner_extractor.TICKET_ENV}`);
|
|
500
|
+
if (ticket.expiredAt !== void 0 && ticket.expiredAt <= Date.now()) {
|
|
501
|
+
throw new Error("\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u7684\u767B\u5F55\u6001\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u6253\u5F00\u5F00\u53D1\u8005\u5DE5\u5177\u5237\u65B0\u767B\u5F55\u6001");
|
|
502
|
+
}
|
|
503
|
+
return ticket.newticket;
|
|
504
|
+
}
|
|
505
|
+
function explainErrcode(errcode) {
|
|
506
|
+
return errcode !== void 0 && ERROR_HINTS[errcode] || "";
|
|
507
|
+
}
|
|
508
|
+
function requireOk(body, action) {
|
|
509
|
+
const errcode = body.baseresponse?.errcode;
|
|
510
|
+
if (errcode !== 0) throw new Error(`${action} ${errcode}: ${body.baseresponse?.errmsg || "\u672A\u77E5\u9519\u8BEF"}${explainErrcode(errcode)}`);
|
|
511
|
+
return body;
|
|
512
|
+
}
|
|
513
|
+
var WechatDevClient = class {
|
|
514
|
+
/**
|
|
515
|
+
* @param findTicket 每次请求都重新取:开发者工具重新登录、切换账号后不用重启服务器
|
|
516
|
+
*/
|
|
517
|
+
constructor(appid, findTicket) {
|
|
518
|
+
this.appid = appid;
|
|
519
|
+
this.findTicket = findTicket;
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* POST JSON 到 path(如 wxa-dev-logic/jslogin),带上 appid 和开发者 ticket
|
|
523
|
+
*
|
|
524
|
+
* @throws 没有可用的登录态、超时、连不上、HTTP 状态不是 2xx 时,消息是给用户看的原因
|
|
525
|
+
*/
|
|
526
|
+
async post(path5, body, timeout = DEFAULT_TIMEOUT) {
|
|
527
|
+
const query = new URLSearchParams({ appid: this.appid, newticket: requireUsableTicket(await this.findTicket()), clientversion: CLIENT_VERSION });
|
|
528
|
+
const response = await fetch(`${BASE_URL}/${path5}?${query}`, {
|
|
529
|
+
method: "POST",
|
|
530
|
+
headers: { "Content-Type": "application/json" },
|
|
531
|
+
body: JSON.stringify(body),
|
|
532
|
+
signal: AbortSignal.timeout(timeout)
|
|
533
|
+
}).catch((error) => {
|
|
534
|
+
throw new Error(error.name === "TimeoutError" ? `\u8BF7\u6C42\u5FAE\u4FE1\u670D\u52A1\u5668\u8D85\u65F6\uFF08${timeout / 1e3}s\uFF09` : `\u8BF7\u6C42\u5FAE\u4FE1\u670D\u52A1\u5668\u5931\u8D25\uFF1A${error.cause?.message ?? error.message}`);
|
|
535
|
+
});
|
|
536
|
+
if (!response.ok) throw new Error(`\u5FAE\u4FE1\u670D\u52A1\u5668\u8FD4\u56DE HTTP ${response.status}`);
|
|
537
|
+
return response;
|
|
538
|
+
}
|
|
539
|
+
/** 同 post,返回解析后的 JSON */
|
|
540
|
+
async postJson(path5, body) {
|
|
541
|
+
return (await this.post(path5, body)).json();
|
|
542
|
+
}
|
|
543
|
+
};
|
|
544
|
+
|
|
545
|
+
// src/server/plugins.ts
|
|
546
|
+
var DOWNLOAD_TIMEOUT = 3e4;
|
|
547
|
+
var PACKAGE_MAGIC = 190;
|
|
548
|
+
var PluginStore = class {
|
|
549
|
+
/**
|
|
550
|
+
* @param wechat 开启 --devtools-login 时才有,没有时不下载插件
|
|
551
|
+
*/
|
|
552
|
+
constructor(wechat, logger) {
|
|
553
|
+
this.wechat = wechat;
|
|
554
|
+
this.logger = logger;
|
|
555
|
+
/** provider@version → 下载结果;失败的不留,下次打开小程序时重试 */
|
|
556
|
+
this.downloads = /* @__PURE__ */ new Map();
|
|
557
|
+
/**
|
|
558
|
+
* 这次打开小程序时决定用哪些插件。同一次打开的逻辑层、业务模块、渲染层等请求都按它处理:
|
|
559
|
+
* 各自去下载的话,下载失败时每个请求都会重试,结果还可能前后不一,页面列表和逻辑层对不上
|
|
560
|
+
*/
|
|
561
|
+
this.selection = null;
|
|
562
|
+
/** 没开 --devtools-login 的提示每个插件只说一次 */
|
|
563
|
+
this.warned = /* @__PURE__ */ new Set();
|
|
564
|
+
}
|
|
565
|
+
/** 打开小程序时(宿主取 app-info)调用:重新决定用哪些插件,下载过的直接用,上次失败的重试 */
|
|
566
|
+
async refresh(build2) {
|
|
567
|
+
this.selection = this.select(build2);
|
|
568
|
+
return withPlugins(build2, await this.selection);
|
|
569
|
+
}
|
|
570
|
+
/** 其余请求沿用这次打开时的决定,不触发下载;还没决定过时(如直接请求逻辑层)先决定一次 */
|
|
571
|
+
async current(build2) {
|
|
572
|
+
this.selection ??= this.select(build2);
|
|
573
|
+
return withPlugins(build2, await this.selection);
|
|
574
|
+
}
|
|
575
|
+
/** app.json 声明的插件;下载不了的跳过,在终端说明原因,小程序自己的页面照常可用 */
|
|
576
|
+
async select(build2) {
|
|
577
|
+
const declared = build2.wxConfig.plugins || {};
|
|
578
|
+
const results = await Promise.all(Object.entries(declared).map(
|
|
579
|
+
([alias, { provider, version }]) => provider && version ? this.load(alias, provider, version) : null
|
|
580
|
+
));
|
|
581
|
+
return results.filter((plugin) => !!plugin);
|
|
582
|
+
}
|
|
583
|
+
async load(alias, provider, version) {
|
|
584
|
+
const label = `\u63D2\u4EF6 ${alias}\uFF08${provider}@${version}\uFF09`;
|
|
585
|
+
if (!this.wechat) {
|
|
586
|
+
this.warnOnce(label, `[wxa-runner] ${label} \u7684\u4EE3\u7801\u8981\u7528\u5F00\u53D1\u8005\u7684\u767B\u5F55\u6001\u5411\u5FAE\u4FE1\u4E0B\u8F7D\uFF0C\u542F\u52A8\u65F6\u52A0 --devtools-login`);
|
|
587
|
+
return null;
|
|
588
|
+
}
|
|
589
|
+
const key = `${provider}@${version}`;
|
|
590
|
+
let download = this.downloads.get(key);
|
|
591
|
+
if (!download) {
|
|
592
|
+
download = this.download(this.wechat, alias, provider, version);
|
|
593
|
+
this.downloads.set(key, download);
|
|
594
|
+
download.catch(() => this.downloads.delete(key));
|
|
595
|
+
}
|
|
596
|
+
try {
|
|
597
|
+
return await download;
|
|
598
|
+
} catch (error) {
|
|
599
|
+
this.logger.warn(`[wxa-runner] ${label} \u4E0B\u8F7D\u5931\u8D25\uFF1A${error.message}`);
|
|
600
|
+
return null;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
/** @throws 没有登录态、连不上、微信拒绝或返回的不是插件代码包时,消息是原因 */
|
|
604
|
+
async download(wechat, alias, provider, version) {
|
|
605
|
+
const response = await wechat.post("wxa-dev/getplugincode", { plugin_id: provider, plugin_version: version }, DOWNLOAD_TIMEOUT);
|
|
606
|
+
const data = Buffer.from(await response.arrayBuffer());
|
|
607
|
+
if (data[0] !== PACKAGE_MAGIC) {
|
|
608
|
+
let body = {};
|
|
609
|
+
try {
|
|
610
|
+
body = JSON.parse(data.toString("utf8"));
|
|
611
|
+
} catch {
|
|
612
|
+
}
|
|
613
|
+
if (body.baseresponse?.errcode) requireOk(body, "\u5FAE\u4FE1\u62D2\u7EDD\u4E0B\u8F7D");
|
|
614
|
+
throw new Error("\u5FAE\u4FE1\u6CA1\u6709\u8FD4\u56DE\u63D2\u4EF6\u4EE3\u7801");
|
|
615
|
+
}
|
|
616
|
+
const files = new Map((0, import_wxa_runner_extractor2.readWxvpkgIndex)(data).map((entry) => [entry.name, Buffer.from((0, import_wxa_runner_extractor2.readWxvpkgFile)(data, entry))]));
|
|
617
|
+
const pluginJson = JSON.parse(files.get("/plugin.json")?.toString("utf8") || "{}");
|
|
618
|
+
return {
|
|
619
|
+
alias,
|
|
620
|
+
provider,
|
|
621
|
+
version,
|
|
622
|
+
files,
|
|
623
|
+
pages: Object.values(pluginJson.pages || {}),
|
|
624
|
+
pageConfigs: pluginJson.page || {}
|
|
625
|
+
};
|
|
626
|
+
}
|
|
627
|
+
warnOnce(key, message) {
|
|
628
|
+
if (this.warned.has(key)) return;
|
|
629
|
+
this.warned.add(key);
|
|
630
|
+
this.logger.warn(message);
|
|
631
|
+
}
|
|
632
|
+
};
|
|
633
|
+
function withPlugins(build2, plugins) {
|
|
634
|
+
if (!plugins.length) return { ...build2, plugins };
|
|
635
|
+
return {
|
|
636
|
+
...build2,
|
|
637
|
+
plugins,
|
|
638
|
+
pages: [...build2.pages, ...plugins.flatMap((plugin) => plugin.pages)],
|
|
639
|
+
wxConfig: {
|
|
640
|
+
...build2.wxConfig,
|
|
641
|
+
page: { ...build2.wxConfig.page, ...Object.assign({}, ...plugins.map((plugin) => plugin.pageConfigs)) }
|
|
642
|
+
}
|
|
643
|
+
};
|
|
644
|
+
}
|
|
645
|
+
function findPluginPage(build2, pagePath) {
|
|
646
|
+
for (const plugin of build2.plugins) {
|
|
647
|
+
const prefix = `__plugin__/${plugin.provider}/`;
|
|
648
|
+
if (plugin.pages.includes(pagePath)) return { plugin, innerPath: pagePath.slice(prefix.length) };
|
|
649
|
+
}
|
|
650
|
+
return null;
|
|
651
|
+
}
|
|
652
|
+
function pluginScriptUrl(plugin, file) {
|
|
653
|
+
return `/__wxa__/plugin/${encodeURIComponent(plugin.provider)}/${encodeURIComponent(plugin.version)}/${file}`;
|
|
654
|
+
}
|
|
655
|
+
|
|
477
656
|
// src/server/html.ts
|
|
478
657
|
function hostHtml() {
|
|
479
658
|
return `<!DOCTYPE html>
|
|
@@ -500,10 +679,11 @@ function appserviceHtml(build2, launch, options) {
|
|
|
500
679
|
...options.isolated ? { isIsolateContext: true } : {}
|
|
501
680
|
};
|
|
502
681
|
const v = build2.version;
|
|
682
|
+
const pluginUrls = build2.plugins.map((plugin) => pluginScriptUrl(plugin, "appservice.js"));
|
|
503
683
|
const moduleUrls = build2.modules.map((id) => `/__wxa__/module/${encodeURI(id)}?v=${v}`);
|
|
504
684
|
const bootstrapUrl = `/__wxa__/service-bootstrap.js?v=${v}`;
|
|
505
685
|
if (options.isolated) {
|
|
506
|
-
const scripts = [...moduleUrls, bootstrapUrl];
|
|
686
|
+
const scripts = [...pluginUrls, ...moduleUrls, bootstrapUrl];
|
|
507
687
|
return `<!DOCTYPE html>
|
|
508
688
|
<html>
|
|
509
689
|
<head>
|
|
@@ -516,7 +696,7 @@ function appserviceHtml(build2, launch, options) {
|
|
|
516
696
|
<body></body>
|
|
517
697
|
</html>`;
|
|
518
698
|
}
|
|
519
|
-
const modules = moduleUrls.map((src) => `<script src="${src}"></script>`).join("\n");
|
|
699
|
+
const modules = [...pluginUrls, ...moduleUrls].map((src) => `<script src="${src}"></script>`).join("\n");
|
|
520
700
|
return `<!DOCTYPE html>
|
|
521
701
|
<html>
|
|
522
702
|
<head>
|
|
@@ -550,29 +730,13 @@ ${empty ? "" : '<script src="/__baselib__/WASubContext.js"></script>\n'}<script>
|
|
|
550
730
|
</html>`;
|
|
551
731
|
}
|
|
552
732
|
function webviewHtml(build2, pagePath, webviewId, options) {
|
|
553
|
-
const pageConfig = build2.wxConfig.page?.[pagePath + ".html"];
|
|
554
|
-
const window = { ...build2.wxConfig.global?.window, ...pageConfig?.window };
|
|
555
|
-
const wxConfig = { ...build2.wxConfig, window };
|
|
556
733
|
const id = Number(webviewId) || 0;
|
|
557
734
|
return `<!DOCTYPE html>
|
|
558
735
|
<html>
|
|
559
736
|
<head>
|
|
560
|
-
|
|
561
|
-
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
|
562
|
-
<title>${escapeHtml(pagePath)}</title>
|
|
563
|
-
<!-- \u5C0F\u7A0B\u5E8F\u6E32\u67D3\u5C42\u7684\u9ED8\u8BA4\u5B57\u53F7\u662F 16px\uFF1B\u4E0D\u58F0\u660E\u7684\u8BDD\u4F1A\u7EE7\u627F\u6D4F\u89C8\u5668\u8BBE\u7F6E\u91CC\u7684\u9ED8\u8BA4\u5B57\u53F7\u3002\u653E\u5728\u6700\u524D\u9762\uFF0C\u57FA\u7840\u5E93\u548C\u9875\u9762\u6837\u5F0F\u90FD\u80FD\u8986\u76D6\u5B83 -->
|
|
564
|
-
<style>html{font-size:16px}</style>
|
|
565
|
-
<!-- \u771F\u673A\u7684\u6EDA\u52A8\u6761\u662F\u4E0D\u5360\u5E03\u5C40\u7684\u6D6E\u5C42\uFF1B\u684C\u9762\u6D4F\u89C8\u5668\u7684\u5E38\u89C4\u6EDA\u52A8\u6761\u548C\u81EA\u5B9A\u4E49 ::-webkit-scrollbar \u4F1A\u6324\u7A84\u9875\u9762\uFF0C\u4E00\u5F8B\u9690\u85CF\u3002
|
|
566
|
-
scrollbar-width \u4F18\u5148\u4E8E ::-webkit-scrollbar\uFF0C\u9875\u9762\u6837\u5F0F\u4E0D\u4F1A\u518D\u628A\u6EDA\u52A8\u6761\u52A0\u56DE\u6765 -->
|
|
567
|
-
<style>*{scrollbar-width:none}::-webkit-scrollbar{display:none}</style>
|
|
568
|
-
<!-- \u903B\u8F91\u5C42\u5EFA\u7684 2d\u3001webgl \u753B\u5E03\u642C\u8FDB wx-canvas \u540E\u94FA\u6EE1\u5B83\uFF08\u89C1 frame.ts \u7684 moveCanvasesIntoPages\uFF09\u3002
|
|
569
|
-
\u57FA\u7840\u5E93\u8FD8\u4F1A\u6309\u903B\u8F91\u5C42\u91CC\u7684\u5E03\u5C40\u6539\u5B83\u7684\u4F4D\u7F6E\u548C\u663E\u9690\uFF0C\u8FD9\u91CC\u4E00\u5F8B\u538B\u4F4F\uFF1B\u89E6\u6478\u7167\u5E38\u4EA4\u7ED9 wx-canvas \u81EA\u5DF1\u7684 canvas -->
|
|
570
|
-
<style>.wxa-service-canvas{position:absolute!important;left:0!important;top:0!important;width:100%!important;height:100%!important;visibility:inherit!important;pointer-events:none}</style>
|
|
571
|
-
<script>var __wxConfig = ${toJs(wxConfig)};</script>
|
|
572
|
-
<script src="/__wxa__/runtime/frame.js" data-kind="webview" data-webview-id="${id}"></script>
|
|
573
|
-
<script src="/__baselib__/WAWebview.js"></script>
|
|
737
|
+
${webviewHead(build2, pagePath, id)}
|
|
574
738
|
${enableHotUpdate(options.hot)}<script src="/__wxa__/page-frame.js?v=${build2.version}"></script>
|
|
575
|
-
${
|
|
739
|
+
${pageWindow(build2, pagePath).disableScroll ? "<style>body{overflow-y:hidden}</style>" : ""}
|
|
576
740
|
</head>
|
|
577
741
|
<body>
|
|
578
742
|
<script>
|
|
@@ -592,6 +756,58 @@ ${window.disableScroll ? "<style>body{overflow-y:hidden}</style>" : ""}
|
|
|
592
756
|
</body>
|
|
593
757
|
</html>`;
|
|
594
758
|
}
|
|
759
|
+
function workerScript(build2, baseLib) {
|
|
760
|
+
const modules = build2.workerModules.map((id) => `/__wxa__/module/${encodeURI(id)}?v=${build2.version}`);
|
|
761
|
+
const prelude = `var __wxConfig = ${toJs(build2.wxConfig)};
|
|
762
|
+
importScripts('/__wxa__/runtime/worker.js');
|
|
763
|
+
`;
|
|
764
|
+
if (!baseLib.hasWorker) {
|
|
765
|
+
const message = `[wxa-runner] \u57FA\u7840\u5E93 ${baseLib.version} \u91CC\u6CA1\u6709 WAWorker.js\uFF0CWorker \u4E0D\u80FD\u8FD0\u884C\u3002\u6362\u7528\u5F00\u53D1\u8005\u5DE5\u5177\u4E0B\u8F7D\u7684\u57FA\u7840\u5E93\uFF0C\u6216\u5347\u7EA7 wxa-runner \u5E26\u4E0A\u65B0\u7684\u5185\u7F6E\u57FA\u7840\u5E93`;
|
|
766
|
+
return `${prelude}throw new Error(${toJs(message)});
|
|
767
|
+
`;
|
|
768
|
+
}
|
|
769
|
+
return `${prelude}var __wxaConsole = self.console;
|
|
770
|
+
importScripts('/__baselib__/WAWorker.js');
|
|
771
|
+
self.console = __wxaConsole;
|
|
772
|
+
importScripts(${modules.map((url) => toJs(url)).join(", ")});
|
|
773
|
+
`;
|
|
774
|
+
}
|
|
775
|
+
function pluginWebviewHtml(build2, plugin, innerPath, pagePath, webviewId) {
|
|
776
|
+
const id = Number(webviewId) || 0;
|
|
777
|
+
const page = plugin.files.get(`/${innerPath}.html`)?.toString("utf8") ?? `<script>console.error(${JSON.stringify(`[wxa-runner] \u63D2\u4EF6 ${plugin.alias} \u91CC\u6CA1\u6709\u9875\u9762 ${innerPath}`)})</script>`;
|
|
778
|
+
return `<!DOCTYPE html>
|
|
779
|
+
<html>
|
|
780
|
+
<head>
|
|
781
|
+
${webviewHead(build2, pagePath, id)}
|
|
782
|
+
<script src="${pluginScriptUrl(plugin, "pageframe.js")}"></script>
|
|
783
|
+
${pageWindow(build2, pagePath).disableScroll ? "<style>body{overflow-y:hidden}</style>" : ""}
|
|
784
|
+
</head>
|
|
785
|
+
<body>
|
|
786
|
+
${page}
|
|
787
|
+
<script>parent.__wxaHost.frameLoaded('webview', ${id});</script>
|
|
788
|
+
</body>
|
|
789
|
+
</html>`;
|
|
790
|
+
}
|
|
791
|
+
function pageWindow(build2, pagePath) {
|
|
792
|
+
return { ...build2.wxConfig.global?.window, ...build2.wxConfig.page?.[pagePath + ".html"]?.window };
|
|
793
|
+
}
|
|
794
|
+
function webviewHead(build2, pagePath, id) {
|
|
795
|
+
const wxConfig = { ...build2.wxConfig, window: pageWindow(build2, pagePath) };
|
|
796
|
+
return `<meta charset="utf-8">
|
|
797
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
|
798
|
+
<title>${escapeHtml(pagePath)}</title>
|
|
799
|
+
<!-- \u5C0F\u7A0B\u5E8F\u6E32\u67D3\u5C42\u7684\u9ED8\u8BA4\u5B57\u53F7\u662F 16px\uFF1B\u4E0D\u58F0\u660E\u7684\u8BDD\u4F1A\u7EE7\u627F\u6D4F\u89C8\u5668\u8BBE\u7F6E\u91CC\u7684\u9ED8\u8BA4\u5B57\u53F7\u3002\u653E\u5728\u6700\u524D\u9762\uFF0C\u57FA\u7840\u5E93\u548C\u9875\u9762\u6837\u5F0F\u90FD\u80FD\u8986\u76D6\u5B83 -->
|
|
800
|
+
<style>html{font-size:16px}</style>
|
|
801
|
+
<!-- \u771F\u673A\u7684\u6EDA\u52A8\u6761\u662F\u4E0D\u5360\u5E03\u5C40\u7684\u6D6E\u5C42\uFF1B\u684C\u9762\u6D4F\u89C8\u5668\u7684\u5E38\u89C4\u6EDA\u52A8\u6761\u548C\u81EA\u5B9A\u4E49 ::-webkit-scrollbar \u4F1A\u6324\u7A84\u9875\u9762\uFF0C\u4E00\u5F8B\u9690\u85CF\u3002
|
|
802
|
+
scrollbar-width \u4F18\u5148\u4E8E ::-webkit-scrollbar\uFF0C\u9875\u9762\u6837\u5F0F\u4E0D\u4F1A\u518D\u628A\u6EDA\u52A8\u6761\u52A0\u56DE\u6765 -->
|
|
803
|
+
<style>*{scrollbar-width:none}::-webkit-scrollbar{display:none}</style>
|
|
804
|
+
<!-- \u903B\u8F91\u5C42\u5EFA\u7684 2d\u3001webgl \u753B\u5E03\u642C\u8FDB wx-canvas \u540E\u94FA\u6EE1\u5B83\uFF08\u89C1 frame.ts \u7684 moveCanvasesIntoPages\uFF09\u3002
|
|
805
|
+
\u57FA\u7840\u5E93\u8FD8\u4F1A\u6309\u903B\u8F91\u5C42\u91CC\u7684\u5E03\u5C40\u6539\u5B83\u7684\u4F4D\u7F6E\u548C\u663E\u9690\uFF0C\u8FD9\u91CC\u4E00\u5F8B\u538B\u4F4F\uFF1B\u89E6\u6478\u7167\u5E38\u4EA4\u7ED9 wx-canvas \u81EA\u5DF1\u7684 canvas -->
|
|
806
|
+
<style>.wxa-service-canvas{position:absolute!important;left:0!important;top:0!important;width:100%!important;height:100%!important;visibility:inherit!important;pointer-events:none}</style>
|
|
807
|
+
<script>var __wxConfig = ${toJs(wxConfig)};</script>
|
|
808
|
+
<script src="/__wxa__/runtime/frame.js" data-kind="webview" data-webview-id="${id}"></script>
|
|
809
|
+
<script src="/__baselib__/WAWebview.js"></script>`;
|
|
810
|
+
}
|
|
595
811
|
function escapeHtml(text) {
|
|
596
812
|
return text.replace(/[&<>"]/g, (ch) => ({ "&": "&", "<": "<", ">": ">", '"': """ })[ch]);
|
|
597
813
|
}
|
|
@@ -697,20 +913,20 @@ var import_child_process = require("child_process");
|
|
|
697
913
|
var import_crypto = require("crypto");
|
|
698
914
|
var import_promises = require("timers/promises");
|
|
699
915
|
var import_ws = require("ws");
|
|
700
|
-
var
|
|
916
|
+
var import_wxa_runner_extractor3 = require("@open-wxa/wxa-runner-extractor");
|
|
701
917
|
var AUTO_PORT = 9420;
|
|
702
918
|
var CLI_TIMEOUT = 6e4;
|
|
703
919
|
var AUTOMATOR_TIMEOUT = 5e3;
|
|
704
920
|
var WINDOW_TIMEOUT = 1e4;
|
|
705
921
|
var WINDOW_RETRY_INTERVAL = 500;
|
|
706
922
|
function developerTicketSource(projectPath, logger) {
|
|
707
|
-
const cli = (0,
|
|
708
|
-
if (!cli) return async () => (0,
|
|
923
|
+
const cli = (0, import_wxa_runner_extractor3.findElectronDevtoolsCli)();
|
|
924
|
+
if (!cli) return async () => (0, import_wxa_runner_extractor3.findDeveloperTicket)();
|
|
709
925
|
let automatorPort = null;
|
|
710
926
|
const startOnce = () => {
|
|
711
927
|
if (!automatorPort) {
|
|
712
928
|
const starting = startAutomation(cli, projectPath).then((port) => {
|
|
713
|
-
logger.log(`[wxa-runner] \
|
|
929
|
+
logger.log(`[wxa-runner] --devtools-login\uFF1A\u5DF2\u5728\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u91CC\u4E3A\u9879\u76EE\u5F00\u542F\u81EA\u52A8\u5316\u63A5\u53E3\uFF08\u7AEF\u53E3 ${port}\uFF09\uFF0Cticket \u4ECE\u5F00\u53D1\u8005\u5DE5\u5177\u5B9E\u65F6\u83B7\u53D6`);
|
|
714
930
|
return port;
|
|
715
931
|
});
|
|
716
932
|
starting.catch(() => {
|
|
@@ -721,7 +937,7 @@ function developerTicketSource(projectPath, logger) {
|
|
|
721
937
|
return automatorPort;
|
|
722
938
|
};
|
|
723
939
|
return async () => {
|
|
724
|
-
if (process.env[
|
|
940
|
+
if (process.env[import_wxa_runner_extractor3.TICKET_ENV]) return { newticket: process.env[import_wxa_runner_extractor3.TICKET_ENV] };
|
|
725
941
|
const port = startOnce();
|
|
726
942
|
try {
|
|
727
943
|
return await requestTicketOnceWindowReady(await port, projectPath);
|
|
@@ -826,74 +1042,62 @@ function explainAutomatorError(message) {
|
|
|
826
1042
|
return new Error(`\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u8FD4\u56DE\u9519\u8BEF\uFF1A${message}`);
|
|
827
1043
|
}
|
|
828
1044
|
|
|
829
|
-
// src/server/
|
|
1045
|
+
// src/server/devtoolsLogin.ts
|
|
830
1046
|
var import_express = __toESM(require("express"));
|
|
831
|
-
var
|
|
832
|
-
var DEV_LOGIC = "https://servicewechat.com/wxa-dev-logic";
|
|
833
|
-
var CLIENT_VERSION = "1021810240";
|
|
834
|
-
var UPSTREAM_TIMEOUT = 1e4;
|
|
1047
|
+
var import_wxa_runner_extractor4 = require("@open-wxa/wxa-runner-extractor");
|
|
835
1048
|
var LOOPBACK_ADDRESSES = ["127.0.0.1", "::1", "::ffff:127.0.0.1"];
|
|
836
1049
|
var LOOPBACK_HOSTS = ["localhost", "127.0.0.1", "[::1]"];
|
|
837
|
-
var
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
40029: "\uFF08\u767B\u5F55\u6001\u5DF2\u5931\u6548\uFF0C\u8BF7\u5728\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u91CC\u91CD\u65B0\u767B\u5F55\uFF09",
|
|
841
|
-
85023: "\uFF08\u5F53\u524D\u5FAE\u4FE1\u8D26\u53F7\u4E0D\u662F\u8BE5\u5C0F\u7A0B\u5E8F\u7684\u5F00\u53D1\u8005\uFF09"
|
|
842
|
-
};
|
|
843
|
-
function requireUsableTicket(ticket) {
|
|
844
|
-
if (!ticket) throw new Error(`\u672A\u627E\u5230\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u7684\u767B\u5F55\u6001\uFF0C\u8BF7\u767B\u5F55\u5F00\u53D1\u8005\u5DE5\u5177\uFF0C\u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF ${import_wxa_runner_extractor2.TICKET_ENV}`);
|
|
845
|
-
if (ticket.expiredAt !== void 0 && ticket.expiredAt <= Date.now()) {
|
|
846
|
-
throw new Error("\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u7684\u767B\u5F55\u6001\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u6253\u5F00\u5F00\u53D1\u8005\u5DE5\u5177\u5237\u65B0\u767B\u5F55\u6001");
|
|
847
|
-
}
|
|
848
|
-
return ticket.newticket;
|
|
849
|
-
}
|
|
850
|
-
function realLoginRouter(appid, findTicket = import_wxa_runner_extractor2.findDeveloperTicket) {
|
|
851
|
-
const callDevLogic = async (endpoint, body) => {
|
|
852
|
-
const query = new URLSearchParams({ appid, newticket: requireUsableTicket(await findTicket()), clientversion: CLIENT_VERSION });
|
|
853
|
-
const response = await fetch(`${DEV_LOGIC}/${endpoint}?${query}`, {
|
|
854
|
-
method: "POST",
|
|
855
|
-
headers: { "Content-Type": "application/json" },
|
|
856
|
-
body: JSON.stringify(body),
|
|
857
|
-
signal: AbortSignal.timeout(UPSTREAM_TIMEOUT)
|
|
858
|
-
}).catch((error) => {
|
|
859
|
-
throw new Error(error.name === "TimeoutError" ? `\u8BF7\u6C42\u5FAE\u4FE1\u670D\u52A1\u5668\u8D85\u65F6\uFF08${UPSTREAM_TIMEOUT / 1e3}s\uFF09` : `\u8BF7\u6C42\u5FAE\u4FE1\u670D\u52A1\u5668\u5931\u8D25\uFF1A${error.cause?.message ?? error.message}`);
|
|
860
|
-
});
|
|
861
|
-
if (!response.ok) throw new Error(`\u5FAE\u4FE1\u670D\u52A1\u5668\u8FD4\u56DE HTTP ${response.status}`);
|
|
862
|
-
return response.json();
|
|
863
|
-
};
|
|
1050
|
+
var FORWARDED_WX_DATA_APIS = ["webapi_servicemarket_jsapi_comm"];
|
|
1051
|
+
function devtoolsLoginRouter(appid, findTicket = import_wxa_runner_extractor4.findDeveloperTicket) {
|
|
1052
|
+
const wechat = new WechatDevClient(appid, findTicket);
|
|
864
1053
|
const router = import_express.default.Router();
|
|
865
1054
|
router.use(onlyLoopback);
|
|
866
1055
|
router.post("/login", respond(async () => {
|
|
867
|
-
const body = await
|
|
868
|
-
|
|
869
|
-
if (errcode !== 0 || !body.code) {
|
|
870
|
-
throw new Error(`\u5FAE\u4FE1\u767B\u5F55\u5931\u8D25 ${errcode}: ${body.baseresponse?.errmsg || "\u672A\u77E5\u9519\u8BEF"}${ERROR_HINTS[errcode] ?? ""}`);
|
|
871
|
-
}
|
|
1056
|
+
const body = requireOk(await wechat.postJson("wxa-dev-logic/jslogin", { scope: ["snsapi_base"] }), "\u5FAE\u4FE1\u767B\u5F55\u5931\u8D25");
|
|
1057
|
+
if (!body.code) throw new Error("\u5FAE\u4FE1\u767B\u5F55\u5931\u8D25\uFF1A\u5FAE\u4FE1\u6CA1\u6709\u8FD4\u56DE code");
|
|
872
1058
|
return { code: body.code };
|
|
873
1059
|
}));
|
|
874
1060
|
router.post("/phone-number", respond(async () => {
|
|
875
|
-
const body = await
|
|
1061
|
+
const body = await wechat.postJson("wxa-dev-logic/jsgetuserwxphone", { appid });
|
|
876
1062
|
const errcode = body.jsapi_baseresponse?.errcode ?? body.BaseResponse?.Ret;
|
|
877
1063
|
if (errcode !== 0 || typeof body.data !== "string") {
|
|
878
1064
|
const errmsg = body.jsapi_baseresponse?.errmsg || body.BaseResponse?.ErrMsg?.String || "\u672A\u77E5\u9519\u8BEF";
|
|
879
|
-
throw new Error(`\u83B7\u53D6\u624B\u673A\u53F7\u5931\u8D25 ${errcode}: ${errmsg}${
|
|
1065
|
+
throw new Error(`\u83B7\u53D6\u624B\u673A\u53F7\u5931\u8D25 ${errcode}: ${errmsg}${explainErrcode(errcode)}`);
|
|
880
1066
|
}
|
|
881
1067
|
const { encryptedData, iv } = JSON.parse(body.data);
|
|
882
1068
|
return { data: body.data, encryptedData, iv };
|
|
883
1069
|
}));
|
|
1070
|
+
router.post("/operate-wx-data", import_express.default.json({ limit: "10mb" }), (req, res, next) => {
|
|
1071
|
+
const apiName = req.body?.data?.api_name;
|
|
1072
|
+
if (FORWARDED_WX_DATA_APIS.includes(apiName)) return next();
|
|
1073
|
+
res.status(403).json({ error: `operateWXData \u53EA\u8F6C\u53D1\u670D\u52A1\u5E02\u573A\u7684\u8BF7\u6C42\uFF0C\u4E0D\u8F6C\u53D1 ${apiName}` });
|
|
1074
|
+
}, respond(async (req) => {
|
|
1075
|
+
const body = requireOk(await wechat.postJson("wxa-dev-logic/jsoperatewxdata", { data: JSON.stringify(req.body.data) }), "\u670D\u52A1\u5E02\u573A\u8C03\u7528\u5931\u8D25");
|
|
1076
|
+
if (typeof body.data !== "string") throw new Error("\u670D\u52A1\u5E02\u573A\u8C03\u7528\u5931\u8D25\uFF1A\u5FAE\u4FE1\u6CA1\u6709\u8FD4\u56DE\u7ED3\u679C");
|
|
1077
|
+
return { data: JSON.parse(body.data) };
|
|
1078
|
+
}));
|
|
1079
|
+
router.post("/verify-plugin", import_express.default.json(), respond(async (req) => {
|
|
1080
|
+
const body = requireOk(await wechat.postJson("wxa-dev-logic/verifyplugin", { ext_info: JSON.stringify(req.body?.data || {}) }), "\u63D2\u4EF6\u6821\u9A8C\u5931\u8D25");
|
|
1081
|
+
return { data: { list: body.list || [] } };
|
|
1082
|
+
}));
|
|
1083
|
+
router.post("/batch-get-contact", import_express.default.json(), respond(async (req) => {
|
|
1084
|
+
const body = requireOk(await wechat.postJson("wxa-dev-logic/batchgetcontact", { appid_list: req.body?.appIds || [] }), "\u83B7\u53D6\u63D2\u4EF6\u4FE1\u606F\u5931\u8D25");
|
|
1085
|
+
const contacts = body.contact_list || [];
|
|
1086
|
+
return { contactList: contacts.filter((contact) => contact.plugin_info).map((contact) => ({ appId: contact.appid, plugin_list: contact.plugin_info.plugin_list })) };
|
|
1087
|
+
}));
|
|
884
1088
|
return router;
|
|
885
1089
|
}
|
|
886
1090
|
function onlyLoopback(req, res, next) {
|
|
887
1091
|
if (!LOOPBACK_ADDRESSES.includes(req.socket.remoteAddress || "") || !LOOPBACK_HOSTS.includes(req.hostname)) {
|
|
888
|
-
res.status(403).json({ error: "\
|
|
1092
|
+
res.status(403).json({ error: "\u5F00\u53D1\u8005\u767B\u5F55\u6001\u63A5\u53E3\u53EA\u5141\u8BB8\u672C\u673A\u8BBF\u95EE" });
|
|
889
1093
|
return;
|
|
890
1094
|
}
|
|
891
1095
|
next();
|
|
892
1096
|
}
|
|
893
1097
|
function respond(action) {
|
|
894
|
-
return async (
|
|
1098
|
+
return async (req, res) => {
|
|
895
1099
|
try {
|
|
896
|
-
res.json(await action());
|
|
1100
|
+
res.json(await action(req));
|
|
897
1101
|
} catch (error) {
|
|
898
1102
|
res.status(500).json({ error: error.message });
|
|
899
1103
|
}
|
|
@@ -1024,11 +1228,16 @@ var DevServer = class {
|
|
|
1024
1228
|
this.tempFiles = /* @__PURE__ */ new Map();
|
|
1025
1229
|
this.logger = options.logger || console;
|
|
1026
1230
|
this.project = new MiniProgram(import_path4.default.resolve(options.projectPath));
|
|
1027
|
-
this.baseLib = (0,
|
|
1231
|
+
this.baseLib = (0, import_wxa_runner_extractor5.resolveBaseLib)({ version: options.baseLibVersion, cacheDir: options.baseLibCacheDir });
|
|
1028
1232
|
if (!this.baseLib.compatible) {
|
|
1029
1233
|
this.logger.warn(`[wxa-runner] \u57FA\u7840\u5E93 ${this.baseLib.version} \u9AD8\u4E8E\u5DF2\u9A8C\u8BC1\u7684\u7248\u672C\u8303\u56F4\uFF0C\u53EF\u80FD\u65E0\u6CD5\u6B63\u5E38\u8FD0\u884C`);
|
|
1030
1234
|
}
|
|
1031
|
-
|
|
1235
|
+
if (options.realLogin !== void 0 && options.devtoolsLogin === void 0) {
|
|
1236
|
+
this.logger.warn("[wxa-runner] realLogin\uFF08--real-login\uFF09\u5DF2\u6539\u540D\u4E3A devtoolsLogin\uFF08--devtools-login\uFF09\uFF0C\u65E7\u540D\u4EE5\u540E\u4F1A\u79FB\u9664");
|
|
1237
|
+
}
|
|
1238
|
+
this.devtoolsLogin = (options.devtoolsLogin ?? options.realLogin) === true;
|
|
1239
|
+
this.ticketSource = this.devtoolsLogin ? developerTicketSource(this.project.projectPath, this.logger) : null;
|
|
1240
|
+
this.plugins = new PluginStore(this.ticketSource && new WechatDevClient(this.project.appid, this.ticketSource), this.logger);
|
|
1032
1241
|
this.device = { ...DEFAULT_DEVICE, ...options.device };
|
|
1033
1242
|
this.builder = new AppBuilder(this.project);
|
|
1034
1243
|
this.setupFile = resolveSetupFile(options.setup, this.project.projectPath);
|
|
@@ -1064,7 +1273,7 @@ ${error.message}`);
|
|
|
1064
1273
|
const { port } = server.address();
|
|
1065
1274
|
this.address = `http://${host}:${port}`;
|
|
1066
1275
|
if (this.options.watch !== false) this.startWatching();
|
|
1067
|
-
this.ticketSource?.().then(requireUsableTicket).catch((error) => this.logger.warn(`[wxa-runner] \
|
|
1276
|
+
this.ticketSource?.().then(requireUsableTicket).catch((error) => this.logger.warn(`[wxa-runner] \u5F00\u53D1\u8005\u5DE5\u5177\u7684\u767B\u5F55\u6001\u6682\u4E0D\u53EF\u7528\uFF08--devtools-login\uFF09\uFF1A${error.message}`));
|
|
1068
1277
|
return this.address;
|
|
1069
1278
|
}
|
|
1070
1279
|
async close() {
|
|
@@ -1091,9 +1300,9 @@ ${error.message}`);
|
|
|
1091
1300
|
});
|
|
1092
1301
|
app.get("/__wxa__/app-info.json", async (_req, res) => {
|
|
1093
1302
|
noStore(res);
|
|
1094
|
-
const base = { appid: this.project.appid, baseLibVersion: this.baseLib.version, device: this.device,
|
|
1303
|
+
const base = { appid: this.project.appid, baseLibVersion: this.baseLib.version, device: this.device, devtoolsLogin: this.devtoolsLogin };
|
|
1095
1304
|
try {
|
|
1096
|
-
const build2 = await this.builder.build();
|
|
1305
|
+
const build2 = await this.plugins.refresh(await this.builder.build());
|
|
1097
1306
|
const info = { ...base, version: build2.version, wxConfig: build2.wxConfig, pages: build2.pages };
|
|
1098
1307
|
if (this.setupFile) info.setup = await this.setupInfo(this.setupFile);
|
|
1099
1308
|
res.json(info);
|
|
@@ -1116,7 +1325,7 @@ ${error.message}`);
|
|
|
1116
1325
|
app.get("/__wxa__/appservice.html", this.withBuild((build2, req, res) => {
|
|
1117
1326
|
const launchPath = String(req.query.path || "").replace(/^\//, "");
|
|
1118
1327
|
const launch = build2.pages.includes(launchPath) ? { path: launchPath, query: Object.fromEntries(new URLSearchParams(String(req.query.query || ""))) } : { path: build2.pages[0], query: {} };
|
|
1119
|
-
res.type("html").send(appserviceHtml(build2, launch, { hot: this.hotEnabled, isolated: (0,
|
|
1328
|
+
res.type("html").send(appserviceHtml(build2, launch, { hot: this.hotEnabled, isolated: (0, import_wxa_runner_extractor5.usesIsolatedContext)(this.baseLib.version) }));
|
|
1120
1329
|
}));
|
|
1121
1330
|
app.get("/__wxa__/subcontext.html", (req, res) => {
|
|
1122
1331
|
const id = Number(req.query.id);
|
|
@@ -1129,16 +1338,32 @@ ${error.message}`);
|
|
|
1129
1338
|
app.get(/^\/__wxa__\/webview\/(.+)\.html$/, this.withBuild((build2, req, res, next) => {
|
|
1130
1339
|
const pagePath = decodeURIComponent(req.params[0]);
|
|
1131
1340
|
if (!build2.pages.includes(pagePath)) return next();
|
|
1132
|
-
|
|
1341
|
+
const pluginPage = findPluginPage(build2, pagePath);
|
|
1342
|
+
res.type("html").send(pluginPage ? pluginWebviewHtml(build2, pluginPage.plugin, pluginPage.innerPath, pagePath, Number(req.query.id)) : webviewHtml(build2, pagePath, Number(req.query.id), { hot: this.hotEnabled }));
|
|
1343
|
+
}));
|
|
1344
|
+
app.get("/__wxa__/plugin/:provider/:version/:file(appservice.js|pageframe.js)", this.withBuild((build2, req, res, next) => {
|
|
1345
|
+
const { provider, version, file } = req.params;
|
|
1346
|
+
const code = build2.plugins.find((plugin) => plugin.provider === provider && plugin.version === version)?.files.get(`/${file}`);
|
|
1347
|
+
if (!code) return next();
|
|
1348
|
+
res.type("js").send(code);
|
|
1349
|
+
}));
|
|
1350
|
+
app.get(/^\/__plugin__\/([^/]+)(\/.+)$/, this.withBuild((build2, req, res, next) => {
|
|
1351
|
+
const file = build2.plugins.find((plugin) => plugin.provider === req.params[0])?.files.get(decodeURIComponent(req.params[1]));
|
|
1352
|
+
if (!file) return next();
|
|
1353
|
+
res.type(import_path4.default.extname(req.params[1]) || "application/octet-stream").send(file);
|
|
1133
1354
|
}));
|
|
1134
1355
|
app.get(/^\/__wxa__\/module\/(.+\.js)$/, this.withBuild((build2, req, res) => {
|
|
1135
1356
|
const id = decodeURIComponent(req.params[0]);
|
|
1136
|
-
if (!build2.modules.includes(id)) {
|
|
1357
|
+
if (!build2.modules.includes(id) && !build2.workerModules.includes(id)) {
|
|
1137
1358
|
res.status(404).type("js").send(`console.error(${JSON.stringify(`[wxa-runner] \u6A21\u5757 ${id} \u4E0D\u5B58\u5728`)})`);
|
|
1138
1359
|
return;
|
|
1139
1360
|
}
|
|
1140
1361
|
res.type("js").send(this.builder.getModuleScript(id));
|
|
1141
1362
|
}));
|
|
1363
|
+
app.get("/__wxa__/worker.js", this.withBuild((build2, _req, res) => {
|
|
1364
|
+
const hasWorker = import_fs4.default.existsSync(import_path4.default.join(this.baseLib.dir, "WAWorker.js"));
|
|
1365
|
+
res.type("js").send(workerScript(build2, { version: this.baseLib.version, hasWorker }));
|
|
1366
|
+
}));
|
|
1142
1367
|
app.get("/__wxa__/service-bootstrap.js", this.withBuild((build2, _req, res) => {
|
|
1143
1368
|
res.type("js").send(build2.serviceBootstrap);
|
|
1144
1369
|
}));
|
|
@@ -1181,7 +1406,7 @@ ${error.message}`);
|
|
|
1181
1406
|
});
|
|
1182
1407
|
app.get("/__wxa__/region/:kind", (req, res) => {
|
|
1183
1408
|
const kind = req.params.kind;
|
|
1184
|
-
const data = kind === "districts" || kind === "streets" ? (0,
|
|
1409
|
+
const data = kind === "districts" || kind === "streets" ? (0, import_wxa_runner_extractor5.readRegionData)(kind) : null;
|
|
1185
1410
|
if (!data) {
|
|
1186
1411
|
res.status(404).end();
|
|
1187
1412
|
return;
|
|
@@ -1214,7 +1439,7 @@ ${error.message}`);
|
|
|
1214
1439
|
app.delete("/__wxa__/tmp/:name", (req, res) => {
|
|
1215
1440
|
res.status(this.tempFiles.delete(req.params.name) ? 204 : 404).end();
|
|
1216
1441
|
});
|
|
1217
|
-
if (this.ticketSource) app.use("/__wxa__/api",
|
|
1442
|
+
if (this.ticketSource) app.use("/__wxa__/api", devtoolsLoginRouter(this.project.appid, this.ticketSource));
|
|
1218
1443
|
app.use("/__wxa__/webview", import_express2.default.static(root));
|
|
1219
1444
|
app.use(import_express2.default.static(root));
|
|
1220
1445
|
app.use((error, _req, res, _next) => {
|
|
@@ -1232,13 +1457,17 @@ ${error.message}`);
|
|
|
1232
1457
|
return { env: this.setupEnv, error: error.message };
|
|
1233
1458
|
}
|
|
1234
1459
|
}
|
|
1460
|
+
/** 构建结果并入这次打开小程序时决定用的插件 */
|
|
1461
|
+
async currentBuild() {
|
|
1462
|
+
return this.plugins.current(await this.builder.build());
|
|
1463
|
+
}
|
|
1235
1464
|
/** 需要构建结果的路由;构建失败时返回错误文本 */
|
|
1236
1465
|
withBuild(handler) {
|
|
1237
1466
|
return async (req, res, next) => {
|
|
1238
1467
|
res.setHeader("Cache-Control", "no-store");
|
|
1239
1468
|
let build2;
|
|
1240
1469
|
try {
|
|
1241
|
-
build2 = await this.
|
|
1470
|
+
build2 = await this.currentBuild();
|
|
1242
1471
|
} catch (error) {
|
|
1243
1472
|
res.status(500).type("text").send(error.message);
|
|
1244
1473
|
return;
|