@infly/vue2-vite 1.0.0 → 1.0.1
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/bin/vue-cli-service.mjs +135 -135
- package/package.json +1 -1
- package/src/compat/assets.mjs +165 -165
- package/src/compat/html.mjs +1 -1
- package/src/compat/import-interop.mjs +2 -2
- package/src/compat/jsx.mjs +142 -142
- package/src/compat/mock.mjs +125 -125
- package/src/compat/require-context.mjs +1 -1
- package/src/compat/sass-export.mjs +112 -112
- package/src/config/discover.mjs +261 -261
- package/src/config/vue-cli-reader.mjs +1 -0
- package/src/factory/create-vite-config.mjs +7 -8
- package/src/factory/manual-chunks.mjs +1 -0
package/src/config/discover.mjs
CHANGED
|
@@ -1,261 +1,261 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 配置发现编排器
|
|
3
|
-
*
|
|
4
|
-
* 按优先级(从低到高)加载所有配置源并合并:
|
|
5
|
-
* 1. 包安全默认值
|
|
6
|
-
* 2. 项目 vue.config.js 标准字段
|
|
7
|
-
* 3. package.json 的 inflyVite 字段
|
|
8
|
-
* 4. infly.vite.config.js / .cjs / .mjs
|
|
9
|
-
* 5. CLI 参数
|
|
10
|
-
*
|
|
11
|
-
* 规范 §9.1
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import fs from 'node:fs';
|
|
15
|
-
import path from 'node:path';
|
|
16
|
-
import { createRequire } from 'node:module';
|
|
17
|
-
import { createDefaultConfig } from './project-config.mjs';
|
|
18
|
-
import { loadVueCliConfig, extractAdditionalVueConfigInfo } from './vue-cli-reader.mjs';
|
|
19
|
-
import {
|
|
20
|
-
import { deepMerge } from './merge.mjs';
|
|
21
|
-
import { validateStrictCompatibility, diagnoseCompatIssues } from './validation.mjs';
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* 可选的 infly.vite.config 文件名(按优先级)
|
|
25
|
-
*/
|
|
26
|
-
const CONFIG_FILES = [
|
|
27
|
-
'infly.vite.config.mjs',
|
|
28
|
-
'infly.vite.config.js',
|
|
29
|
-
'infly.vite.config.cjs',
|
|
30
|
-
];
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* @param {object} options
|
|
34
|
-
* @param {string} options.command - 'serve' | 'build'
|
|
35
|
-
* @param {string} options.mode - 模式
|
|
36
|
-
* @param {string} [options.target] - CLI target
|
|
37
|
-
* @param {string} options.projectRoot - 项目根目录
|
|
38
|
-
* @param {object} [options.cliOptions] - CLI 额外选项
|
|
39
|
-
* @returns {Promise<object>} 归一化配置 + 元信息
|
|
40
|
-
*/
|
|
41
|
-
export async function discoverConfig(options = {}) {
|
|
42
|
-
const {
|
|
43
|
-
command = 'build',
|
|
44
|
-
mode = 'production',
|
|
45
|
-
target: cliTarget,
|
|
46
|
-
projectRoot = process.cwd(),
|
|
47
|
-
cliOptions = {},
|
|
48
|
-
} = options;
|
|
49
|
-
|
|
50
|
-
// test 命令复用 build 的配置语义(mode=test,读取 .env.test 等)
|
|
51
|
-
const isBuild = command === 'build' || command === 'test';
|
|
52
|
-
const isServe = command === 'serve';
|
|
53
|
-
|
|
54
|
-
// 1. 包默认值
|
|
55
|
-
const defaults = createDefaultConfig({ command, mode, target: cliTarget, projectRoot, isBuild, isServe });
|
|
56
|
-
|
|
57
|
-
// 2. 环境变量(解析 target)
|
|
58
|
-
const { target: envTarget, define } = buildDefine({
|
|
59
|
-
projectRoot,
|
|
60
|
-
mode,
|
|
61
|
-
target: cliTarget,
|
|
62
|
-
defaultTarget: defaults.context.target || 'DEFAULT',
|
|
63
|
-
});
|
|
64
|
-
const resolvedTarget = cliTarget || envTarget || 'DEFAULT';
|
|
65
|
-
|
|
66
|
-
// 3. vue.config.js 标准字段
|
|
67
|
-
const { vueConfig: vueCli, warnings: vueCliWarnings } = loadVueCliConfig(projectRoot, mode);
|
|
68
|
-
const extraInfo = extractAdditionalVueConfigInfo(projectRoot);
|
|
69
|
-
|
|
70
|
-
// 4. package.json inflyVite 字段
|
|
71
|
-
const pkgConfig = loadPackageJsonConfig(projectRoot);
|
|
72
|
-
|
|
73
|
-
// 5. infly.vite.config.js / .cjs / .mjs
|
|
74
|
-
const { config: fileConfig, errors: fileErrors } = await loadInflyViteConfig(projectRoot, {
|
|
75
|
-
command, mode, target: resolvedTarget, projectRoot, isBuild, isServe,
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
// 开始合并
|
|
79
|
-
const merged = deepMerge(
|
|
80
|
-
defaults,
|
|
81
|
-
// vue.config.js → 标准字段映射
|
|
82
|
-
{
|
|
83
|
-
base: vueCli.base,
|
|
84
|
-
outputDir: vueCli.outputDir,
|
|
85
|
-
assetsDir: vueCli.assetsDir,
|
|
86
|
-
productionSourceMap: vueCli.productionSourceMap,
|
|
87
|
-
server: {
|
|
88
|
-
port: vueCli.server?.port,
|
|
89
|
-
proxy: vueCli.server?.proxy,
|
|
90
|
-
},
|
|
91
|
-
css: {
|
|
92
|
-
additionalData: vueCli.css?.additionalData,
|
|
93
|
-
},
|
|
94
|
-
resolve: {
|
|
95
|
-
alias: vueCli.resolve?.alias,
|
|
96
|
-
},
|
|
97
|
-
html: {
|
|
98
|
-
title: vueCli.html?.title,
|
|
99
|
-
},
|
|
100
|
-
mock: extraInfo.mockEntry ? {
|
|
101
|
-
enabled: true,
|
|
102
|
-
entry: extraInfo.mockEntry,
|
|
103
|
-
} : undefined,
|
|
104
|
-
},
|
|
105
|
-
// package.json inflyVite
|
|
106
|
-
pkgConfig,
|
|
107
|
-
// infly.vite.config.js
|
|
108
|
-
fileConfig || {},
|
|
109
|
-
// CLI 参数
|
|
110
|
-
{
|
|
111
|
-
context: { target: resolvedTarget },
|
|
112
|
-
server: {
|
|
113
|
-
port: cliOptions.port,
|
|
114
|
-
host: cliOptions.host,
|
|
115
|
-
open: cliOptions.open,
|
|
116
|
-
strictPort: cliOptions.strictPort,
|
|
117
|
-
},
|
|
118
|
-
}
|
|
119
|
-
);
|
|
120
|
-
|
|
121
|
-
// Mock 默认值:serve 且存在 mock 入口时启用
|
|
122
|
-
if (merged.mock.entry) {
|
|
123
|
-
const mockFullPath = path.resolve(projectRoot, merged.mock.entry);
|
|
124
|
-
if (fs.existsSync(mockFullPath)) {
|
|
125
|
-
merged.mock.enabled = merged.mock.enabled !== false && isServe;
|
|
126
|
-
} else if (merged.mock.enabled) {
|
|
127
|
-
// mock 明确启用但文件不存在 → 记录但由 runner 决定
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// 严格兼容性验证
|
|
132
|
-
let validation = { valid: true, errors: [] };
|
|
133
|
-
let diagnoses = [];
|
|
134
|
-
|
|
135
|
-
if (merged.strictCompatibility) {
|
|
136
|
-
validation = validateStrictCompatibility(merged, {
|
|
137
|
-
hasChainWebpack: vueCli.hasChainWebpack,
|
|
138
|
-
hasFunctionConfigureWebpack: vueCli.hasFunctionConfigureWebpack,
|
|
139
|
-
projectRoot,
|
|
140
|
-
targets: Object.keys(fileConfig?.targets || {}),
|
|
141
|
-
});
|
|
142
|
-
} else {
|
|
143
|
-
diagnoses = diagnoseCompatIssues(merged, {
|
|
144
|
-
hasChainWebpack: vueCli.hasChainWebpack,
|
|
145
|
-
hasFunctionConfigureWebpack: vueCli.hasFunctionConfigureWebpack,
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// 路径规范化
|
|
150
|
-
if (merged.outputDir && !path.isAbsolute(merged.outputDir)) {
|
|
151
|
-
merged.outputDir = path.resolve(projectRoot, merged.outputDir);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
return {
|
|
155
|
-
config: merged,
|
|
156
|
-
env: { define, target: resolvedTarget, envVars: {} },
|
|
157
|
-
meta: {
|
|
158
|
-
vueCliWarnings,
|
|
159
|
-
fileErrors,
|
|
160
|
-
validation,
|
|
161
|
-
diagnoses,
|
|
162
|
-
resolvedTarget,
|
|
163
|
-
},
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* 从 package.json 读取 inflyVite 字段
|
|
169
|
-
*/
|
|
170
|
-
function loadPackageJsonConfig(projectRoot) {
|
|
171
|
-
const pkgPath = path.join(projectRoot, 'package.json');
|
|
172
|
-
if (!fs.existsSync(pkgPath)) return {};
|
|
173
|
-
|
|
174
|
-
try {
|
|
175
|
-
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
176
|
-
return pkg.inflyVite || {};
|
|
177
|
-
} catch
|
|
178
|
-
return {};
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* 加载 infly.vite.config.{mjs,js,cjs}
|
|
184
|
-
*
|
|
185
|
-
* @param {string} projectRoot
|
|
186
|
-
* @param {object} context - { command, mode, target, projectRoot, isBuild, isServe }
|
|
187
|
-
* @returns {Promise<{ config: object|null, errors: string[] }>}
|
|
188
|
-
*/
|
|
189
|
-
async function loadInflyViteConfig(projectRoot, context) {
|
|
190
|
-
// 检测多文件冲突
|
|
191
|
-
const found = CONFIG_FILES.filter((name) =>
|
|
192
|
-
fs.existsSync(path.join(projectRoot, name))
|
|
193
|
-
);
|
|
194
|
-
|
|
195
|
-
if (found.length > 1) {
|
|
196
|
-
return {
|
|
197
|
-
config: null,
|
|
198
|
-
errors: [
|
|
199
|
-
`检测到多个 infly.vite.config 文件: ${found.join(', ')}。请只保留一个。`
|
|
200
|
-
],
|
|
201
|
-
};
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
if (found.length === 0) {
|
|
205
|
-
return { config: null, errors: [] };
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const configPath = path.join(projectRoot, found[0]);
|
|
209
|
-
const ext = path.extname(found[0]);
|
|
210
|
-
|
|
211
|
-
try {
|
|
212
|
-
let rawConfig;
|
|
213
|
-
|
|
214
|
-
if (ext === '.mjs') {
|
|
215
|
-
// ESM 动态导入
|
|
216
|
-
const imported = await import(`file://${configPath}`);
|
|
217
|
-
rawConfig = imported.default || imported;
|
|
218
|
-
} else if (ext === '.js' || ext === '.cjs') {
|
|
219
|
-
// CJS require
|
|
220
|
-
const projectRequire = createRequire(path.join(projectRoot, 'package.json'));
|
|
221
|
-
rawConfig = projectRequire(configPath);
|
|
222
|
-
} else {
|
|
223
|
-
return { config: null, errors: [`不支持的配置文件扩展名: ${ext}`] };
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
// 函数形式
|
|
227
|
-
if (typeof rawConfig === 'function') {
|
|
228
|
-
rawConfig = rawConfig(context);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
if (!rawConfig || typeof rawConfig !== 'object') {
|
|
232
|
-
return { config: null, errors: [`${found[0]} 必须导出配置对象或函数`] };
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
return { config: rawConfig, errors: [] };
|
|
236
|
-
} catch (err) {
|
|
237
|
-
return {
|
|
238
|
-
config: null,
|
|
239
|
-
errors: [`无法加载 ${found[0]}: ${err.message}`],
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* 读取 package.json 信息(用于获取项目名称等元数据)
|
|
246
|
-
*/
|
|
247
|
-
export function readProjectMeta(projectRoot) {
|
|
248
|
-
const pkgPath = path.join(projectRoot, 'package.json');
|
|
249
|
-
if (!fs.existsSync(pkgPath)) return { name: 'unknown', version: '0.0.0' };
|
|
250
|
-
|
|
251
|
-
try {
|
|
252
|
-
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
253
|
-
return {
|
|
254
|
-
name: pkg.name || path.basename(projectRoot),
|
|
255
|
-
version: pkg.version || '0.0.0',
|
|
256
|
-
description: pkg.description || '',
|
|
257
|
-
};
|
|
258
|
-
} catch
|
|
259
|
-
return { name: path.basename(projectRoot), version: '0.0.0' };
|
|
260
|
-
}
|
|
261
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* 配置发现编排器
|
|
3
|
+
*
|
|
4
|
+
* 按优先级(从低到高)加载所有配置源并合并:
|
|
5
|
+
* 1. 包安全默认值
|
|
6
|
+
* 2. 项目 vue.config.js 标准字段
|
|
7
|
+
* 3. package.json 的 inflyVite 字段
|
|
8
|
+
* 4. infly.vite.config.js / .cjs / .mjs
|
|
9
|
+
* 5. CLI 参数
|
|
10
|
+
*
|
|
11
|
+
* 规范 §9.1
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import fs from 'node:fs';
|
|
15
|
+
import path from 'node:path';
|
|
16
|
+
import { createRequire } from 'node:module';
|
|
17
|
+
import { createDefaultConfig } from './project-config.mjs';
|
|
18
|
+
import { loadVueCliConfig, extractAdditionalVueConfigInfo } from './vue-cli-reader.mjs';
|
|
19
|
+
import { buildDefine } from './env.mjs';
|
|
20
|
+
import { deepMerge } from './merge.mjs';
|
|
21
|
+
import { validateStrictCompatibility, diagnoseCompatIssues } from './validation.mjs';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* 可选的 infly.vite.config 文件名(按优先级)
|
|
25
|
+
*/
|
|
26
|
+
const CONFIG_FILES = [
|
|
27
|
+
'infly.vite.config.mjs',
|
|
28
|
+
'infly.vite.config.js',
|
|
29
|
+
'infly.vite.config.cjs',
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @param {object} options
|
|
34
|
+
* @param {string} options.command - 'serve' | 'build'
|
|
35
|
+
* @param {string} options.mode - 模式
|
|
36
|
+
* @param {string} [options.target] - CLI target
|
|
37
|
+
* @param {string} options.projectRoot - 项目根目录
|
|
38
|
+
* @param {object} [options.cliOptions] - CLI 额外选项
|
|
39
|
+
* @returns {Promise<object>} 归一化配置 + 元信息
|
|
40
|
+
*/
|
|
41
|
+
export async function discoverConfig(options = {}) {
|
|
42
|
+
const {
|
|
43
|
+
command = 'build',
|
|
44
|
+
mode = 'production',
|
|
45
|
+
target: cliTarget,
|
|
46
|
+
projectRoot = process.cwd(),
|
|
47
|
+
cliOptions = {},
|
|
48
|
+
} = options;
|
|
49
|
+
|
|
50
|
+
// test 命令复用 build 的配置语义(mode=test,读取 .env.test 等)
|
|
51
|
+
const isBuild = command === 'build' || command === 'test';
|
|
52
|
+
const isServe = command === 'serve';
|
|
53
|
+
|
|
54
|
+
// 1. 包默认值
|
|
55
|
+
const defaults = createDefaultConfig({ command, mode, target: cliTarget, projectRoot, isBuild, isServe });
|
|
56
|
+
|
|
57
|
+
// 2. 环境变量(解析 target)
|
|
58
|
+
const { target: envTarget, define } = buildDefine({
|
|
59
|
+
projectRoot,
|
|
60
|
+
mode,
|
|
61
|
+
target: cliTarget,
|
|
62
|
+
defaultTarget: defaults.context.target || 'DEFAULT',
|
|
63
|
+
});
|
|
64
|
+
const resolvedTarget = cliTarget || envTarget || 'DEFAULT';
|
|
65
|
+
|
|
66
|
+
// 3. vue.config.js 标准字段
|
|
67
|
+
const { vueConfig: vueCli, warnings: vueCliWarnings } = loadVueCliConfig(projectRoot, mode);
|
|
68
|
+
const extraInfo = extractAdditionalVueConfigInfo(projectRoot);
|
|
69
|
+
|
|
70
|
+
// 4. package.json inflyVite 字段
|
|
71
|
+
const pkgConfig = loadPackageJsonConfig(projectRoot);
|
|
72
|
+
|
|
73
|
+
// 5. infly.vite.config.js / .cjs / .mjs
|
|
74
|
+
const { config: fileConfig, errors: fileErrors } = await loadInflyViteConfig(projectRoot, {
|
|
75
|
+
command, mode, target: resolvedTarget, projectRoot, isBuild, isServe,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// 开始合并
|
|
79
|
+
const merged = deepMerge(
|
|
80
|
+
defaults,
|
|
81
|
+
// vue.config.js → 标准字段映射
|
|
82
|
+
{
|
|
83
|
+
base: vueCli.base,
|
|
84
|
+
outputDir: vueCli.outputDir,
|
|
85
|
+
assetsDir: vueCli.assetsDir,
|
|
86
|
+
productionSourceMap: vueCli.productionSourceMap,
|
|
87
|
+
server: {
|
|
88
|
+
port: vueCli.server?.port,
|
|
89
|
+
proxy: vueCli.server?.proxy,
|
|
90
|
+
},
|
|
91
|
+
css: {
|
|
92
|
+
additionalData: vueCli.css?.additionalData,
|
|
93
|
+
},
|
|
94
|
+
resolve: {
|
|
95
|
+
alias: vueCli.resolve?.alias,
|
|
96
|
+
},
|
|
97
|
+
html: {
|
|
98
|
+
title: vueCli.html?.title,
|
|
99
|
+
},
|
|
100
|
+
mock: extraInfo.mockEntry ? {
|
|
101
|
+
enabled: true,
|
|
102
|
+
entry: extraInfo.mockEntry,
|
|
103
|
+
} : undefined,
|
|
104
|
+
},
|
|
105
|
+
// package.json inflyVite
|
|
106
|
+
pkgConfig,
|
|
107
|
+
// infly.vite.config.js
|
|
108
|
+
fileConfig || {},
|
|
109
|
+
// CLI 参数
|
|
110
|
+
{
|
|
111
|
+
context: { target: resolvedTarget },
|
|
112
|
+
server: {
|
|
113
|
+
port: cliOptions.port,
|
|
114
|
+
host: cliOptions.host,
|
|
115
|
+
open: cliOptions.open,
|
|
116
|
+
strictPort: cliOptions.strictPort,
|
|
117
|
+
},
|
|
118
|
+
}
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
// Mock 默认值:serve 且存在 mock 入口时启用
|
|
122
|
+
if (merged.mock.entry) {
|
|
123
|
+
const mockFullPath = path.resolve(projectRoot, merged.mock.entry);
|
|
124
|
+
if (fs.existsSync(mockFullPath)) {
|
|
125
|
+
merged.mock.enabled = merged.mock.enabled !== false && isServe;
|
|
126
|
+
} else if (merged.mock.enabled) {
|
|
127
|
+
// mock 明确启用但文件不存在 → 记录但由 runner 决定
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// 严格兼容性验证
|
|
132
|
+
let validation = { valid: true, errors: [] };
|
|
133
|
+
let diagnoses = [];
|
|
134
|
+
|
|
135
|
+
if (merged.strictCompatibility) {
|
|
136
|
+
validation = validateStrictCompatibility(merged, {
|
|
137
|
+
hasChainWebpack: vueCli.hasChainWebpack,
|
|
138
|
+
hasFunctionConfigureWebpack: vueCli.hasFunctionConfigureWebpack,
|
|
139
|
+
projectRoot,
|
|
140
|
+
targets: Object.keys(fileConfig?.targets || {}),
|
|
141
|
+
});
|
|
142
|
+
} else {
|
|
143
|
+
diagnoses = diagnoseCompatIssues(merged, {
|
|
144
|
+
hasChainWebpack: vueCli.hasChainWebpack,
|
|
145
|
+
hasFunctionConfigureWebpack: vueCli.hasFunctionConfigureWebpack,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// 路径规范化
|
|
150
|
+
if (merged.outputDir && !path.isAbsolute(merged.outputDir)) {
|
|
151
|
+
merged.outputDir = path.resolve(projectRoot, merged.outputDir);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return {
|
|
155
|
+
config: merged,
|
|
156
|
+
env: { define, target: resolvedTarget, envVars: {} },
|
|
157
|
+
meta: {
|
|
158
|
+
vueCliWarnings,
|
|
159
|
+
fileErrors,
|
|
160
|
+
validation,
|
|
161
|
+
diagnoses,
|
|
162
|
+
resolvedTarget,
|
|
163
|
+
},
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* 从 package.json 读取 inflyVite 字段
|
|
169
|
+
*/
|
|
170
|
+
function loadPackageJsonConfig(projectRoot) {
|
|
171
|
+
const pkgPath = path.join(projectRoot, 'package.json');
|
|
172
|
+
if (!fs.existsSync(pkgPath)) return {};
|
|
173
|
+
|
|
174
|
+
try {
|
|
175
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
176
|
+
return pkg.inflyVite || {};
|
|
177
|
+
} catch {
|
|
178
|
+
return {};
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* 加载 infly.vite.config.{mjs,js,cjs}
|
|
184
|
+
*
|
|
185
|
+
* @param {string} projectRoot
|
|
186
|
+
* @param {object} context - { command, mode, target, projectRoot, isBuild, isServe }
|
|
187
|
+
* @returns {Promise<{ config: object|null, errors: string[] }>}
|
|
188
|
+
*/
|
|
189
|
+
async function loadInflyViteConfig(projectRoot, context) {
|
|
190
|
+
// 检测多文件冲突
|
|
191
|
+
const found = CONFIG_FILES.filter((name) =>
|
|
192
|
+
fs.existsSync(path.join(projectRoot, name))
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
if (found.length > 1) {
|
|
196
|
+
return {
|
|
197
|
+
config: null,
|
|
198
|
+
errors: [
|
|
199
|
+
`检测到多个 infly.vite.config 文件: ${found.join(', ')}。请只保留一个。`
|
|
200
|
+
],
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (found.length === 0) {
|
|
205
|
+
return { config: null, errors: [] };
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const configPath = path.join(projectRoot, found[0]);
|
|
209
|
+
const ext = path.extname(found[0]);
|
|
210
|
+
|
|
211
|
+
try {
|
|
212
|
+
let rawConfig;
|
|
213
|
+
|
|
214
|
+
if (ext === '.mjs') {
|
|
215
|
+
// ESM 动态导入
|
|
216
|
+
const imported = await import(`file://${configPath}`);
|
|
217
|
+
rawConfig = imported.default || imported;
|
|
218
|
+
} else if (ext === '.js' || ext === '.cjs') {
|
|
219
|
+
// CJS require
|
|
220
|
+
const projectRequire = createRequire(path.join(projectRoot, 'package.json'));
|
|
221
|
+
rawConfig = projectRequire(configPath);
|
|
222
|
+
} else {
|
|
223
|
+
return { config: null, errors: [`不支持的配置文件扩展名: ${ext}`] };
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// 函数形式
|
|
227
|
+
if (typeof rawConfig === 'function') {
|
|
228
|
+
rawConfig = rawConfig(context);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (!rawConfig || typeof rawConfig !== 'object') {
|
|
232
|
+
return { config: null, errors: [`${found[0]} 必须导出配置对象或函数`] };
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return { config: rawConfig, errors: [] };
|
|
236
|
+
} catch (err) {
|
|
237
|
+
return {
|
|
238
|
+
config: null,
|
|
239
|
+
errors: [`无法加载 ${found[0]}: ${err.message}`],
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* 读取 package.json 信息(用于获取项目名称等元数据)
|
|
246
|
+
*/
|
|
247
|
+
export function readProjectMeta(projectRoot) {
|
|
248
|
+
const pkgPath = path.join(projectRoot, 'package.json');
|
|
249
|
+
if (!fs.existsSync(pkgPath)) return { name: 'unknown', version: '0.0.0' };
|
|
250
|
+
|
|
251
|
+
try {
|
|
252
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
253
|
+
return {
|
|
254
|
+
name: pkg.name || path.basename(projectRoot),
|
|
255
|
+
version: pkg.version || '0.0.0',
|
|
256
|
+
description: pkg.description || '',
|
|
257
|
+
};
|
|
258
|
+
} catch {
|
|
259
|
+
return { name: path.basename(projectRoot), version: '0.0.0' };
|
|
260
|
+
}
|
|
261
|
+
}
|
|
@@ -71,7 +71,7 @@ function resolveDependencyForOptimize(requireFn, dependency, workspacePackagesDi
|
|
|
71
71
|
return false;
|
|
72
72
|
}
|
|
73
73
|
return true;
|
|
74
|
-
} catch
|
|
74
|
+
} catch {
|
|
75
75
|
// Optional or currently inactive dependencies remain discoverable at runtime.
|
|
76
76
|
return false;
|
|
77
77
|
}
|
|
@@ -144,7 +144,7 @@ function resolveNestedDependencyAliases(projectRoot) {
|
|
|
144
144
|
find: nestedDependency,
|
|
145
145
|
replacement: path.dirname(packageJsonPath),
|
|
146
146
|
});
|
|
147
|
-
} catch
|
|
147
|
+
} catch {
|
|
148
148
|
// The project does not use this optional compatibility dependency.
|
|
149
149
|
}
|
|
150
150
|
}
|
|
@@ -188,7 +188,7 @@ function resolvePnpmStorePaths(projectRoot) {
|
|
|
188
188
|
const realPath = fs.realpathSync(pnpmStoreLink);
|
|
189
189
|
paths.push(realPath);
|
|
190
190
|
}
|
|
191
|
-
} catch
|
|
191
|
+
} catch {
|
|
192
192
|
// 忽略错误
|
|
193
193
|
}
|
|
194
194
|
|
|
@@ -208,11 +208,11 @@ function resolvePnpmStorePaths(projectRoot) {
|
|
|
208
208
|
const realEntryPath = fs.realpathSync(appRequire.resolve(dependency));
|
|
209
209
|
const storeRoot = findPnpmStoreRoot(realEntryPath);
|
|
210
210
|
if (storeRoot && !paths.includes(storeRoot)) paths.push(storeRoot);
|
|
211
|
-
} catch
|
|
211
|
+
} catch {
|
|
212
212
|
// 未安装或没有可解析入口的依赖不影响其他 store 路径发现。
|
|
213
213
|
}
|
|
214
214
|
}
|
|
215
|
-
} catch
|
|
215
|
+
} catch {
|
|
216
216
|
// 缺失或无效的 package.json 由后续配置流程报告。
|
|
217
217
|
}
|
|
218
218
|
|
|
@@ -261,7 +261,6 @@ function prepareViteHtml(config, projectRoot) {
|
|
|
261
261
|
const {
|
|
262
262
|
htmlTemplate = 'public/index.html',
|
|
263
263
|
mainEntry = 'src/main.js',
|
|
264
|
-
mock = {},
|
|
265
264
|
} = config;
|
|
266
265
|
|
|
267
266
|
const htmlOptions = {
|
|
@@ -320,7 +319,7 @@ export function createViteConfig(config) {
|
|
|
320
319
|
// 构建期在真实 workspace 解析,工厂只组装配置、不在组装期崩溃。
|
|
321
320
|
try {
|
|
322
321
|
return projectRequire.resolve('vue/dist/vue.esm.js');
|
|
323
|
-
} catch
|
|
322
|
+
} catch {
|
|
324
323
|
return 'vue/dist/vue.esm.js';
|
|
325
324
|
}
|
|
326
325
|
})();
|
|
@@ -338,7 +337,7 @@ export function createViteConfig(config) {
|
|
|
338
337
|
try {
|
|
339
338
|
const echartsDir = path.dirname(projectRequire.resolve('echarts'));
|
|
340
339
|
aliases.push({ find: 'echarts', replacement: echartsDir });
|
|
341
|
-
} catch
|
|
340
|
+
} catch {
|
|
342
341
|
// 当前应用未使用 echarts
|
|
343
342
|
}
|
|
344
343
|
|