@shijiu/jsview 2.3.0 → 2.3.728-alpha.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/dom/bin/jsview-dom-browser-engine-core.min.js +1 -1
- package/dom/bin/jsview-dom-browser-engine-modules.min.js +1 -1
- package/dom/bin/{jsview-dom-browser-forge.1436.54c9.wasm → jsview-dom-browser-forge.1798.9ed7.wasm} +0 -0
- package/dom/bin/jsview-dom-browser-forge.min.js +1 -1
- package/dom/bin/jsview-dom-browser-forge.worker.min.js +1 -1
- package/dom/bin/jsview-dom-browser.min.js +1 -1
- package/dom/bin/jsview-dom-native.min.js +1 -1
- package/dom/bin/jsview-engine-js-browser.min.js +1 -1
- package/dom/bin/jsview-engine-js-native.min.js +1 -1
- package/dom/bin/jsview-forge-define.min.js +1 -1
- package/dom/target_core_revision.mjs +2 -2
- package/loader/jsv-core-api/jsview-core-api-glue.js +12 -1
- package/loader/jsv-core-api/wasm/core-api.js +95 -1
- package/loader/jsv-core-api/wasm/wasm-extension.js +5 -0
- package/loader/jsview-loader.js +10 -3
- package/loader/jsview-main.mjs +1 -0
- package/loader/jsview.config.default.js +4 -0
- package/package.json +1 -1
- package/patches/node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js +6 -2
- package/tools/jsview-build-zip.mjs +7 -2
- package/tools/jsview-common.mjs +10 -1
- package/tools/jsview-post-build.mjs +88 -6
- package/tools/jsview-post-install.mjs +10 -4
- package/tools/jsview-run-tool.mjs +3 -6
|
@@ -10,6 +10,7 @@ export default class WasmCoreApis {
|
|
|
10
10
|
this.EngineJs = "embedded";
|
|
11
11
|
this.UrlBuilder = URL;
|
|
12
12
|
this.Platform = "pc-wasm"; // 平台信息,可选有 android/pc-wasm/harmony-webview
|
|
13
|
+
this.ProcessType = "wasm";
|
|
13
14
|
|
|
14
15
|
this._ForgeHandle = null;
|
|
15
16
|
|
|
@@ -157,6 +158,14 @@ export default class WasmCoreApis {
|
|
|
157
158
|
console.log("removeGlobalJsExceptionAck not implemented");
|
|
158
159
|
}
|
|
159
160
|
|
|
161
|
+
addModuleFailedAck(callback) {
|
|
162
|
+
console.log("addModuleFailedAck not implemented");
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
removeModuleFailedAck(callback) {
|
|
166
|
+
console.log("removeModuleFailedAck not implemented");
|
|
167
|
+
}
|
|
168
|
+
|
|
160
169
|
toggleViewVisible(toVisible) {
|
|
161
170
|
console.log("toggleViewVisible not implemented");
|
|
162
171
|
}
|
|
@@ -189,8 +198,22 @@ export default class WasmCoreApis {
|
|
|
189
198
|
// wasm不支持调整 cookie domain
|
|
190
199
|
}
|
|
191
200
|
|
|
201
|
+
refreshCookies() {
|
|
202
|
+
// wasm不支持调整 cookie domain
|
|
203
|
+
}
|
|
204
|
+
|
|
192
205
|
setRenderGlobalConfig(json) {
|
|
193
|
-
|
|
206
|
+
// 抓取forge_config中需要的配置, 保持未设时, 在forge_config中也不存在
|
|
207
|
+
const forge_config = {};
|
|
208
|
+
['texCache', 'holderCache', 'simulDecodeNum', 'touchSlop', 'wheelRate'].forEach(key => { if (key in json) forge_config[key] = json[key]; });
|
|
209
|
+
this._ForgeHandle?.sRenderBridge.SetGlobalConfig(forge_config);
|
|
210
|
+
|
|
211
|
+
// 抓取dom_config中需要的配置, 保持未设时, 在dom_config中也不存在
|
|
212
|
+
const dom_config = {};
|
|
213
|
+
['maxDomSync'].forEach(key => { if (key in json) dom_config[key] = json[key]; });
|
|
214
|
+
if (typeof dom_config.maxDomSync == 'number') {
|
|
215
|
+
window.JsvCode.Dom.SetLazyTaskOverLoadLevel(dom_config.maxDomSync);
|
|
216
|
+
}
|
|
194
217
|
}
|
|
195
218
|
|
|
196
219
|
setForgeJsHandle(forgeHandle) {
|
|
@@ -201,8 +224,79 @@ export default class WasmCoreApis {
|
|
|
201
224
|
console.log("onMainTsDone...");
|
|
202
225
|
}
|
|
203
226
|
|
|
227
|
+
/**
|
|
228
|
+
* 完全释放GLView, 以达到完全清理GL内存的目的,一般配合JsView的visibility的回调一齐使用
|
|
229
|
+
* 场景1: 可以通过此接口,规避在android 9.0上把其他进程的GL内存都算在本进程的内存统计上的问题
|
|
230
|
+
* 场景2: 完全释放绘制资源,以保证作为Launcher时,退到后时最小化内存
|
|
231
|
+
*
|
|
232
|
+
* @param delayedTimeMs int类型 延迟关闭View的时间,可以为0, 单位:秒
|
|
233
|
+
*/
|
|
234
|
+
delayRemoveGLView(delayedTimeSec) {
|
|
235
|
+
console.log("delayRemoveGLView not implemented in wasm");
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* 恢复已经被关闭的GLView,一般在delayRemoveGLView后对GLView进行重新展示
|
|
240
|
+
* 此接口内部有状态自查,可以在任何状态调用,既使 delayRemoveGLView 没有触发
|
|
241
|
+
*/
|
|
242
|
+
restoreGLView() {
|
|
243
|
+
console.log("restoreGLView not implemented in wasm");
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// wasm专属api调试api, tag参数中以空格隔开每个tag
|
|
204
247
|
enableConsoleTag(tag) {
|
|
205
248
|
this.WasmExt.ForgeLogRef?.EnableTag(tag);
|
|
206
249
|
this.WasmExt.JseLogRef?.EnableTag(tag);
|
|
207
250
|
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* 用户无操作时降帧的功能
|
|
254
|
+
*
|
|
255
|
+
* @param enable boolean类型, 是否开启此功能
|
|
256
|
+
* @param idleFps int类型, 0-60, 开启时限制的帧率
|
|
257
|
+
* @param idleTimeMs int类型, 用户无操作多少时间后降帧(毫秒)
|
|
258
|
+
*/
|
|
259
|
+
setIdleFps(enable, idleFps, idleTimeMs) {
|
|
260
|
+
console.log("setIdleFps not implemented in wasm");
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* 保持fps高帧率的开关,主要用于灵活控制用户无操作时降帧功能的小开关
|
|
265
|
+
*
|
|
266
|
+
* @param enable boolean类型, 是否保持,保持时关闭降帧功能,不保持时开启降帧功能
|
|
267
|
+
*/
|
|
268
|
+
keepFpsHighPerf(enable) {
|
|
269
|
+
console.log("keepFpsHighPerf not implemented in wasm");
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* 设置图片缓存上限,默认为80M,每次进行回收时会自动回收到其3/4
|
|
274
|
+
* @params new_level int, 新水位
|
|
275
|
+
*/
|
|
276
|
+
setTextureMaxWaterLevel(level) {
|
|
277
|
+
console.log("setTextureMaxWaterLevel not implemented in wasm");
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
base64ToLatinBytes(base64String) {
|
|
281
|
+
// 在wasm版本中,String会转成uint8Array, 和C++的jse::impl::JseStringImpl中的处理呼应
|
|
282
|
+
// 因为在wasm,native层无法直接按照Latin-1编码提取String
|
|
283
|
+
const bytes = atob(base64String);
|
|
284
|
+
const uint8Array = new Uint8Array(bytes.length);
|
|
285
|
+
|
|
286
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
287
|
+
const code = bytes.charCodeAt(i);
|
|
288
|
+
// Latin-1 范围是 0x00-0xFF,超出范围的字符会被截断
|
|
289
|
+
uint8Array[i] = code & 0xFF;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return uint8Array;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
AddSwappedOnceListener(callback) {
|
|
296
|
+
console.log("AddSwappedOnceListener not implemented in wasm");
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
RemoveSwappedOnceListener(callback) {
|
|
300
|
+
console.log("RemoveSwappedOnceListener not implemented in wasm");
|
|
301
|
+
}
|
|
208
302
|
}
|
|
@@ -34,4 +34,9 @@ export default class WasmCoreApisExtension {
|
|
|
34
34
|
this.ForgeLogRef = forge_log_ref;
|
|
35
35
|
this.JseLogRef = jse_log_ref;
|
|
36
36
|
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// 补充setJsvAppConfig api,用于在wasm场景下设置app配置
|
|
40
|
+
if (!window.setJsvAppConfig) {
|
|
41
|
+
window.setJsvAppConfig = function(appConfig) { }
|
|
37
42
|
}
|
package/loader/jsview-loader.js
CHANGED
|
@@ -20,7 +20,7 @@ class JsThreadBlockTester {
|
|
|
20
20
|
if (gap > CYCLE_TIME + BLOCK_CHECK_TIME) {
|
|
21
21
|
console.warn(JsThreadBlockTester.#TAG, `js thread blocked, preTime: ${preTimestamp}, curTime: ${JsThreadBlockTester.#timestamp}, curTime-preTime: ${gap}`);
|
|
22
22
|
}
|
|
23
|
-
JsThreadBlockTester.#timeoutHandler =
|
|
23
|
+
JsThreadBlockTester.#timeoutHandler = window.JsvCoreApi.BackgroundTask.postDelay(JsThreadBlockTester.#checkTask, CYCLE_TIME);
|
|
24
24
|
};
|
|
25
25
|
static #onVisibleChange = (data) => {
|
|
26
26
|
if (data.status == "hide") {
|
|
@@ -42,12 +42,12 @@ class JsThreadBlockTester {
|
|
|
42
42
|
static #start() {
|
|
43
43
|
console.log(JsThreadBlockTester.#TAG, "start");
|
|
44
44
|
JsThreadBlockTester.#timestamp = Date.now();
|
|
45
|
-
JsThreadBlockTester.#timeoutHandler =
|
|
45
|
+
JsThreadBlockTester.#timeoutHandler = window.JsvCoreApi.BackgroundTask.postDelay(JsThreadBlockTester.#checkTask, CYCLE_TIME);
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
static #stop() {
|
|
49
49
|
console.log(JsThreadBlockTester.#TAG, "stop");
|
|
50
|
-
|
|
50
|
+
window.JsvCoreApi.BackgroundTask.clear(JsThreadBlockTester.#timeoutHandler);
|
|
51
51
|
JsThreadBlockTester.#timeoutHandler = -1;
|
|
52
52
|
}
|
|
53
53
|
}
|
|
@@ -138,6 +138,13 @@ export default class JsViewLoader {
|
|
|
138
138
|
// (可选配置)按键接受的扩展,例如将静音按键(JAVA键值为164)映射为JS键值20001,PS:注意"164"的引号
|
|
139
139
|
window.JsvCoreApi.addKeysMap(this.#config.vendorConfig.bindKeys);
|
|
140
140
|
|
|
141
|
+
// 设置触摸滑动距离阈值
|
|
142
|
+
if (this.#config.vendorConfig.touchConfig.slop > 0) {
|
|
143
|
+
window.JsvCoreApi.setRenderGlobalConfig({
|
|
144
|
+
touchSlop: this.#config.vendorConfig.touchConfig.slop
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
141
148
|
// (可选配置)localStorage支持
|
|
142
149
|
let storageDomain = this.#config.jsviewConfig.localStorage.domain;
|
|
143
150
|
if (!storageDomain || storageDomain === "default") {
|
package/loader/jsview-main.mjs
CHANGED
|
@@ -17,6 +17,7 @@ async function main() {
|
|
|
17
17
|
const onInitJsViewEnv = async function () {
|
|
18
18
|
// JsView环境加载完毕后,加载vue/react的main.js文件。
|
|
19
19
|
try {
|
|
20
|
+
window.setJsvAppConfig(JSON.stringify(appConfig));
|
|
20
21
|
await import('/src/main.tsx');
|
|
21
22
|
} finally {
|
|
22
23
|
window.JsvCoreApi.onMainTsDone(); // 通知Java, 此时app首次渲染执行完毕
|
package/package.json
CHANGED
|
@@ -368,6 +368,7 @@ const comparator = (a, b) => {
|
|
|
368
368
|
};
|
|
369
369
|
// JsView Modified >>>
|
|
370
370
|
let JsvRenderCount = 0;
|
|
371
|
+
let hasBreakEnableApi = !!(window.JsView?.ifRenderBreakEnable);
|
|
371
372
|
// JsView Modified <<<
|
|
372
373
|
function flushJobs(seen) {
|
|
373
374
|
isFlushPending = false;
|
|
@@ -5167,8 +5168,9 @@ function baseCreateRenderer(options, createHydrationFns) {
|
|
|
5167
5168
|
// 有按键打断, 取消patch
|
|
5168
5169
|
if (n1 == null && n2) {
|
|
5169
5170
|
if (n2.key == "__QcodeJsviewMetroWidgetSlot"
|
|
5171
|
+
&& (!hasBreakEnableApi || window.JsView.ifRenderBreakEnable())
|
|
5170
5172
|
&& (jsvPendingForFirstDelayRender
|
|
5171
|
-
|| window.JsvCode.Dom.
|
|
5173
|
+
|| window.JsvCode.Dom.IsLazyTaskQueueOverLoad() // 用于解决一次性dom元素过多导致一帧卡太久的问题
|
|
5172
5174
|
|| window.JsView?.hasPendingUserInput?.())
|
|
5173
5175
|
&& JsvRenderCount >= (window.JsView?.getInstantRenderNum?.() ?? 0)) {
|
|
5174
5176
|
// 创建Comment节点, 以解决el释放可能出错问题
|
|
@@ -5184,7 +5186,9 @@ function baseCreateRenderer(options, createHydrationFns) {
|
|
|
5184
5186
|
}
|
|
5185
5187
|
};
|
|
5186
5188
|
|
|
5187
|
-
|
|
5189
|
+
// TODO: 有时候children[0]不存在
|
|
5190
|
+
// TODO: 为什么需要对children[0]进行设置?是否是考虑patch时第一子节点不递归的问题, 需要vue版本升级时重新评估
|
|
5191
|
+
if (n2.children?.[0]?.key === "__QcodeJsviewMetroWidgetSlot") {
|
|
5188
5192
|
n2.children[0].anchor = anchor;
|
|
5189
5193
|
n2.children[0].jsvRenderBreaker = {
|
|
5190
5194
|
breaked: true,
|
|
@@ -21,12 +21,16 @@ async function main(argv)
|
|
|
21
21
|
const zipName = 'dist.dat';
|
|
22
22
|
const zipPath = path.resolve(options.distDir, zipName);
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
let password = argv.password ?? 'jsview.shijiu.com';
|
|
25
|
+
if(argv.noPassword) {
|
|
26
|
+
password = null;
|
|
27
|
+
}
|
|
25
28
|
|
|
26
29
|
execCommand('npm run build');
|
|
27
30
|
|
|
28
31
|
let childFileNames = fs.readdirSync(options.distDir);
|
|
29
32
|
childFileNames = childFileNames.filter(it => it !== zipName);
|
|
33
|
+
childFileNames = childFileNames.filter(it => it !== 'debug');
|
|
30
34
|
childFileNames = childFileNames.map(it => path.resolve(options.distDir, it));
|
|
31
35
|
|
|
32
36
|
makeZip(zipPath, password, ...childFileNames)
|
|
@@ -37,7 +41,8 @@ async function main(argv)
|
|
|
37
41
|
const requiredUsages = {
|
|
38
42
|
};
|
|
39
43
|
const optionalUsages = {
|
|
40
|
-
'--password': 'Input
|
|
44
|
+
'--password': 'Input password',
|
|
45
|
+
'--no-password': 'Ignore password',
|
|
41
46
|
};
|
|
42
47
|
const argv = parseArguments(requiredUsages, optionalUsages);
|
|
43
48
|
main(argv);
|
package/tools/jsview-common.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
1
|
+
// #!/usr/bin/env node
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
import childProcess from 'node:child_process';
|
|
@@ -66,6 +66,10 @@ function parseArguments(requiredUsages = {},
|
|
|
66
66
|
|| value === 'null'
|
|
67
67
|
|| value === '') {
|
|
68
68
|
formattedValue = null;
|
|
69
|
+
} else if(value === 'true') {
|
|
70
|
+
formattedValue = true;
|
|
71
|
+
} else if(value === 'false') {
|
|
72
|
+
formattedValue = false;
|
|
69
73
|
}
|
|
70
74
|
return formattedValue;
|
|
71
75
|
}
|
|
@@ -180,6 +184,7 @@ function parseArguments(requiredUsages = {},
|
|
|
180
184
|
* jsview-test-project
|
|
181
185
|
* ├── dist
|
|
182
186
|
* │ ├── assets
|
|
187
|
+
* │ ├── css
|
|
183
188
|
* │ ├── debug
|
|
184
189
|
* │ │ └── map
|
|
185
190
|
* │ └── js
|
|
@@ -197,6 +202,7 @@ function parseArguments(requiredUsages = {},
|
|
|
197
202
|
* │ │ │ ├── tools
|
|
198
203
|
* │ │ ├── jsview-vue -> ../../../../@shijiu/jsview-vue
|
|
199
204
|
* │ │ │ └── utils
|
|
205
|
+
* │ │ ├── jsview-vue-plus -> ../../../../@shijiu/jsview-vue-plus
|
|
200
206
|
* │ │ └── jsview-vue-samples -> ../../../../@shijiu/jsview-vue-samples
|
|
201
207
|
* └── src
|
|
202
208
|
* └── appConfig
|
|
@@ -217,6 +223,7 @@ function getOptions(framework)
|
|
|
217
223
|
options.jsviewDomRevisionFile = path.resolve(options.jsviewDir, 'dom', 'target_core_revision.mjs');
|
|
218
224
|
|
|
219
225
|
options.jsviewVueDir = path.resolve(options.modulesDir, '@shijiu', 'jsview-vue');
|
|
226
|
+
options.jsviewVuePlusDir = path.resolve(options.modulesDir, '@shijiu', 'jsview-vue-plus');
|
|
220
227
|
options.jsviewReactDir = path.resolve(options.modulesDir, '@shijiu', 'jsview-react');
|
|
221
228
|
if (framework) {
|
|
222
229
|
options.jsviewFrameworkDir = path.resolve(options.modulesDir, '@shijiu', 'jsview-' + framework);
|
|
@@ -240,10 +247,12 @@ function getOptions(framework)
|
|
|
240
247
|
}
|
|
241
248
|
}
|
|
242
249
|
}
|
|
250
|
+
options.distJsvConfigFile = path.resolve(options.distDir, 'jsv-config.json');
|
|
243
251
|
options.distJsvListFile = path.resolve(options.distDir, 'jsv-list.json');
|
|
244
252
|
options.distJsvInfoFile = path.resolve(options.distDir, 'jsv-info.json');
|
|
245
253
|
options.distJsIndexFile = path.resolve(options.distDir, 'index.html');
|
|
246
254
|
options.distAssetsDir = path.resolve(options.distDir, 'assets');
|
|
255
|
+
options.distCssDir = path.resolve(options.distDir, 'css');
|
|
247
256
|
options.distJsDir = path.resolve(options.distDir, 'js');
|
|
248
257
|
options.distDebugDir = path.resolve(options.distDir, 'debug');
|
|
249
258
|
options.distDebugMapDir = path.resolve(options.distDebugDir, 'map');
|
|
@@ -95,6 +95,7 @@ function updateOptions(options)
|
|
|
95
95
|
options.appPrivKey = privKey;
|
|
96
96
|
options.appPubKey = pubKey;
|
|
97
97
|
options.appEntryMd5 = appEntryMd5;
|
|
98
|
+
options.appEntryFileName = `main.jsv.${options.appEntryMd5.slice(0, 8)}.js`;
|
|
98
99
|
}
|
|
99
100
|
|
|
100
101
|
function getOtherSignVerifyKeys(options)
|
|
@@ -191,6 +192,22 @@ async function prepareMainAppData(options)
|
|
|
191
192
|
preloadBurdenResources.push(fileName);
|
|
192
193
|
}
|
|
193
194
|
|
|
195
|
+
const aesKeyFilePath = path.resolve(options.appConfigDir, 'fingerprint_aes_key.mjs');
|
|
196
|
+
if (fs.existsSync(aesKeyFilePath)) {
|
|
197
|
+
const aesKeyFileUrl = url.pathToFileURL(aesKeyFilePath);
|
|
198
|
+
const { default: aesKeyConfig } = await import (aesKeyFileUrl);
|
|
199
|
+
const aesKey = aesKeyConfig.aes_key;
|
|
200
|
+
const aesIv = aesKeyConfig.iv;
|
|
201
|
+
|
|
202
|
+
// 对appConfig.AppName进行aes加密并赋值给EncryptCode2
|
|
203
|
+
if (aesKey && aesIv) {
|
|
204
|
+
const cipher = crypto.createCipheriv('aes-128-cbc', Buffer.from(aesKey, 'utf8'), Buffer.from(aesIv, 'utf8'));
|
|
205
|
+
let encrypted = cipher.update(appConfig.AppName, 'utf8', 'base64');
|
|
206
|
+
encrypted += cipher.final('base64');
|
|
207
|
+
appConfig.EncryptCode2 = encrypted;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
194
211
|
// 组装AppData
|
|
195
212
|
appConfig.PublicKeys = publicKeys; // 使用签名数组,支持后续追加签名
|
|
196
213
|
appConfig.EncryptCodes = [encryptBase64]; // 同样使用数组,支持后续追加
|
|
@@ -199,10 +216,32 @@ async function prepareMainAppData(options)
|
|
|
199
216
|
BaseUrl: bunderBaseUrl,
|
|
200
217
|
Resources: preloadBurdenResources,
|
|
201
218
|
};
|
|
219
|
+
if (appConfig.FingerPrint) {
|
|
220
|
+
// 删除FingerPrint的存储,节省信息字节数
|
|
221
|
+
delete appConfig.FingerPrint;
|
|
222
|
+
}
|
|
202
223
|
|
|
203
224
|
return JSON.stringify(appConfig);
|
|
204
225
|
}
|
|
205
226
|
|
|
227
|
+
async function checkCssFileSize(options)
|
|
228
|
+
{
|
|
229
|
+
if(fs.existsSync(options.distCssDir) == false) {
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const cssFileNames = fs.readdirSync(options.distCssDir);
|
|
234
|
+
for(const fileName of cssFileNames) {
|
|
235
|
+
const filePath = path.resolve(options.distCssDir, fileName)
|
|
236
|
+
const fileStats = await fs.statSync(filePath);
|
|
237
|
+
if (fileStats.size > 0) {
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
fs.writeFileSync(filePath, ' ', 'utf8'); // 防止空文件。
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
206
245
|
async function checkAppConfig(options)
|
|
207
246
|
{
|
|
208
247
|
const appConfigFilePath = path.resolve(options.appConfigDir, 'app.config.mjs');
|
|
@@ -333,7 +372,8 @@ function redirectBurdenResource(options)
|
|
|
333
372
|
let sourceContent = fs.readFileSync(filePath, 'utf8');
|
|
334
373
|
|
|
335
374
|
for(const burdenFilePath of burdenFilePathList) {
|
|
336
|
-
|
|
375
|
+
let relativeBurdenFilePath = path.relative(options.distJsDir, burdenFilePath);
|
|
376
|
+
relativeBurdenFilePath = relativeBurdenFilePath.replaceAll('\\', '/'); // 更正windows分隔符
|
|
337
377
|
if(!sourceContent.includes(relativeBurdenFilePath)) {
|
|
338
378
|
continue;
|
|
339
379
|
}
|
|
@@ -395,14 +435,13 @@ function makeMainJsvMjs(options, framework)
|
|
|
395
435
|
|
|
396
436
|
// 更新entry hash
|
|
397
437
|
const jsEntryFilePath = getEntryFilePath(options);
|
|
398
|
-
const
|
|
399
|
-
const newEntryFilePath = path.resolve(path.dirname(jsEntryFilePath), newEntryFileName);
|
|
438
|
+
const newEntryFilePath = path.resolve(options.distJsDir, options.appEntryFileName);
|
|
400
439
|
Logger.Info(' -> ' + path.relative(options.projectDir, newEntryFilePath));
|
|
401
440
|
fs.renameSync(jsEntryFilePath, newEntryFilePath);
|
|
402
441
|
|
|
403
442
|
// 更新index.html hash
|
|
404
443
|
var indexContent = fs.readFileSync(options.distJsIndexFile, 'utf8');
|
|
405
|
-
indexContent = indexContent.replace(path.basename(jsEntryFilePath),
|
|
444
|
+
indexContent = indexContent.replace(path.basename(jsEntryFilePath), options.appEntryFileName);
|
|
406
445
|
Logger.Info(' -> ' + path.relative(options.projectDir, options.distJsIndexFile));
|
|
407
446
|
fs.writeFileSync(options.distJsIndexFile, indexContent, 'utf8');
|
|
408
447
|
|
|
@@ -478,6 +517,38 @@ function makeDebugMap(options, framework)
|
|
|
478
517
|
fs.copyFileSync(jsmapServePath, to);
|
|
479
518
|
}
|
|
480
519
|
|
|
520
|
+
async function makeJsvConfig(options)
|
|
521
|
+
{
|
|
522
|
+
const jsviewVersionURL = url.pathToFileURL(options.jsviewDomRevisionFile);
|
|
523
|
+
const { default: jsviewTargetVersion } = await import(jsviewVersionURL);
|
|
524
|
+
const appEntryFilePath = path.resolve(options.distJsDir, options.appEntryFileName);
|
|
525
|
+
let appEntryFileName = `./${path.relative(options.distDir, appEntryFilePath)}`;
|
|
526
|
+
// appEntryFileName = appEntryFileName.replace(/\.js$/, '.mjs'); // deprecated
|
|
527
|
+
appEntryFileName = appEntryFileName.replaceAll('\\', '/'); // windows平台适配
|
|
528
|
+
|
|
529
|
+
const appConfigFilePath = path.resolve(options.appConfigDir, 'app.config.mjs');
|
|
530
|
+
if (!fs.existsSync(appConfigFilePath)) {
|
|
531
|
+
Logger.ErrorAndExit('Failed to open app config file from ' + appConfigFilePath);
|
|
532
|
+
}
|
|
533
|
+
const appConfigFileUrl = url.pathToFileURL(appConfigFilePath);
|
|
534
|
+
const { default: appConfig } = await import(appConfigFileUrl);
|
|
535
|
+
|
|
536
|
+
const jsvConfig = {
|
|
537
|
+
"COREVERSIONRANGE": jsviewTargetVersion.CoreRevisionAndBranch,
|
|
538
|
+
"ENGINE": jsviewTargetVersion.JseUrl,
|
|
539
|
+
"URL": appEntryFileName,
|
|
540
|
+
"MINIAPPNAME": appConfig.AppName,
|
|
541
|
+
};
|
|
542
|
+
|
|
543
|
+
// 启动图
|
|
544
|
+
if (appConfig.StartImageUrl && appConfig.StartImageUrl.length != 0) {
|
|
545
|
+
jsvConfig.STARTIMG = appConfig.StartImageUrl;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
const content = JSON.stringify(jsvConfig, null, 2);
|
|
549
|
+
fs.writeFileSync(options.distJsvConfigFile, content, 'utf8');
|
|
550
|
+
}
|
|
551
|
+
|
|
481
552
|
function makeJsvList(options)
|
|
482
553
|
{
|
|
483
554
|
let jsvList = makeFileListRecusive(options.distDir);
|
|
@@ -551,6 +622,10 @@ async function main(argv)
|
|
|
551
622
|
await checkDomDebugDisabled(options);
|
|
552
623
|
|
|
553
624
|
Logger.Info();
|
|
625
|
+
const jsviewPkgJson = loadPackageObject(options.jsviewDir);
|
|
626
|
+
Logger.Info(`JsView version: ${jsviewPkgJson.version}`);
|
|
627
|
+
Logger.Info();
|
|
628
|
+
|
|
554
629
|
Logger.Info('Redirecting JsView burden resource...');
|
|
555
630
|
redirectBurdenResource(options)
|
|
556
631
|
Logger.Info('Redirected JsView burden resource...');
|
|
@@ -562,6 +637,10 @@ async function main(argv)
|
|
|
562
637
|
// EntryMd5 要放在sourcemap更新之后
|
|
563
638
|
updateOptions(options);
|
|
564
639
|
|
|
640
|
+
Logger.Info('Checking JsView css file size...');
|
|
641
|
+
await checkCssFileSize(options);
|
|
642
|
+
Logger.Info('Checked JsView css file size...');
|
|
643
|
+
|
|
565
644
|
Logger.Info('Checking JsView app config...');
|
|
566
645
|
await checkAppConfig(options);
|
|
567
646
|
Logger.Info('Checked JsView app config...');
|
|
@@ -578,13 +657,16 @@ async function main(argv)
|
|
|
578
657
|
makeDebugMap(options, argv.framework);
|
|
579
658
|
Logger.Info('Made JsView Debug map.');
|
|
580
659
|
|
|
660
|
+
Logger.Info('Cleaning JsView Burden Resource...');
|
|
661
|
+
cleanupBurdenResource(options);
|
|
662
|
+
Logger.Info('Cleaned JsView Burden Resource...');
|
|
663
|
+
|
|
581
664
|
Logger.Info('Making JsView info...');
|
|
665
|
+
await makeJsvConfig(options);
|
|
582
666
|
makeJsvList(options);
|
|
583
667
|
await makeJsvInfo(options);
|
|
584
668
|
Logger.Info('Made JsView info...');
|
|
585
669
|
|
|
586
|
-
cleanupBurdenResource(options);
|
|
587
|
-
|
|
588
670
|
Logger.Info('Done...');
|
|
589
671
|
}
|
|
590
672
|
|
|
@@ -230,10 +230,10 @@ async function printRevision(options)
|
|
|
230
230
|
let versionFilePath = path.resolve(pathname, 'version.mjs');
|
|
231
231
|
if (fs.existsSync(versionFilePath)) {
|
|
232
232
|
const versionFileURL = url.pathToFileURL(versionFilePath);
|
|
233
|
-
const
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
233
|
+
const versionModule = await import(versionFileURL);
|
|
234
|
+
// 兼容 default 导出(JsvAudio/JsvPlayer)与命名导出 PluginInfo(JsvLatex)
|
|
235
|
+
const targetVersion = versionModule.PluginInfo ?? versionModule.default;
|
|
236
|
+
Logger.Info(`* [${path.basename(pathname)}] : ${targetVersion.packageName} : ${targetVersion.version}`);
|
|
237
237
|
pluginCount++;
|
|
238
238
|
}
|
|
239
239
|
}
|
|
@@ -250,9 +250,15 @@ function doPostInstall(framework, pkgNeedPatch, skipCheckVersion, skipCheckNpmcm
|
|
|
250
250
|
const options = getOptions(framework);
|
|
251
251
|
options.projectDir = process.cwd();
|
|
252
252
|
|
|
253
|
+
Logger.Info();
|
|
254
|
+
const jsviewPkgJson = loadPackageObject(options.jsviewDir);
|
|
255
|
+
Logger.Info(`JsView version: ${jsviewPkgJson.version}`);
|
|
256
|
+
Logger.Info();
|
|
257
|
+
|
|
253
258
|
const linkablePkgNames = [
|
|
254
259
|
'@shijiu/jsview',
|
|
255
260
|
'@shijiu/jsview-vue',
|
|
261
|
+
'@shijiu/jsview-vue-plus',
|
|
256
262
|
'@shijiu/jsview-vue-samples',
|
|
257
263
|
'@shijiu/jsview-vue-extra-samples',
|
|
258
264
|
'@shijiu/jsview-react',
|
|
@@ -79,6 +79,7 @@ async function getExtraOptions(argv)
|
|
|
79
79
|
options.genKeypair = argv.genKeypair;
|
|
80
80
|
options.buildMinifyExclude = argv.buildMinifyExclude;
|
|
81
81
|
options.buildZip = argv.buildZip;
|
|
82
|
+
options.noPassword = argv.noPassword;
|
|
82
83
|
options.buildBurdenLocal = argv.buildBurdenLocal;
|
|
83
84
|
options.buildBurdenBaseurl = argv.buildBurdenBaseurl;
|
|
84
85
|
options.vueDevtools = argv.vueDevtools;
|
|
@@ -129,11 +130,7 @@ function doCommand(options, argv) {
|
|
|
129
130
|
} else if(options.buildZip) {
|
|
130
131
|
const defaultPassword = 'jsview.shijiu.com';
|
|
131
132
|
const password = (typeof(options.buildZip) === 'string' ? options.buildZip : defaultPassword);
|
|
132
|
-
|
|
133
|
-
Logger.Warn(`Zip password is not set, use default value: ${defaultPassword}`);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
command = `node node_modules/@shijiu/jsview/tools/jsview-build-zip.mjs --password=${password}`;
|
|
133
|
+
command = `node node_modules/@shijiu/jsview/tools/jsview-build-zip.mjs --password=${password} ${options.noPassword ? '--no-password' : ''}`;
|
|
137
134
|
} else if(options.buildBurdenLocal) {
|
|
138
135
|
command = 'JSVIEW_BURDEN_LOCAL=true npm run build';
|
|
139
136
|
} else if(options.buildBurdenBaseurl) {
|
|
@@ -217,7 +214,7 @@ const optionalUsages = {
|
|
|
217
214
|
'-c | --config-app': 'Config app, like: -c or --config-app=[AppName:AppTitle].',
|
|
218
215
|
'-g | --gen-keypair': 'Generate sign keypair.',
|
|
219
216
|
'-m | --build-minify-exclude': 'Build target with minify-exclude filter, like: -m or --build-minify-exclude=[filter], additional options: -s or --script=build:dev.',
|
|
220
|
-
'-z | --build-zip': 'Build target to offline zip package, like: -z
|
|
217
|
+
'-z | --build-zip': 'Build target to offline zip package, like: -z, --build-zip=[password] or --build-zip --no-password.',
|
|
221
218
|
'-l | --build-burden-local': 'Build target with local burden files.',
|
|
222
219
|
'-b | --build-burden-baseurl': 'Build target with custom burden base url.',
|
|
223
220
|
'-d | --vue-devtools': 'Start vue dev server and vue-devtools standalone, like: -d or --vue-devtools=[port].',
|