@playcraft/build 0.0.3 → 0.0.8
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/analyzers/scene-asset-collector.js +210 -1
- package/dist/base-builder.d.ts +17 -0
- package/dist/base-builder.js +211 -16
- package/dist/generators/config-generator.js +29 -3
- package/dist/loaders/playcanvas-loader.d.ts +7 -0
- package/dist/loaders/playcanvas-loader.js +53 -3
- package/dist/platforms/adikteev.d.ts +10 -0
- package/dist/platforms/adikteev.js +72 -0
- package/dist/platforms/base.d.ts +12 -0
- package/dist/platforms/base.js +208 -0
- package/dist/platforms/facebook.js +5 -2
- package/dist/platforms/index.d.ts +4 -0
- package/dist/platforms/index.js +16 -0
- package/dist/platforms/inmobi.d.ts +10 -0
- package/dist/platforms/inmobi.js +68 -0
- package/dist/platforms/ironsource.js +5 -2
- package/dist/platforms/moloco.js +5 -2
- package/dist/platforms/playcraft.d.ts +33 -0
- package/dist/platforms/playcraft.js +44 -0
- package/dist/platforms/remerge.d.ts +10 -0
- package/dist/platforms/remerge.js +56 -0
- package/dist/templates/__loading__.js +100 -0
- package/dist/templates/__modules__.js +47 -0
- package/dist/templates/__settings__.template.js +20 -0
- package/dist/templates/__start__.js +332 -0
- package/dist/templates/index.html +18 -0
- package/dist/templates/logo.png +0 -0
- package/dist/templates/manifest.json +1 -0
- package/dist/templates/patches/cannon.min.js +28 -0
- package/dist/templates/patches/lz4.js +10 -0
- package/dist/templates/patches/one-page-http-get.js +20 -0
- package/dist/templates/patches/one-page-inline-game-scripts.js +52 -0
- package/dist/templates/patches/one-page-mraid-resize-canvas.js +46 -0
- package/dist/templates/patches/p2.min.js +27 -0
- package/dist/templates/patches/playcraft-no-xhr.js +76 -0
- package/dist/templates/playcanvas-stable.min.js +16363 -0
- package/dist/templates/styles.css +43 -0
- package/dist/types.d.ts +14 -1
- package/dist/utils/build-mode-detector.d.ts +9 -0
- package/dist/utils/build-mode-detector.js +42 -0
- package/dist/vite/config-builder.d.ts +29 -1
- package/dist/vite/config-builder.js +169 -39
- package/dist/vite/platform-configs.d.ts +4 -0
- package/dist/vite/platform-configs.js +98 -14
- package/dist/vite/plugin-esm-html-generator.d.ts +22 -0
- package/dist/vite/plugin-esm-html-generator.js +1061 -0
- package/dist/vite/plugin-platform.js +56 -17
- package/dist/vite/plugin-playcanvas.d.ts +2 -0
- package/dist/vite/plugin-playcanvas.js +579 -49
- package/dist/vite/plugin-source-builder.d.ts +3 -0
- package/dist/vite/plugin-source-builder.js +920 -23
- package/dist/vite-builder.d.ts +19 -2
- package/dist/vite-builder.js +162 -12
- package/package.json +2 -1
- package/physics/cannon-es-bundle.js +13092 -0
- package/physics/cannon-rigidbody-adapter.js +375 -0
- package/physics/connon-integration.js +411 -0
- package/templates/__start__.js +8 -3
- package/templates/index.esm.html +20 -0
- package/templates/index.esm.mjs +502 -0
- package/templates/patches/one-page-inline-game-scripts.js +33 -1
- package/templates/patches/playcraft-cta-adapter.js +297 -0
- package/templates/patches/playcraft-no-xhr.js +25 -1
- package/templates/playcanvas-esm-wrapper.mjs +827 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
html {
|
|
2
|
+
height: 100%;
|
|
3
|
+
width: 100%;
|
|
4
|
+
background-color: #1d292c;
|
|
5
|
+
}
|
|
6
|
+
body {
|
|
7
|
+
margin: 0;
|
|
8
|
+
max-height: 100%;
|
|
9
|
+
height: 100%;
|
|
10
|
+
overflow: hidden;
|
|
11
|
+
background-color: #1d292c;
|
|
12
|
+
font-family: Helvetica, arial, sans-serif;
|
|
13
|
+
position: relative;
|
|
14
|
+
width: 100%;
|
|
15
|
+
|
|
16
|
+
-webkit-tap-highlight-color: transparent;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
#application-canvas {
|
|
20
|
+
display: block;
|
|
21
|
+
position: absolute;
|
|
22
|
+
top: 0;
|
|
23
|
+
left: 0;
|
|
24
|
+
right: 0;
|
|
25
|
+
bottom: 0;
|
|
26
|
+
}
|
|
27
|
+
#application-canvas.fill-mode-NONE {
|
|
28
|
+
margin: auto;
|
|
29
|
+
}
|
|
30
|
+
#application-canvas.fill-mode-KEEP_ASPECT {
|
|
31
|
+
width: 100%;
|
|
32
|
+
height: auto;
|
|
33
|
+
margin: 0;
|
|
34
|
+
}
|
|
35
|
+
#application-canvas.fill-mode-FILL_WINDOW {
|
|
36
|
+
width: 100%;
|
|
37
|
+
height: 100%;
|
|
38
|
+
margin: 0;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
canvas:focus {
|
|
42
|
+
outline: none;
|
|
43
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
export type Platform = 'facebook' | 'snapchat' | 'ironsource' | 'applovin' | 'google' | 'tiktok' | 'unity' | 'liftoff' | 'moloco' | 'bigo' | 'inmobi' | 'adikteev' | 'remerge';
|
|
1
|
+
export type Platform = 'playcraft' | 'facebook' | 'snapchat' | 'ironsource' | 'applovin' | 'google' | 'tiktok' | 'unity' | 'liftoff' | 'moloco' | 'bigo' | 'inmobi' | 'adikteev' | 'remerge';
|
|
2
2
|
export type OutputFormat = 'html' | 'zip';
|
|
3
|
+
export type BuildMode = 'classic' | 'esm';
|
|
4
|
+
export type ESMMode = 'auto' | 'enabled' | 'disabled';
|
|
3
5
|
export interface BuildOptions {
|
|
4
6
|
platform: Platform;
|
|
5
7
|
format?: OutputFormat;
|
|
@@ -33,6 +35,17 @@ export interface BuildOptions {
|
|
|
33
35
|
convertToWebP?: boolean;
|
|
34
36
|
compressModels?: boolean;
|
|
35
37
|
modelCompression?: 'draco' | 'meshopt';
|
|
38
|
+
esmMode?: ESMMode;
|
|
39
|
+
preserveESM?: boolean;
|
|
40
|
+
forceIIFE?: boolean;
|
|
41
|
+
}
|
|
42
|
+
export interface BaseBuildMetadata {
|
|
43
|
+
mode: BuildMode;
|
|
44
|
+
importMap?: {
|
|
45
|
+
id: string;
|
|
46
|
+
imports: Record<string, string>;
|
|
47
|
+
};
|
|
48
|
+
entryPoint?: string;
|
|
36
49
|
}
|
|
37
50
|
export interface LocalBuildOptions {
|
|
38
51
|
scriptsConcatenate?: boolean;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { BaseBuildMetadata } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* 检测 Base Build 的构建模式
|
|
4
|
+
*/
|
|
5
|
+
export declare function detectBuildMode(baseBuildDir: string): Promise<BaseBuildMetadata>;
|
|
6
|
+
/**
|
|
7
|
+
* 解析 Import Map 为 Vite resolve.alias
|
|
8
|
+
*/
|
|
9
|
+
export declare function importMapToAlias(importMap: Record<string, string>, baseBuildDir: string): Record<string, string>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* 检测 Base Build 的构建模式
|
|
5
|
+
*/
|
|
6
|
+
export async function detectBuildMode(baseBuildDir) {
|
|
7
|
+
// 1. 读取 index.html
|
|
8
|
+
const indexPath = path.join(baseBuildDir, 'index.html');
|
|
9
|
+
const html = await fs.readFile(indexPath, 'utf-8');
|
|
10
|
+
// 2. 检测 import map
|
|
11
|
+
const hasImportMap = html.includes('<script type="importmap">');
|
|
12
|
+
if (hasImportMap) {
|
|
13
|
+
// ESM 模式
|
|
14
|
+
const importMapMatch = html.match(/<script type="importmap">\s*(\{[\s\S]*?\})\s*<\/script>/);
|
|
15
|
+
const importMapContent = importMapMatch ? JSON.parse(importMapMatch[1]) : { imports: {} };
|
|
16
|
+
return {
|
|
17
|
+
mode: 'esm',
|
|
18
|
+
importMap: {
|
|
19
|
+
id: 'detected',
|
|
20
|
+
imports: importMapContent.imports || {},
|
|
21
|
+
},
|
|
22
|
+
entryPoint: 'js/index.mjs',
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
// Classic 模式
|
|
26
|
+
return {
|
|
27
|
+
mode: 'classic',
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* 解析 Import Map 为 Vite resolve.alias
|
|
32
|
+
*/
|
|
33
|
+
export function importMapToAlias(importMap, baseBuildDir) {
|
|
34
|
+
const alias = {};
|
|
35
|
+
for (const [key, value] of Object.entries(importMap)) {
|
|
36
|
+
// 移除尾部斜杠
|
|
37
|
+
const cleanKey = key.replace(/\/$/, '');
|
|
38
|
+
const cleanValue = value.replace(/^\.\//, '');
|
|
39
|
+
alias[cleanKey] = path.resolve(baseBuildDir, cleanValue);
|
|
40
|
+
}
|
|
41
|
+
return alias;
|
|
42
|
+
}
|
|
@@ -4,8 +4,36 @@ export declare class ViteConfigBuilder {
|
|
|
4
4
|
private baseBuildDir;
|
|
5
5
|
private platform;
|
|
6
6
|
private options;
|
|
7
|
+
private baseBuildMetadata?;
|
|
8
|
+
private esmBundledScript;
|
|
9
|
+
private finalOutputDir;
|
|
10
|
+
private viteOutputDir;
|
|
7
11
|
constructor(baseBuildDir: string, platform: Platform, options: BuildOptions);
|
|
8
|
-
create(): UserConfig
|
|
12
|
+
create(): Promise<UserConfig>;
|
|
13
|
+
/**
|
|
14
|
+
* 获取 Vite 的临时输出目录
|
|
15
|
+
*/
|
|
16
|
+
getViteOutputDir(): string;
|
|
17
|
+
/**
|
|
18
|
+
* 获取最终输出目录
|
|
19
|
+
*/
|
|
20
|
+
getFinalOutputDir(): string;
|
|
21
|
+
/**
|
|
22
|
+
* 判断是否需要转换为 IIFE
|
|
23
|
+
*/
|
|
24
|
+
private shouldConvertToIIFE;
|
|
25
|
+
/**
|
|
26
|
+
* 创建 ESM 打包配置(将 ESM 转为 IIFE)
|
|
27
|
+
*
|
|
28
|
+
* 策略:使用 index.html 作为入口,ESM 脚本已经预先打包到 this.esmBundledScript
|
|
29
|
+
*/
|
|
30
|
+
private createESMBundleConfig;
|
|
31
|
+
/**
|
|
32
|
+
* 创建传统配置(Classic 模式或保留 ESM)
|
|
33
|
+
*/
|
|
34
|
+
private createClassicConfig;
|
|
35
|
+
private createLogger;
|
|
36
|
+
private createRollupWarnHandler;
|
|
9
37
|
private getPlatformConfig;
|
|
10
38
|
private shouldMinifyCSS;
|
|
11
39
|
private shouldMinifyJS;
|
|
@@ -6,37 +6,158 @@ import viteImagemin from '@vheemstra/vite-plugin-imagemin';
|
|
|
6
6
|
import imageminMozjpeg from 'imagemin-mozjpeg';
|
|
7
7
|
import imageminPngquant from 'imagemin-pngquant';
|
|
8
8
|
import imageminWebp from 'imagemin-webp';
|
|
9
|
-
import { visualizer } from 'rollup-plugin-visualizer';
|
|
10
9
|
import { PLATFORM_CONFIGS } from './platform-configs.js';
|
|
11
10
|
import { vitePlayCanvasPlugin } from './plugin-playcanvas.js';
|
|
12
11
|
import { vitePlatformPlugin } from './plugin-platform.js';
|
|
13
12
|
import { viteModelCompressionPlugin } from './plugin-model-compression.js';
|
|
13
|
+
import { viteESMBundlePlugin, bundleESMToIIFE } from './plugin-esm-html-generator.js';
|
|
14
14
|
import { createPlatformAdapter } from '../platforms/index.js';
|
|
15
|
+
import { detectBuildMode, importMapToAlias } from '../utils/build-mode-detector.js';
|
|
15
16
|
export class ViteConfigBuilder {
|
|
16
17
|
constructor(baseBuildDir, platform, options) {
|
|
17
18
|
this.baseBuildDir = baseBuildDir;
|
|
18
19
|
this.platform = platform;
|
|
19
20
|
this.options = options;
|
|
21
|
+
this.esmBundledScript = ''; // 预先打包的 ESM 脚本
|
|
22
|
+
this.finalOutputDir = ''; // 用户指定的最终输出目录
|
|
23
|
+
this.viteOutputDir = ''; // Vite 的临时输出目录(在 root 下)
|
|
20
24
|
}
|
|
21
|
-
create() {
|
|
25
|
+
async create() {
|
|
26
|
+
// 1. 检测 Base Build 模式
|
|
27
|
+
this.baseBuildMetadata = await detectBuildMode(this.baseBuildDir);
|
|
28
|
+
console.log(`[ViteConfigBuilder] 检测到构建模式: ${this.baseBuildMetadata.mode}`);
|
|
29
|
+
// 2. 决定最终输出格式
|
|
30
|
+
const shouldConvertToIIFE = this.shouldConvertToIIFE();
|
|
31
|
+
console.log(`[ViteConfigBuilder] 转换为 IIFE: ${shouldConvertToIIFE}`);
|
|
22
32
|
const platformConfig = this.getPlatformConfig();
|
|
23
33
|
const outputDir = this.options.outputDir || './dist';
|
|
24
34
|
const playableOptions = this.getPlayableOptions(platformConfig);
|
|
25
35
|
const rootDir = fs.realpathSync(this.baseBuildDir);
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
36
|
+
// 为了避免 Vite build-html 插件的路径问题,使用相对于 root 的输出目录
|
|
37
|
+
// 注意:必须使用相对路径字符串,不能用绝对路径
|
|
38
|
+
const viteOutputDir = '__dist__'; // 相对于 root 的路径
|
|
39
|
+
const viteOutputDirAbsolute = path.join(rootDir, viteOutputDir);
|
|
40
|
+
// 确保用户的 outputDir 是绝对路径(用于后续复制)
|
|
41
|
+
const finalOutputDir = path.isAbsolute(outputDir)
|
|
42
|
+
? outputDir
|
|
43
|
+
: path.resolve(process.cwd(), outputDir);
|
|
44
|
+
// 保存最终输出目录,供 ViteBuilder 使用
|
|
45
|
+
this.finalOutputDir = finalOutputDir;
|
|
46
|
+
this.viteOutputDir = viteOutputDirAbsolute;
|
|
47
|
+
console.log(`[ViteConfigBuilder] 路径配置:`);
|
|
48
|
+
console.log(` - root: ${rootDir}`);
|
|
49
|
+
console.log(` - viteOutputDir (相对): ${viteOutputDir}`);
|
|
50
|
+
console.log(` - viteOutputDir (绝对): ${viteOutputDirAbsolute}`);
|
|
51
|
+
console.log(` - finalOutputDir: ${finalOutputDir}`);
|
|
52
|
+
// 3. 如果需要,预先打包 ESM 脚本(在主 Vite 构建之前)
|
|
53
|
+
if (this.baseBuildMetadata.mode === 'esm' && shouldConvertToIIFE) {
|
|
54
|
+
this.esmBundledScript = await bundleESMToIIFE({
|
|
55
|
+
baseBuildDir: this.baseBuildDir,
|
|
56
|
+
outputDir: viteOutputDirAbsolute,
|
|
57
|
+
minify: platformConfig.minifyJS,
|
|
58
|
+
});
|
|
59
|
+
return this.createESMBundleConfig(platformConfig, viteOutputDir, playableOptions, rootDir);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
return this.createClassicConfig(platformConfig, viteOutputDir, playableOptions, rootDir);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* 获取 Vite 的临时输出目录
|
|
67
|
+
*/
|
|
68
|
+
getViteOutputDir() {
|
|
69
|
+
return this.viteOutputDir || '';
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* 获取最终输出目录
|
|
73
|
+
*/
|
|
74
|
+
getFinalOutputDir() {
|
|
75
|
+
return this.finalOutputDir || '';
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* 判断是否需要转换为 IIFE
|
|
79
|
+
*/
|
|
80
|
+
shouldConvertToIIFE() {
|
|
81
|
+
// 1. 处理 esmMode 选项(优先)
|
|
82
|
+
const esmMode = this.options.esmMode || 'auto';
|
|
83
|
+
if (esmMode === 'disabled') {
|
|
84
|
+
return true; // 用户强制禁用 ESM,转换为 IIFE
|
|
85
|
+
}
|
|
86
|
+
if (esmMode === 'enabled') {
|
|
87
|
+
return false; // 用户强制启用 ESM,保留原生格式
|
|
88
|
+
}
|
|
89
|
+
// 2. 向后兼容旧的 API(如果设置了这些选项)
|
|
90
|
+
if (this.options.forceIIFE)
|
|
91
|
+
return true;
|
|
92
|
+
if (this.options.preserveESM)
|
|
93
|
+
return false;
|
|
94
|
+
// 3. 自动模式(默认):根据项目和平台特性决定
|
|
95
|
+
// 如果是 Classic 模式,不需要转换
|
|
96
|
+
if (this.baseBuildMetadata?.mode === 'classic') {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
// 根据平台配置决定
|
|
100
|
+
const platformConfig = PLATFORM_CONFIGS[this.platform];
|
|
101
|
+
const esmSupport = platformConfig.esmSupport;
|
|
102
|
+
if (!esmSupport || !esmSupport.enabled) {
|
|
103
|
+
return true; // 平台不支持 ESM,必须转换
|
|
104
|
+
}
|
|
105
|
+
return esmSupport.preferIIFE ?? true; // 默认转换为 IIFE(更安全)
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* 创建 ESM 打包配置(将 ESM 转为 IIFE)
|
|
109
|
+
*
|
|
110
|
+
* 策略:使用 index.html 作为入口,ESM 脚本已经预先打包到 this.esmBundledScript
|
|
111
|
+
*/
|
|
112
|
+
createESMBundleConfig(platformConfig, outputDir, playableOptions, rootDir) {
|
|
113
|
+
const logger = this.createLogger();
|
|
114
|
+
const metadata = this.baseBuildMetadata;
|
|
115
|
+
console.log(`[ViteConfigBuilder] ESM Bundle 配置:`);
|
|
116
|
+
console.log(` - root: ${rootDir}`);
|
|
117
|
+
console.log(` - outDir: ${outputDir}`);
|
|
118
|
+
return defineConfig({
|
|
119
|
+
root: rootDir,
|
|
120
|
+
base: './',
|
|
121
|
+
customLogger: logger,
|
|
122
|
+
resolve: {
|
|
123
|
+
// 将 Import Map 转换为 Vite alias
|
|
124
|
+
alias: metadata.importMap
|
|
125
|
+
? importMapToAlias(metadata.importMap.imports, rootDir)
|
|
126
|
+
: {},
|
|
34
127
|
},
|
|
35
|
-
|
|
128
|
+
build: {
|
|
129
|
+
outDir: outputDir,
|
|
130
|
+
emptyOutDir: true,
|
|
131
|
+
cssMinify: this.shouldMinifyCSS(platformConfig) ? 'lightningcss' : false,
|
|
132
|
+
minify: this.shouldMinifyJS(platformConfig) ? 'terser' : false,
|
|
133
|
+
terserOptions: {
|
|
134
|
+
compress: {
|
|
135
|
+
drop_console: true,
|
|
136
|
+
drop_debugger: true,
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
assetsInlineLimit: Infinity,
|
|
140
|
+
sourcemap: platformConfig.includeSourcemap,
|
|
141
|
+
rollupOptions: {
|
|
142
|
+
// 不设置 input,让 Vite 自动从 root 目录发现 index.html
|
|
143
|
+
onwarn: this.createRollupWarnHandler(),
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
plugins: this.createPlugins(platformConfig, outputDir, playableOptions, true),
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* 创建传统配置(Classic 模式或保留 ESM)
|
|
151
|
+
*/
|
|
152
|
+
createClassicConfig(platformConfig, outputDir, playableOptions, rootDir) {
|
|
153
|
+
const logger = this.createLogger();
|
|
154
|
+
console.log(`[ViteConfigBuilder] Classic 配置:`);
|
|
155
|
+
console.log(` - root: ${rootDir}`);
|
|
156
|
+
console.log(` - outDir: ${outputDir}`);
|
|
36
157
|
return defineConfig({
|
|
37
158
|
root: rootDir,
|
|
38
159
|
base: './',
|
|
39
|
-
customLogger,
|
|
160
|
+
customLogger: logger,
|
|
40
161
|
build: {
|
|
41
162
|
outDir: outputDir,
|
|
42
163
|
emptyOutDir: true,
|
|
@@ -55,21 +176,34 @@ export class ViteConfigBuilder {
|
|
|
55
176
|
// 不生成 sourcemap(Playable Ads 不需要)
|
|
56
177
|
sourcemap: platformConfig.includeSourcemap,
|
|
57
178
|
rollupOptions: {
|
|
58
|
-
input
|
|
59
|
-
|
|
60
|
-
},
|
|
61
|
-
onwarn(warning, warn) {
|
|
62
|
-
const message = typeof warning === 'string' ? warning : warning.message;
|
|
63
|
-
if (message && message.includes('can\'t be bundled without type="module"')) {
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
warn(warning);
|
|
67
|
-
},
|
|
179
|
+
// 不设置 input,让 Vite 自动从 root 目录发现 index.html
|
|
180
|
+
onwarn: this.createRollupWarnHandler(),
|
|
68
181
|
},
|
|
69
182
|
},
|
|
70
|
-
plugins: this.createPlugins(platformConfig, outputDir, playableOptions),
|
|
183
|
+
plugins: this.createPlugins(platformConfig, outputDir, playableOptions, false),
|
|
71
184
|
});
|
|
72
185
|
}
|
|
186
|
+
createLogger() {
|
|
187
|
+
const logger = createLogger();
|
|
188
|
+
return {
|
|
189
|
+
...logger,
|
|
190
|
+
warn(msg, options) {
|
|
191
|
+
if (typeof msg === 'string' && msg.includes('can\'t be bundled without type="module"')) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
logger.warn(msg, options);
|
|
195
|
+
},
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
createRollupWarnHandler() {
|
|
199
|
+
return (warning, warn) => {
|
|
200
|
+
const message = typeof warning === 'string' ? warning : warning.message;
|
|
201
|
+
if (message && message.includes('can\'t be bundled without type="module"')) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
warn(warning);
|
|
205
|
+
};
|
|
206
|
+
}
|
|
73
207
|
getPlatformConfig() {
|
|
74
208
|
const baseConfig = PLATFORM_CONFIGS[this.platform];
|
|
75
209
|
const resolvedOutputFormat = this.options.format ?? baseConfig.outputFormat;
|
|
@@ -93,11 +227,18 @@ export class ViteConfigBuilder {
|
|
|
93
227
|
shouldMinifyJS(config) {
|
|
94
228
|
return config.minifyJS;
|
|
95
229
|
}
|
|
96
|
-
createPlugins(platformConfig, outputDir, playableOptions) {
|
|
230
|
+
createPlugins(platformConfig, outputDir, playableOptions, isESMBundle = false) {
|
|
97
231
|
const plugins = [];
|
|
98
|
-
//
|
|
232
|
+
// 0. ESM Bundle 插件(如果是 ESM 模式且需要转换为 IIFE)
|
|
233
|
+
// ESM 脚本已经预先打包到 this.esmBundledScript
|
|
234
|
+
if (isESMBundle && this.baseBuildMetadata?.mode === 'esm' && this.esmBundledScript) {
|
|
235
|
+
plugins.push(viteESMBundlePlugin(this.esmBundledScript));
|
|
236
|
+
}
|
|
237
|
+
// 1. PlayCanvas 资源转换插件
|
|
99
238
|
plugins.push(vitePlayCanvasPlugin({
|
|
100
239
|
baseBuildDir: this.baseBuildDir,
|
|
240
|
+
buildMode: this.baseBuildMetadata?.mode || 'classic',
|
|
241
|
+
isESMBundle: isESMBundle,
|
|
101
242
|
inlineScripts: true,
|
|
102
243
|
convertDataUrls: platformConfig.outputFormat === 'html',
|
|
103
244
|
outputFormat: playableOptions.outputFormat,
|
|
@@ -110,10 +251,12 @@ export class ViteConfigBuilder {
|
|
|
110
251
|
}));
|
|
111
252
|
// 2. 平台特定插件
|
|
112
253
|
const platformAdapter = createPlatformAdapter(this.options);
|
|
254
|
+
// 注意:outputDir 需要使用绝对路径,因为 copyBaseBuildAssets 需要绝对路径
|
|
255
|
+
const absoluteOutputDir = this.viteOutputDir || path.resolve(this.baseBuildDir, outputDir);
|
|
113
256
|
plugins.push(vitePlatformPlugin({
|
|
114
257
|
platform: this.platform,
|
|
115
258
|
adapter: platformAdapter,
|
|
116
|
-
outputDir:
|
|
259
|
+
outputDir: absoluteOutputDir,
|
|
117
260
|
baseBuildDir: this.baseBuildDir,
|
|
118
261
|
outputFormat: platformConfig.outputFormat,
|
|
119
262
|
externFiles: playableOptions.externFiles,
|
|
@@ -163,19 +306,6 @@ export class ViteConfigBuilder {
|
|
|
163
306
|
removeViteModuleLoader: true,
|
|
164
307
|
}));
|
|
165
308
|
}
|
|
166
|
-
// 6. 打包分析报告
|
|
167
|
-
if (this.options.analyze) {
|
|
168
|
-
const reportPath = this.options.analyzeReportPath
|
|
169
|
-
? this.options.analyzeReportPath
|
|
170
|
-
: path.join(outputDir, 'bundle-report.html');
|
|
171
|
-
plugins.push(visualizer({
|
|
172
|
-
filename: reportPath,
|
|
173
|
-
template: 'treemap',
|
|
174
|
-
gzipSize: true,
|
|
175
|
-
brotliSize: true,
|
|
176
|
-
open: false,
|
|
177
|
-
}));
|
|
178
|
-
}
|
|
179
309
|
return plugins.filter(Boolean);
|
|
180
310
|
}
|
|
181
311
|
getPlayableOptions(config) {
|