@playcraft/build 0.0.43 → 0.0.45
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/engines/playable-scripts-adapter.d.ts +1 -1
- package/dist/engines/playable-scripts-adapter.js +55 -21
- package/dist/platforms/bigo.js +3 -5
- package/dist/platforms/inmobi.js +3 -5
- package/dist/platforms/liftoff.js +3 -5
- package/dist/platforms/mintegral.js +4 -6
- package/dist/platforms/snapchat.js +1 -1
- package/dist/platforms/tiktok.js +3 -5
- package/dist/vite/platform-configs.js +7 -7
- package/dist/vite/plugin-playcanvas.js +151 -46
- package/package.json +1 -1
- package/dist/analyzers/__tests__/optimization-analyzer.test.d.ts +0 -1
- package/dist/analyzers/__tests__/optimization-analyzer.test.js +0 -169
- package/dist/templates/__loading__.js +0 -100
- package/dist/templates/__modules__.js +0 -47
- package/dist/templates/__settings__.template.js +0 -20
- package/dist/templates/__start__.js +0 -332
- package/dist/templates/index.html +0 -18
- package/dist/templates/logo.png +0 -0
- package/dist/templates/manifest.json +0 -1
- package/dist/templates/patches/cannon.min.js +0 -28
- package/dist/templates/patches/lz4.js +0 -10
- package/dist/templates/patches/one-page-http-get.js +0 -20
- package/dist/templates/patches/one-page-inline-game-scripts.js +0 -52
- package/dist/templates/patches/one-page-mraid-resize-canvas.js +0 -46
- package/dist/templates/patches/p2.min.js +0 -27
- package/dist/templates/patches/playcraft-no-xhr.js +0 -76
- package/dist/templates/playcanvas-stable.min.js +0 -16363
- package/dist/templates/styles.css +0 -43
|
@@ -148,7 +148,7 @@ export declare class PlayableScriptsAdapter {
|
|
|
148
148
|
private copyToOutputDir;
|
|
149
149
|
/**
|
|
150
150
|
* 是否对 playable-scripts 使用 --zip。
|
|
151
|
-
*
|
|
151
|
+
* 双格式渠道默认 HTML;仅在请求或配置显式选择 ZIP 时传递 --zip。
|
|
152
152
|
*/
|
|
153
153
|
private isZipOutput;
|
|
154
154
|
/**
|
|
@@ -258,7 +258,7 @@ export class PlayableScriptsAdapter {
|
|
|
258
258
|
// 输出目录 - 统一使用 dist,与 PlayCraft 标准一致
|
|
259
259
|
const outputDir = config.outputDir ?? 'dist';
|
|
260
260
|
args.push('--out-dir', outputDir);
|
|
261
|
-
// ZIP
|
|
261
|
+
// ZIP 输出:显式 config.zip 或构建请求 format=zip(如 Google / Facebook / TikTok 等选 ZIP)
|
|
262
262
|
const isZipFormat = this.isZipOutput();
|
|
263
263
|
if (isZipFormat) {
|
|
264
264
|
args.push('--zip');
|
|
@@ -631,6 +631,12 @@ export class PlayableScriptsAdapter {
|
|
|
631
631
|
'ignore-scripts=false',
|
|
632
632
|
'strict-peer-dependencies=false',
|
|
633
633
|
'dangerously-allow-all-builds=true',
|
|
634
|
+
// pnpm >=10.10 默认启用 minimum-release-age=24h(supply-chain 防护,
|
|
635
|
+
// 阻止安装发布不满 24 小时的包),构建端的 worker 镜像若意外跑到 pnpm 11
|
|
636
|
+
// (corepack 行为差异等),此策略会让恰好今天发版的依赖(如 vue@3.5.x)报
|
|
637
|
+
// ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION。这里在临时 .npmrc 里强制关掉,
|
|
638
|
+
// install 完即 unlink,仅作用于本次 PlayCraft 构建,不影响外部环境。
|
|
639
|
+
'minimum-release-age=0',
|
|
634
640
|
].join('\n');
|
|
635
641
|
try {
|
|
636
642
|
await fs.writeFile(npmrcPath, npmrcContent, 'utf-8');
|
|
@@ -646,19 +652,34 @@ export class PlayableScriptsAdapter {
|
|
|
646
652
|
try {
|
|
647
653
|
// 执行 pnpm install 安装 package.json 中定义的所有依赖
|
|
648
654
|
// 包括 @playcraft/devkit 和 babel-loader 等构建工具
|
|
649
|
-
// 注意:不要设置 NODE_ENV=production,否则会跳过 devDependencies
|
|
650
655
|
await this.runCommandWithTimeout('pnpm', installArgs, {
|
|
651
656
|
cwd: this.projectDir,
|
|
652
|
-
timeout:
|
|
653
|
-
env:
|
|
657
|
+
timeout: 10 * 60 * 1000,
|
|
658
|
+
env: {
|
|
659
|
+
...process.env,
|
|
660
|
+
NODE_ENV: 'development',
|
|
661
|
+
},
|
|
654
662
|
});
|
|
655
663
|
}
|
|
656
664
|
catch (error) {
|
|
665
|
+
const errMsg = error.message ?? String(error);
|
|
666
|
+
if (errMsg.startsWith('命令被中止')) {
|
|
667
|
+
// 清理 .npmrc 后再抛,避免临时配置残留
|
|
668
|
+
try {
|
|
669
|
+
await fs.unlink(npmrcPath);
|
|
670
|
+
}
|
|
671
|
+
catch { /* ignore */ }
|
|
672
|
+
throw new Error(`[PlayableScriptsAdapter] pnpm install 被中止(5 分钟 timeout)。\n` +
|
|
673
|
+
`install 未跑完 link-bin 阶段,node_modules/.bin 软链缺失,无法继续构建。\n` +
|
|
674
|
+
`常见原因:依赖 1000+ 包冷启动、mozjpeg/sharp 等 native postinstall 编译过慢。\n` +
|
|
675
|
+
`建议:worker 镜像预热 pnpm store / 修复 mozjpeg 预编译产物 / 调高 install timeout。\n` +
|
|
676
|
+
`原始错误: ${errMsg}`);
|
|
677
|
+
}
|
|
657
678
|
// 不立即放弃:新版 pnpm 即使 install 实际成功,也可能因 ERR_PNPM_IGNORED_BUILDS
|
|
658
679
|
// 等告警退出非零;devkit 本身不需要 native build,只要 node_modules 里能定位到
|
|
659
680
|
// CLI 入口,构建即可继续。先记下错误,后面 verify 再决定是否真正失败。
|
|
660
681
|
installError = error;
|
|
661
|
-
console.log(`[PlayableScriptsAdapter] ⚠️ pnpm install 退出非零,将再次校验 node_modules 实际状态: ${
|
|
682
|
+
console.log(`[PlayableScriptsAdapter] ⚠️ pnpm install 退出非零,将再次校验 node_modules 实际状态: ${errMsg}`);
|
|
662
683
|
}
|
|
663
684
|
// 清理临时 .npmrc
|
|
664
685
|
try {
|
|
@@ -681,12 +702,28 @@ export class PlayableScriptsAdapter {
|
|
|
681
702
|
path.join(devkitDir, 'dist', 'cli.js'),
|
|
682
703
|
path.join(devkitDir, 'bin', 'playable-scripts.js'),
|
|
683
704
|
];
|
|
705
|
+
const dotBinPath = path.join(this.projectDir, 'node_modules', '.bin', 'playable-scripts');
|
|
706
|
+
let dotBinReady = false;
|
|
707
|
+
try {
|
|
708
|
+
await fs.access(dotBinPath);
|
|
709
|
+
dotBinReady = true;
|
|
710
|
+
}
|
|
711
|
+
catch {
|
|
712
|
+
// .bin 软链不存在,下面 fallback 路径也会再检一次
|
|
713
|
+
}
|
|
684
714
|
for (const binPath of possiblePaths) {
|
|
685
715
|
try {
|
|
686
716
|
await fs.access(binPath);
|
|
717
|
+
if (!dotBinReady) {
|
|
718
|
+
// CLI 物理文件已到位但 .bin 软链缺失 —— install 没跑完 link-bin 阶段
|
|
719
|
+
console.error(`[PlayableScriptsAdapter] ❌ 找到 CLI 物理文件 (${binPath}) 但 .bin/playable-scripts 软链缺失,` +
|
|
720
|
+
`判定 install 未跑完 link-bin 阶段,拒绝继续构建`);
|
|
721
|
+
// 跳出 for 循环,让外层走 fallback / return null
|
|
722
|
+
break;
|
|
723
|
+
}
|
|
687
724
|
console.log(`[PlayableScriptsAdapter] 安装后找到 playable-scripts: ${binPath}`);
|
|
688
725
|
if (installError) {
|
|
689
|
-
console.log('[PlayableScriptsAdapter] ✅ pnpm install 虽然退出非零,但 devkit
|
|
726
|
+
console.log('[PlayableScriptsAdapter] ✅ pnpm install 虽然退出非零,但 devkit 与 .bin 软链均已就绪,忽略告警继续构建');
|
|
690
727
|
}
|
|
691
728
|
return binPath;
|
|
692
729
|
}
|
|
@@ -694,7 +731,9 @@ export class PlayableScriptsAdapter {
|
|
|
694
731
|
// 继续尝试下一个
|
|
695
732
|
}
|
|
696
733
|
}
|
|
697
|
-
|
|
734
|
+
if (dotBinReady) {
|
|
735
|
+
console.error(`[PlayableScriptsAdapter] ❌ 找到 devkit 但无法定位 CLI: ${devkitDir}`);
|
|
736
|
+
}
|
|
698
737
|
}
|
|
699
738
|
catch {
|
|
700
739
|
// require.resolve 失败,回退到 findLocalPlayableScripts
|
|
@@ -835,7 +874,14 @@ export class PlayableScriptsAdapter {
|
|
|
835
874
|
await this.runCommandWithTimeout('pnpm', installArgs, {
|
|
836
875
|
cwd: this.projectDir,
|
|
837
876
|
timeout: 3 * 60 * 1000,
|
|
838
|
-
|
|
877
|
+
// NODE_ENV 覆盖原因同 ensureLocalDevkit 中 pnpm install:
|
|
878
|
+
// worker 容器自身 ENV NODE_ENV=production,若直接透传,pnpm 会按 --prod 处理,
|
|
879
|
+
// 即使是 `pnpm add -D` 也存在跨版本行为差异的风险。这里强制 development 保证
|
|
880
|
+
// install 主路径与 add 兜底路径行为一致。
|
|
881
|
+
env: {
|
|
882
|
+
...process.env,
|
|
883
|
+
NODE_ENV: 'development',
|
|
884
|
+
},
|
|
839
885
|
});
|
|
840
886
|
}
|
|
841
887
|
catch (error) {
|
|
@@ -1155,25 +1201,13 @@ export class PlayableScriptsAdapter {
|
|
|
1155
1201
|
}
|
|
1156
1202
|
/**
|
|
1157
1203
|
* 是否对 playable-scripts 使用 --zip。
|
|
1158
|
-
*
|
|
1204
|
+
* 双格式渠道默认 HTML;仅在请求或配置显式选择 ZIP 时传递 --zip。
|
|
1159
1205
|
*/
|
|
1160
1206
|
isZipOutput() {
|
|
1161
1207
|
const config = this.config ?? {};
|
|
1162
|
-
const channels = config.channels ?? ['google'];
|
|
1163
1208
|
if (config.zip === true) {
|
|
1164
1209
|
return true;
|
|
1165
1210
|
}
|
|
1166
|
-
const zipOnlyPlatforms = new Set([
|
|
1167
|
-
'tiktok',
|
|
1168
|
-
'snapchat',
|
|
1169
|
-
'liftoff',
|
|
1170
|
-
'bigo',
|
|
1171
|
-
'inmobi',
|
|
1172
|
-
'mintegral',
|
|
1173
|
-
]);
|
|
1174
|
-
if (channels.some((ch) => zipOnlyPlatforms.has(ch))) {
|
|
1175
|
-
return true;
|
|
1176
|
-
}
|
|
1177
1211
|
const fmt = this.options.format;
|
|
1178
1212
|
return fmt === 'zip';
|
|
1179
1213
|
}
|
package/dist/platforms/bigo.js
CHANGED
|
@@ -8,7 +8,7 @@ export class BigoAdapter extends PlatformAdapter {
|
|
|
8
8
|
return 5 * 1024 * 1024;
|
|
9
9
|
}
|
|
10
10
|
getDefaultFormat() {
|
|
11
|
-
return '
|
|
11
|
+
return 'html';
|
|
12
12
|
}
|
|
13
13
|
async modifyHTML(html, assets) {
|
|
14
14
|
// BIGO Ads 需要 BIGO JS-SDK
|
|
@@ -36,7 +36,7 @@ export class BigoAdapter extends PlatformAdapter {
|
|
|
36
36
|
`;
|
|
37
37
|
const sdkScript = `<script src="https://static-web.likeevideo.com/oss/material-ad/playable-ad-demo/bgy-mraid-sdk.js"></script>`;
|
|
38
38
|
const fallbackScript = await this.minifyPlatformScript(bigoScriptCode, 'bigo-sdk');
|
|
39
|
-
const comment = `<!-- BIGO: ZIP
|
|
39
|
+
const comment = `<!-- BIGO: HTML/ZIP format, config.json includes orientation when present, use BGY_MRAID.open() -->`;
|
|
40
40
|
// 在 </head> 之前插入
|
|
41
41
|
html = html.replace('</head>', `${sdkScript}${fallbackScript}${comment}</head>`);
|
|
42
42
|
// 注入统一的 CTA 适配器
|
|
@@ -71,8 +71,6 @@ export class BigoAdapter extends PlatformAdapter {
|
|
|
71
71
|
};
|
|
72
72
|
}
|
|
73
73
|
validateOptions() {
|
|
74
|
-
|
|
75
|
-
console.warn('警告: BIGO Ads 要求 ZIP 格式');
|
|
76
|
-
}
|
|
74
|
+
// BIGO Ads supports both HTML and ZIP output in PlayCraft.
|
|
77
75
|
}
|
|
78
76
|
}
|
package/dist/platforms/inmobi.js
CHANGED
|
@@ -8,7 +8,7 @@ export class InMobiAdapter extends PlatformAdapter {
|
|
|
8
8
|
return 5 * 1024 * 1024;
|
|
9
9
|
}
|
|
10
10
|
getDefaultFormat() {
|
|
11
|
-
return '
|
|
11
|
+
return 'html';
|
|
12
12
|
}
|
|
13
13
|
async modifyHTML(html, assets) {
|
|
14
14
|
// InMobi 需要 MRAID 支持
|
|
@@ -36,7 +36,7 @@ export class InMobiAdapter extends PlatformAdapter {
|
|
|
36
36
|
};
|
|
37
37
|
`;
|
|
38
38
|
const inmobiScript = await this.minifyPlatformScript(inmobiScriptCode, 'inmobi-mraid');
|
|
39
|
-
const comment = `<!-- InMobi: ZIP
|
|
39
|
+
const comment = `<!-- InMobi: HTML/ZIP format, use mraid.open() -->`;
|
|
40
40
|
// 在 </head> 之前插入平台特定的 API
|
|
41
41
|
html = html.replace('</head>', `${inmobiScript}${comment}</head>`);
|
|
42
42
|
// 注入统一的 CTA 适配器
|
|
@@ -57,8 +57,6 @@ export class InMobiAdapter extends PlatformAdapter {
|
|
|
57
57
|
`;
|
|
58
58
|
}
|
|
59
59
|
validateOptions() {
|
|
60
|
-
|
|
61
|
-
console.warn('警告: InMobi 要求 ZIP 格式');
|
|
62
|
-
}
|
|
60
|
+
// InMobi supports both HTML and ZIP output in PlayCraft.
|
|
63
61
|
}
|
|
64
62
|
}
|
|
@@ -8,7 +8,7 @@ export class LiftoffAdapter extends PlatformAdapter {
|
|
|
8
8
|
return 5 * 1024 * 1024;
|
|
9
9
|
}
|
|
10
10
|
getDefaultFormat() {
|
|
11
|
-
return '
|
|
11
|
+
return 'html';
|
|
12
12
|
}
|
|
13
13
|
async modifyHTML(html, assets) {
|
|
14
14
|
// Liftoff 支持 MRAID 或 window.open
|
|
@@ -31,7 +31,7 @@ export class LiftoffAdapter extends PlatformAdapter {
|
|
|
31
31
|
};
|
|
32
32
|
`;
|
|
33
33
|
const liftoffScript = await this.minifyPlatformScript(liftoffScriptCode, 'liftoff-mraid');
|
|
34
|
-
const comment = `<!-- Liftoff: ZIP
|
|
34
|
+
const comment = `<!-- Liftoff: HTML/ZIP format, ASCII filenames recommended, use mraid.open() or window.open() -->`;
|
|
35
35
|
// 在 </head> 之前插入
|
|
36
36
|
html = html.replace('</head>', `${liftoffScript}${comment}</head>`);
|
|
37
37
|
// 注入统一的 CTA 适配器
|
|
@@ -47,8 +47,6 @@ export class LiftoffAdapter extends PlatformAdapter {
|
|
|
47
47
|
`;
|
|
48
48
|
}
|
|
49
49
|
validateOptions() {
|
|
50
|
-
|
|
51
|
-
console.warn('警告: Liftoff 要求 ZIP 格式');
|
|
52
|
-
}
|
|
50
|
+
// Liftoff supports both HTML and ZIP output in PlayCraft.
|
|
53
51
|
}
|
|
54
52
|
}
|
|
@@ -4,11 +4,11 @@ export class MintegralAdapter extends PlatformAdapter {
|
|
|
4
4
|
return 'Mintegral';
|
|
5
5
|
}
|
|
6
6
|
getSizeLimit() {
|
|
7
|
-
// Mintegral: 5MB
|
|
7
|
+
// Mintegral: 5MB
|
|
8
8
|
return 5 * 1024 * 1024;
|
|
9
9
|
}
|
|
10
10
|
getDefaultFormat() {
|
|
11
|
-
return '
|
|
11
|
+
return 'html';
|
|
12
12
|
}
|
|
13
13
|
async modifyHTML(html, assets) {
|
|
14
14
|
// Mintegral 要求 charset 为 utf-8,确保存在
|
|
@@ -33,7 +33,7 @@ export class MintegralAdapter extends PlatformAdapter {
|
|
|
33
33
|
window.HttpAPI = window.HttpAPI || { sendPoint: function() {} };
|
|
34
34
|
`;
|
|
35
35
|
const mintegralScript = await this.minifyPlatformScript(mintegralScriptCode, 'mintegral-sdk');
|
|
36
|
-
const comment = `<!-- Mintegral: ZIP
|
|
36
|
+
const comment = `<!-- Mintegral: HTML/ZIP format, 5MB limit, use window.install(), supports both orientations -->`;
|
|
37
37
|
// 在 </head> 之前插入 polyfill 和注释,如果没有 </head> 则在文件开头插入
|
|
38
38
|
if (html.includes('</head>')) {
|
|
39
39
|
html = html.replace('</head>', `${mintegralScript}${comment}\n</head>`);
|
|
@@ -59,8 +59,6 @@ export class MintegralAdapter extends PlatformAdapter {
|
|
|
59
59
|
`;
|
|
60
60
|
}
|
|
61
61
|
validateOptions() {
|
|
62
|
-
|
|
63
|
-
console.warn('警告: Mintegral 要求 ZIP 格式,将自动使用 ZIP');
|
|
64
|
-
}
|
|
62
|
+
// Mintegral supports both HTML and ZIP output in PlayCraft.
|
|
65
63
|
}
|
|
66
64
|
}
|
package/dist/platforms/tiktok.js
CHANGED
|
@@ -8,7 +8,7 @@ export class TikTokAdapter extends PlatformAdapter {
|
|
|
8
8
|
return 5 * 1024 * 1024;
|
|
9
9
|
}
|
|
10
10
|
getDefaultFormat() {
|
|
11
|
-
return '
|
|
11
|
+
return 'html';
|
|
12
12
|
}
|
|
13
13
|
async modifyHTML(html, assets) {
|
|
14
14
|
// TikTok/Pangle 需要 Pangle JS-SDK
|
|
@@ -35,7 +35,7 @@ export class TikTokAdapter extends PlatformAdapter {
|
|
|
35
35
|
};
|
|
36
36
|
`;
|
|
37
37
|
const pangleScript = await this.minifyPlatformScript(pangleScriptCode, 'pangle-sdk');
|
|
38
|
-
const comment = `<!-- TikTok/Pangle: ZIP
|
|
38
|
+
const comment = `<!-- TikTok/Pangle: HTML/ZIP format, config.json includes playable_orientation when present, no mraid.js -->`;
|
|
39
39
|
// 在 </head> 之前插入
|
|
40
40
|
html = html.replace('</head>', `${pangleScript}${comment}</head>`);
|
|
41
41
|
// 注入统一的 CTA 适配器
|
|
@@ -63,8 +63,6 @@ export class TikTokAdapter extends PlatformAdapter {
|
|
|
63
63
|
};
|
|
64
64
|
}
|
|
65
65
|
validateOptions() {
|
|
66
|
-
|
|
67
|
-
console.warn('警告: TikTok/Pangle 要求 ZIP 格式');
|
|
68
|
-
}
|
|
66
|
+
// TikTok/Pangle supports both HTML and ZIP output in PlayCraft.
|
|
69
67
|
}
|
|
70
68
|
}
|
|
@@ -67,7 +67,7 @@ export const PLATFORM_CONFIGS = {
|
|
|
67
67
|
},
|
|
68
68
|
snapchat: {
|
|
69
69
|
sizeLimit: 5 * 1024 * 1024, // 5MB
|
|
70
|
-
outputFormat: '
|
|
70
|
+
outputFormat: 'html',
|
|
71
71
|
minifyCSS: true,
|
|
72
72
|
minifyJS: true,
|
|
73
73
|
compressImages: false, // 禁用图片压缩,原图输出效果更好
|
|
@@ -185,7 +185,7 @@ export const PLATFORM_CONFIGS = {
|
|
|
185
185
|
},
|
|
186
186
|
tiktok: {
|
|
187
187
|
sizeLimit: 5 * 1024 * 1024, // 5MB
|
|
188
|
-
outputFormat: '
|
|
188
|
+
outputFormat: 'html',
|
|
189
189
|
minifyCSS: true,
|
|
190
190
|
minifyJS: true,
|
|
191
191
|
compressImages: false, // 禁用图片压缩,原图输出效果更好
|
|
@@ -243,7 +243,7 @@ export const PLATFORM_CONFIGS = {
|
|
|
243
243
|
},
|
|
244
244
|
liftoff: {
|
|
245
245
|
sizeLimit: 5 * 1024 * 1024, // 5MB
|
|
246
|
-
outputFormat: '
|
|
246
|
+
outputFormat: 'html',
|
|
247
247
|
minifyCSS: true,
|
|
248
248
|
minifyJS: true,
|
|
249
249
|
compressImages: false, // 禁用图片压缩,原图输出效果更好
|
|
@@ -301,7 +301,7 @@ export const PLATFORM_CONFIGS = {
|
|
|
301
301
|
},
|
|
302
302
|
bigo: {
|
|
303
303
|
sizeLimit: 5 * 1024 * 1024, // 5MB
|
|
304
|
-
outputFormat: '
|
|
304
|
+
outputFormat: 'html',
|
|
305
305
|
minifyCSS: true,
|
|
306
306
|
minifyJS: true,
|
|
307
307
|
compressImages: false, // 禁用图片压缩,原图输出效果更好
|
|
@@ -329,7 +329,7 @@ export const PLATFORM_CONFIGS = {
|
|
|
329
329
|
},
|
|
330
330
|
inmobi: {
|
|
331
331
|
sizeLimit: 5 * 1024 * 1024, // 5MB
|
|
332
|
-
outputFormat: '
|
|
332
|
+
outputFormat: 'html',
|
|
333
333
|
minifyCSS: true,
|
|
334
334
|
minifyJS: true,
|
|
335
335
|
compressImages: false, // 禁用图片压缩,原图输出效果更好
|
|
@@ -416,8 +416,8 @@ export const PLATFORM_CONFIGS = {
|
|
|
416
416
|
},
|
|
417
417
|
},
|
|
418
418
|
mintegral: {
|
|
419
|
-
sizeLimit: 5 * 1024 * 1024, // 5MB
|
|
420
|
-
outputFormat: '
|
|
419
|
+
sizeLimit: 5 * 1024 * 1024, // 5MB
|
|
420
|
+
outputFormat: 'html',
|
|
421
421
|
minifyCSS: true,
|
|
422
422
|
minifyJS: true,
|
|
423
423
|
compressImages: false, // 禁用图片压缩,原图输出效果更好
|