@playcraft/devkit 1.0.28 → 1.0.29
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/cli/bin/playable-scripts.js +6 -44
- package/cli/commands/build.js +40 -220
- package/cli/commands/builds.js +2 -13
- package/cli/commands/dev.js +1 -7
- package/cli/commands/pack.js +39 -308
- package/cli/commands/vite-dev.js +1 -7
- package/core/batch-build.js +149 -1255
- package/core/constants.js +2 -16
- package/core/cos-uploader.js +24 -286
- package/core/index.d.ts +4 -1
- package/core/index.js +7 -76
- package/core/loaders/gltf-loader.js +28 -74
- package/core/options.js +15 -326
- package/core/plugins/AdikteevInjectorPlugin.js +4 -26
- package/core/plugins/BigoAdsInjectorPlugin.js +4 -21
- package/core/plugins/DAPIInjectorPlugin.js +2 -25
- package/core/plugins/DebuggerInjectionPlugin.js +3 -31
- package/core/plugins/ExitAPIInjectorPlugin.js +3 -56
- package/core/plugins/FflateCompressionPlugin.js +40 -231
- package/core/plugins/FontInjectionWebpackPlugin.js +4 -46
- package/core/plugins/LiftoffInjectorPlugin.js +4 -26
- package/core/plugins/MRAIDInjectorPlugin.js +2 -24
- package/core/plugins/MintegralInjectorPlugin.js +2 -25
- package/core/plugins/PangleInjectorPlugin.js +2 -24
- package/core/plugins/PlaycraftOrientationInjectorPlugin.js +3 -29
- package/core/plugins/SnapchatInjectorPlugin.js +4 -26
- package/core/plugins/SocialMediaInjectorPlugin.js +7 -119
- package/core/plugins/TikTokInjectorPlugin.js +2 -24
- package/core/plugins/UnityInjectorPlugin.js +8 -37
- package/core/plugins/ZipPlugin.js +20 -138
- package/core/plugins/socialMediaVitePlugin.js +2 -108
- package/core/utils/buildDefines.js +2 -30
- package/core/utils/buildTemplateString.js +5 -39
- package/core/utils/date.js +1 -16
- package/core/utils/fontRegistry.js +13 -81
- package/core/utils/fontResolver.js +37 -335
- package/core/utils/generateAdikteevHtmlWebpackPluginConfig.js +7 -42
- package/core/utils/generateBigabidHtmlWebpackPluginConfig.js +3 -30
- package/core/utils/generateInMobiHtmlWebpackPluginConfig.js +7 -43
- package/core/utils/getPlaycraftOrientationSuffix.js +2 -9
- package/core/utils/injectSDKPlugins.js +13 -68
- package/core/utils/logOptions.js +5 -46
- package/core/utils/mergeOptions.js +2 -19
- package/core/utils/parseArgvOptions.js +5 -111
- package/core/utils/resolveChannelFold2Zip.js +5 -17
- package/core/utils/validateThemeData.js +26 -227
- package/core/validators/pre-build-checker.js +26 -286
- package/core/validators/tracking-validator.js +40 -358
- package/core/vite.dev.js +17 -322
- package/core/webpack.build.js +65 -520
- package/core/webpack.common.js +11 -177
- package/core/webpack.dev.js +6 -88
- package/defines.d.ts +1 -0
- package/package.json +3 -4
- package/README.md +0 -262
package/core/vite.dev.js
CHANGED
|
@@ -1,337 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
const fs =
|
|
5
|
-
const {
|
|
6
|
-
const {
|
|
7
|
-
const { buildDefines } = require('./utils/buildDefines.js');
|
|
8
|
-
const { logOptions } = require('./utils/logOptions.js');
|
|
9
|
-
const { getOrGenerateFontCSS } = require('./utils/fontResolver.js');
|
|
10
|
-
const { socialMediaVitePlugin } = require('./plugins/socialMediaVitePlugin.js');
|
|
11
|
-
|
|
12
|
-
// ── 公共 Vite 插件(供项目 vite.config.ts 直接引用) ──
|
|
13
|
-
|
|
14
|
-
/** JSON5 文件加载插件 */
|
|
15
|
-
function json5Plugin() {
|
|
16
|
-
return {
|
|
17
|
-
name: 'vite-plugin-json5',
|
|
18
|
-
transform(code, id) {
|
|
19
|
-
if (id.endsWith('.json5')) {
|
|
20
|
-
const JSON5 = require('json5');
|
|
21
|
-
const raw = fs.readFileSync(id, 'utf-8');
|
|
22
|
-
const parsed = JSON5.parse(raw);
|
|
23
|
-
return {
|
|
24
|
-
code: `export default ${JSON.stringify(parsed)};`,
|
|
25
|
-
map: null,
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/** 资源内联插件(模拟 webpack 的 asset/inline 行为) */
|
|
33
|
-
function assetInlinePlugin() {
|
|
34
|
-
return {
|
|
35
|
-
name: 'vite-plugin-asset-inline',
|
|
36
|
-
enforce: 'pre',
|
|
37
|
-
transform(code, id) {
|
|
38
|
-
// .atlas 文件 -> base64 data URL
|
|
39
|
-
if (id.endsWith('.atlas')) {
|
|
40
|
-
const content = fs.readFileSync(id);
|
|
41
|
-
const base64 = content.toString('base64');
|
|
42
|
-
return {
|
|
43
|
-
code: `export default "data:text/atlas;base64,${base64}";`,
|
|
44
|
-
map: null,
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
// .fnt 文件 -> base64 data URL
|
|
48
|
-
if (id.endsWith('.fnt')) {
|
|
49
|
-
const content = fs.readFileSync(id);
|
|
50
|
-
const base64 = content.toString('base64');
|
|
51
|
-
return {
|
|
52
|
-
code: `export default "data:text/plain;base64,${base64}";`,
|
|
53
|
-
map: null,
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
// .xml 文件 -> 原始文本
|
|
57
|
-
if (id.endsWith('.xml')) {
|
|
58
|
-
const raw = fs.readFileSync(id, 'utf-8');
|
|
59
|
-
return {
|
|
60
|
-
code: `export default ${JSON.stringify(raw)};`,
|
|
61
|
-
map: null,
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
},
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/** 字体注入插件(dev 模式:读取字体文件 base64 内联到 index.html) */
|
|
69
|
-
function fontFamilyPlugin() {
|
|
70
|
-
let _themeName = null;
|
|
71
|
-
let _themeConfig = null;
|
|
72
|
-
|
|
73
|
-
// 检测当前主题名(与 build.js 中 detectCurrentTheme 逻辑一致)
|
|
74
|
-
function detectTheme() {
|
|
75
|
-
const root = process.cwd();
|
|
76
|
-
const buildsConfigPath = path.join(root, 'builds.config.js');
|
|
77
|
-
let config = { sourceDir: 'src/theme', entryFile: 'src/theme/index.ts' };
|
|
78
|
-
if (fs.existsSync(buildsConfigPath)) {
|
|
79
|
-
try {
|
|
80
|
-
delete require.cache[require.resolve(buildsConfigPath)];
|
|
81
|
-
const buildsConfig = require(buildsConfigPath);
|
|
82
|
-
if (buildsConfig.themes) {
|
|
83
|
-
config = { ...config, ...buildsConfig.themes };
|
|
84
|
-
}
|
|
85
|
-
} catch (_) { /* ignore */ }
|
|
86
|
-
}
|
|
87
|
-
let name = null;
|
|
88
|
-
const entryPath = path.join(root, config.entryFile);
|
|
89
|
-
if (fs.existsSync(entryPath)) {
|
|
90
|
-
const content = fs.readFileSync(entryPath, 'utf8');
|
|
91
|
-
const match = content.match(/from\s+['"]\.\/([^'"]+)['"]/);
|
|
92
|
-
if (match) name = match[1];
|
|
93
|
-
}
|
|
94
|
-
return { themeName: name, themeConfig: config };
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return {
|
|
98
|
-
name: 'vite-plugin-font-family',
|
|
99
|
-
apply: 'serve',
|
|
100
|
-
transformIndexHtml: {
|
|
101
|
-
order: 'pre',
|
|
102
|
-
handler() {
|
|
103
|
-
if (_themeName === null) {
|
|
104
|
-
const detected = detectTheme();
|
|
105
|
-
_themeName = detected.themeName;
|
|
106
|
-
_themeConfig = detected.themeConfig;
|
|
107
|
-
}
|
|
108
|
-
if (!_themeName) return '';
|
|
109
|
-
const css = getOrGenerateFontCSS({
|
|
110
|
-
projectRoot: process.cwd(),
|
|
111
|
-
themeName: _themeName,
|
|
112
|
-
themeConfig: _themeConfig,
|
|
113
|
-
});
|
|
114
|
-
return css ? [{ tag: 'style', attrs: { 'data-playable-fonts': '' }, children: css.replace(/<\/?style[^>]*>/g, ''), injectTo: 'head' }] : [];
|
|
115
|
-
},
|
|
116
|
-
},
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// ── makeViteDevConfig / runViteDev ──
|
|
121
|
-
|
|
1
|
+
"use strict";const path=require("path");const fs=require("fs");const{options}=require("./options.js");const{mergeOptions}=require("./utils/mergeOptions.js");const{buildDefines}=require("./utils/buildDefines.js");const{logOptions}=require("./utils/logOptions.js");const{getOrGenerateFontCSS}=require("./utils/fontResolver.js");const{socialMediaVitePlugin}=require("./plugins/socialMediaVitePlugin.js");// ── 公共 Vite 插件(供项目 vite.config.ts 直接引用) ──
|
|
2
|
+
/** JSON5 文件加载插件 */function json5Plugin(){return{name:"vite-plugin-json5",transform(code,id){if(id.endsWith(".json5")){const JSON5=require("json5");const raw=fs.readFileSync(id,"utf-8");const parsed=JSON5.parse(raw);return{code:`export default ${JSON.stringify(parsed)};`,map:null}}}}}/** 资源内联插件(模拟 webpack 的 asset/inline 行为) */function assetInlinePlugin(){return{name:"vite-plugin-asset-inline",enforce:"pre",transform(code,id){// .atlas 文件 -> base64 data URL
|
|
3
|
+
if(id.endsWith(".atlas")){const content=fs.readFileSync(id);const base64=content.toString("base64");return{code:`export default "data:text/atlas;base64,${base64}";`,map:null}}// .fnt 文件 -> base64 data URL
|
|
4
|
+
if(id.endsWith(".fnt")){const content=fs.readFileSync(id);const base64=content.toString("base64");return{code:`export default "data:text/plain;base64,${base64}";`,map:null}}// .xml 文件 -> 原始文本
|
|
5
|
+
if(id.endsWith(".xml")){const raw=fs.readFileSync(id,"utf-8");return{code:`export default ${JSON.stringify(raw)};`,map:null}}}}}/** 字体注入插件(dev 模式:读取字体文件 base64 内联到 index.html) */function fontFamilyPlugin(){let _themeName=null;let _themeConfig=null;// 检测当前主题名(与 build.js 中 detectCurrentTheme 逻辑一致)
|
|
6
|
+
function detectTheme(){const root=process.cwd();const buildsConfigPath=path.join(root,"builds.config.js");let config={sourceDir:"src/theme",entryFile:"src/theme/index.ts"};if(fs.existsSync(buildsConfigPath)){try{delete require.cache[require.resolve(buildsConfigPath)];const buildsConfig=require(buildsConfigPath);if(buildsConfig.themes){config={...config,...buildsConfig.themes}}}catch(_){/* ignore */}}let name=null;const entryPath=path.join(root,config.entryFile);if(fs.existsSync(entryPath)){const content=fs.readFileSync(entryPath,"utf8");const match=content.match(/from\s+['"]\.\/([^'"]+)['"]/);if(match)name=match[1]}return{themeName:name,themeConfig:config}}return{name:"vite-plugin-font-family",apply:"serve",transformIndexHtml:{order:"pre",handler(){if(_themeName===null){const detected=detectTheme();_themeName=detected.themeName;_themeConfig=detected.themeConfig}if(!_themeName)return"";const css=getOrGenerateFontCSS({projectRoot:process.cwd(),themeName:_themeName,themeConfig:_themeConfig});return css?[{tag:"style",attrs:{"data-playable-fonts":""},children:css.replace(/<\/?style[^>]*>/g,""),injectTo:"head"}]:[]}}}}// ── makeViteDevConfig / runViteDev ──
|
|
122
7
|
/**
|
|
123
8
|
* 创建 Vite 开发配置
|
|
124
9
|
* @param {Partial<import('./index').CLIOptions>} [customOptions] - 自定义选项,会与默认选项合并
|
|
125
10
|
* @param {Record<string, any>} [customDefines] - 额外的 define 常量
|
|
126
11
|
* @param {import('vite').UserConfig} [viteCustomConfig] - 自定义 Vite 配置,会与默认配置合并
|
|
127
12
|
* @returns {import('vite').UserConfig} 最终的 Vite 开发配置
|
|
128
|
-
*/
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
// 构建 define 常量(复用 webpack 的 buildDefines 逻辑)
|
|
136
|
-
const defines = {
|
|
137
|
-
...buildDefines(),
|
|
138
|
-
...devOptions.defines,
|
|
139
|
-
__DEV__: JSON.stringify(devOptions['dev'] === undefined ? true : devOptions['dev']),
|
|
140
|
-
...customDefines,
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
// 解析 tsconfig/jsconfig 路径别名
|
|
144
|
-
const tsConfigPath = path.resolve(devOptions.tsConfig || 'tsconfig.json');
|
|
145
|
-
const jsConfigPath = path.resolve(devOptions.jsConfig || 'jsconfig.json');
|
|
146
|
-
let aliasConfig = {};
|
|
147
|
-
|
|
148
|
-
// 尝试从 tsconfig/jsconfig 中读取 paths 配置
|
|
149
|
-
let configFilePath = null;
|
|
150
|
-
if (fs.existsSync(tsConfigPath)) {
|
|
151
|
-
configFilePath = tsConfigPath;
|
|
152
|
-
} else if (fs.existsSync(jsConfigPath)) {
|
|
153
|
-
configFilePath = jsConfigPath;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
if (configFilePath) {
|
|
157
|
-
try {
|
|
158
|
-
const JSON5 = require('json5');
|
|
159
|
-
const configContent = fs.readFileSync(configFilePath, 'utf-8');
|
|
160
|
-
const config = JSON5.parse(configContent);
|
|
161
|
-
const paths = config.compilerOptions?.paths || {};
|
|
162
|
-
for (const [alias, targets] of Object.entries(paths)) {
|
|
163
|
-
// 将 tsconfig paths 格式 "foo/*" -> ["src/foo/*"] 转换为 vite alias
|
|
164
|
-
const cleanAlias = alias.replace('/*', '');
|
|
165
|
-
const cleanTarget = targets[0]?.replace('/*', '') || '';
|
|
166
|
-
if (cleanAlias && cleanTarget) {
|
|
167
|
-
aliasConfig[cleanAlias] = path.resolve(cleanTarget);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
} catch (err) {
|
|
171
|
-
console.log('\x1b[33m⚠️ 读取路径配置失败: ' + err.message + '\x1b[0m');
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// 默认别名
|
|
176
|
-
aliasConfig = {
|
|
177
|
-
assets: path.resolve('assets'),
|
|
178
|
-
'@': path.resolve('src'),
|
|
179
|
-
...aliasConfig,
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
/** @type {import('vite').UserConfig} */
|
|
183
|
-
const viteConfig = {
|
|
184
|
-
root: '.',
|
|
185
|
-
resolve: {
|
|
186
|
-
alias: aliasConfig,
|
|
187
|
-
},
|
|
188
|
-
plugins: [json5Plugin(), assetInlinePlugin(), fontFamilyPlugin(), socialMediaVitePlugin()],
|
|
189
|
-
define: defines,
|
|
190
|
-
server: {
|
|
191
|
-
port: devOptions['port'] || 3000,
|
|
192
|
-
open: devOptions['open'] || false,
|
|
193
|
-
},
|
|
194
|
-
build: {
|
|
195
|
-
outDir: devOptions['outDir'] || 'dist',
|
|
196
|
-
sourcemap: true,
|
|
197
|
-
},
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
// 合并自定义配置
|
|
201
|
-
if (viteCustomConfig) {
|
|
202
|
-
const { plugins: customPlugins, define: customDefine, resolve: customResolve, server: customServer, build: customBuild, ...rest } = viteCustomConfig;
|
|
203
|
-
|
|
204
|
-
if (customPlugins) {
|
|
205
|
-
viteConfig.plugins = [...viteConfig.plugins, ...customPlugins];
|
|
206
|
-
}
|
|
207
|
-
if (customDefine) {
|
|
208
|
-
viteConfig.define = { ...viteConfig.define, ...customDefine };
|
|
209
|
-
}
|
|
210
|
-
if (customResolve) {
|
|
211
|
-
viteConfig.resolve = {
|
|
212
|
-
...viteConfig.resolve,
|
|
213
|
-
...customResolve,
|
|
214
|
-
alias: { ...viteConfig.resolve.alias, ...(customResolve.alias || {}) },
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
if (customServer) {
|
|
218
|
-
viteConfig.server = { ...viteConfig.server, ...customServer };
|
|
219
|
-
}
|
|
220
|
-
if (customBuild) {
|
|
221
|
-
viteConfig.build = { ...viteConfig.build, ...customBuild };
|
|
222
|
-
}
|
|
223
|
-
Object.assign(viteConfig, rest);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
return viteConfig;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
/**
|
|
13
|
+
*/function makeViteDevConfig(customOptions,customDefines,viteCustomConfig){const devOptions=mergeOptions(options,customOptions);logOptions(devOptions);customDefines=customDefines||{};viteCustomConfig=viteCustomConfig||{};// 构建 define 常量(复用 webpack 的 buildDefines 逻辑)
|
|
14
|
+
const defines={...buildDefines(),...devOptions.defines,__DEV__:JSON.stringify(devOptions["dev"]===undefined?true:devOptions["dev"]),...customDefines};// 解析 tsconfig/jsconfig 路径别名
|
|
15
|
+
const tsConfigPath=path.resolve(devOptions.tsConfig||"tsconfig.json");const jsConfigPath=path.resolve(devOptions.jsConfig||"jsconfig.json");let aliasConfig={};// 尝试从 tsconfig/jsconfig 中读取 paths 配置
|
|
16
|
+
let configFilePath=null;if(fs.existsSync(tsConfigPath)){configFilePath=tsConfigPath}else if(fs.existsSync(jsConfigPath)){configFilePath=jsConfigPath}if(configFilePath){try{var _config$compilerOptio;const JSON5=require("json5");const configContent=fs.readFileSync(configFilePath,"utf-8");const config=JSON5.parse(configContent);const paths=((_config$compilerOptio=config.compilerOptions)===null||_config$compilerOptio===void 0?void 0:_config$compilerOptio.paths)||{};for(const[alias,targets]of Object.entries(paths)){var _targets$;// 将 tsconfig paths 格式 "foo/*" -> ["src/foo/*"] 转换为 vite alias
|
|
17
|
+
const cleanAlias=alias.replace("/*","");const cleanTarget=((_targets$=targets[0])===null||_targets$===void 0?void 0:_targets$.replace("/*",""))||"";if(cleanAlias&&cleanTarget){aliasConfig[cleanAlias]=path.resolve(cleanTarget)}}}catch(err){console.log("\x1B[33m\u26A0\uFE0F \u8BFB\u53D6\u8DEF\u5F84\u914D\u7F6E\u5931\u8D25: "+err.message+"\x1B[0m")}}// 默认别名
|
|
18
|
+
aliasConfig={assets:path.resolve("assets"),"@":path.resolve("src"),...aliasConfig};/** @type {import('vite').UserConfig} */const viteConfig={root:".",resolve:{alias:aliasConfig},plugins:[json5Plugin(),assetInlinePlugin(),fontFamilyPlugin(),socialMediaVitePlugin()],define:defines,server:{port:devOptions["port"]||3000,open:devOptions["open"]||false},build:{outDir:devOptions["outDir"]||"dist",sourcemap:true}};// 合并自定义配置
|
|
19
|
+
if(viteCustomConfig){const{plugins:customPlugins,define:customDefine,resolve:customResolve,server:customServer,build:customBuild,...rest}=viteCustomConfig;if(customPlugins){viteConfig.plugins=[...viteConfig.plugins,...customPlugins]}if(customDefine){viteConfig.define={...viteConfig.define,...customDefine}}if(customResolve){viteConfig.resolve={...viteConfig.resolve,...customResolve,alias:{...viteConfig.resolve.alias,...(customResolve.alias||{})}}}if(customServer){viteConfig.server={...viteConfig.server,...customServer}}if(customBuild){viteConfig.build={...viteConfig.build,...customBuild}}Object.assign(viteConfig,rest)}return viteConfig}/**
|
|
230
20
|
* 深度合并两个 Vite 配置对象。override 覆盖 base。
|
|
231
21
|
* 数组会拼接(plugins),其余字段浅覆盖。
|
|
232
|
-
*/
|
|
233
|
-
function deepMergeViteConfig(base, override) {
|
|
234
|
-
if (!override || typeof override !== 'object') return base;
|
|
235
|
-
const result = { ...base };
|
|
236
|
-
for (const key of Object.keys(override)) {
|
|
237
|
-
const bv = base[key];
|
|
238
|
-
const ov = override[key];
|
|
239
|
-
if (key === 'plugins' && Array.isArray(bv) && Array.isArray(ov)) {
|
|
240
|
-
result[key] = [...bv, ...ov];
|
|
241
|
-
} else if (
|
|
242
|
-
ov !== null && typeof ov === 'object' && !Array.isArray(ov) &&
|
|
243
|
-
bv !== null && typeof bv === 'object' && !Array.isArray(bv)
|
|
244
|
-
) {
|
|
245
|
-
result[key] = { ...bv, ...ov };
|
|
246
|
-
} else {
|
|
247
|
-
result[key] = ov;
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
return result;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
/**
|
|
22
|
+
*/function deepMergeViteConfig(base,override){if(!override||typeof override!=="object")return base;const result={...base};for(const key of Object.keys(override)){const bv=base[key];const ov=override[key];if(key==="plugins"&&Array.isArray(bv)&&Array.isArray(ov)){result[key]=[...bv,...ov]}else if(ov!==null&&typeof ov==="object"&&!Array.isArray(ov)&&bv!==null&&typeof bv==="object"&&!Array.isArray(bv)){result[key]={...bv,...ov}}else{result[key]=ov}}return result}/**
|
|
254
23
|
* 尝试加载项目根目录的 vite.config.ts。
|
|
255
|
-
*/
|
|
256
|
-
async function loadProjectViteConfig(root) {
|
|
257
|
-
const candidates = ['vite.config.ts', 'vite.config.js', 'vite.config.mjs'];
|
|
258
|
-
let configPath = null;
|
|
259
|
-
for (const c of candidates) {
|
|
260
|
-
const p = path.join(root, c);
|
|
261
|
-
if (fs.existsSync(p)) { configPath = p; break; }
|
|
262
|
-
}
|
|
263
|
-
if (!configPath) return null;
|
|
264
|
-
|
|
265
|
-
const { createRequire } = require('module');
|
|
266
|
-
let projRequire;
|
|
267
|
-
try {
|
|
268
|
-
projRequire = createRequire(path.join(root, 'package.json'));
|
|
269
|
-
} catch (_) {
|
|
270
|
-
projRequire = createRequire(path.join(root, 'noop.js'));
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
let loadConfigFromFile;
|
|
274
|
-
try {
|
|
275
|
-
loadConfigFromFile = projRequire('vite').loadConfigFromFile;
|
|
276
|
-
} catch (_) {
|
|
277
|
-
try {
|
|
278
|
-
loadConfigFromFile = projRequire('vite/dist/node/config').loadConfigFromFile;
|
|
279
|
-
} catch (_2) {
|
|
280
|
-
console.log('\x1b[33m⚠️ [vite] Cannot load project config (loadConfigFromFile unavailable), using scripts default\x1b[0m');
|
|
281
|
-
return null;
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
if (!loadConfigFromFile) return null;
|
|
286
|
-
|
|
287
|
-
try {
|
|
288
|
-
const result = await loadConfigFromFile(
|
|
289
|
-
{ command: 'serve', mode: process.env.NODE_ENV || 'development' },
|
|
290
|
-
configPath,
|
|
291
|
-
root
|
|
292
|
-
);
|
|
293
|
-
if (result && result.config) {
|
|
294
|
-
console.log(`[vite] Loaded project config: ${path.relative(root, configPath)}`);
|
|
295
|
-
return result.config;
|
|
296
|
-
}
|
|
297
|
-
return null;
|
|
298
|
-
} catch (err) {
|
|
299
|
-
console.log(`\x1b[33m⚠️ [vite] Failed to load ${path.relative(root, configPath)}: ${err.message}, using scripts default\x1b[0m`);
|
|
300
|
-
return null;
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
/**
|
|
24
|
+
*/async function loadProjectViteConfig(root){const candidates=["vite.config.ts","vite.config.js","vite.config.mjs"];let configPath=null;for(const c of candidates){const p=path.join(root,c);if(fs.existsSync(p)){configPath=p;break}}if(!configPath)return null;const{createRequire}=require("module");let projRequire;try{projRequire=createRequire(path.join(root,"package.json"))}catch(_){projRequire=createRequire(path.join(root,"noop.js"))}let loadConfigFromFile;try{loadConfigFromFile=projRequire("vite").loadConfigFromFile}catch(_){try{loadConfigFromFile=projRequire("vite/dist/node/config").loadConfigFromFile}catch(_2){console.log("\x1B[33m\u26A0\uFE0F [vite] Cannot load project config (loadConfigFromFile unavailable), using scripts default\x1B[0m");return null}}if(!loadConfigFromFile)return null;try{const result=await loadConfigFromFile({command:"serve",mode:process.env.NODE_ENV||"development"},configPath,root);if(result&&result.config){console.log(`[vite] Loaded project config: ${path.relative(root,configPath)}`);return result.config}return null}catch(err){console.log(`\x1b[33m⚠️ [vite] Failed to load ${path.relative(root,configPath)}: ${err.message}, using scripts default\x1b[0m`);return null}}/**
|
|
305
25
|
* 启动 Vite 开发服务器。
|
|
306
26
|
*
|
|
307
27
|
* 配置优先级(从低到高):
|
|
308
28
|
* 1. makeViteDevConfig 构建的默认配置(fontFamilyPlugin、json5Plugin 等)
|
|
309
29
|
* 2. 项目根目录的 vite.config.ts(如果存在,覆盖/扩充默认配置)
|
|
310
30
|
* 3. 传入的 viteConfig / customOptions / customDefines / viteCustomConfig
|
|
311
|
-
*/
|
|
312
|
-
|
|
313
|
-
if (!viteConfig) {
|
|
314
|
-
viteConfig = makeViteDevConfig(customOptions, customDefines, viteCustomConfig);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
const projectRoot = process.cwd();
|
|
318
|
-
const projectConfig = await loadProjectViteConfig(projectRoot);
|
|
319
|
-
if (projectConfig) {
|
|
320
|
-
viteConfig = deepMergeViteConfig(viteConfig, projectConfig);
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
const { createRequire } = require('module');
|
|
324
|
-
const projRequire = createRequire(path.join(projectRoot, 'package.json'));
|
|
325
|
-
const { createServer } = projRequire('vite');
|
|
326
|
-
const server = await createServer({ ...viteConfig, configFile: false });
|
|
327
|
-
await server.listen();
|
|
328
|
-
server.printUrls();
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
// ── 导出 ──
|
|
332
|
-
|
|
333
|
-
exports.json5Plugin = json5Plugin;
|
|
334
|
-
exports.assetInlinePlugin = assetInlinePlugin;
|
|
335
|
-
exports.fontFamilyPlugin = fontFamilyPlugin;
|
|
336
|
-
exports.makeViteDevConfig = makeViteDevConfig;
|
|
337
|
-
exports.runViteDev = runViteDev;
|
|
31
|
+
*/async function runViteDev(viteConfig,customOptions,customDefines,viteCustomConfig){if(!viteConfig){viteConfig=makeViteDevConfig(customOptions,customDefines,viteCustomConfig)}const projectRoot=process.cwd();const projectConfig=await loadProjectViteConfig(projectRoot);if(projectConfig){viteConfig=deepMergeViteConfig(viteConfig,projectConfig)}const{createRequire}=require("module");const projRequire=createRequire(path.join(projectRoot,"package.json"));const{createServer}=projRequire("vite");const server=await createServer({...viteConfig,configFile:false});await server.listen();server.printUrls()}// ── 导出 ──
|
|
32
|
+
exports.json5Plugin=json5Plugin;exports.assetInlinePlugin=assetInlinePlugin;exports.fontFamilyPlugin=fontFamilyPlugin;exports.makeViteDevConfig=makeViteDevConfig;exports.runViteDev=runViteDev;
|