@bams-app/ui-dev-server 0.1.3 → 0.1.5
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/package.json +2 -4
- package/src/main.js +1 -1
- package/utils.js +1 -209
- package/vue.config.base.js +2 -2
- package/config-utils.js +0 -105
- package/empty-entry.js +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bams-app/ui-dev-server",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"serve": "node ./bin/ui-dev-server.js",
|
|
6
6
|
"build": "vue-cli-service build",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"@bams-app/components": "^0.1.3",
|
|
18
18
|
"@bams-app/composition-api": "^0.1.3",
|
|
19
19
|
"@bams-app/config": "^0.1.3",
|
|
20
|
-
"@bams-app/configs": "^0.1.
|
|
20
|
+
"@bams-app/configs": "^0.1.4",
|
|
21
21
|
"@bams-app/data-dict": "^0.1.3",
|
|
22
22
|
"@bams-app/global-data": "^0.1.3",
|
|
23
23
|
"@bams-app/i18n": "^0.1.3",
|
|
@@ -72,8 +72,6 @@
|
|
|
72
72
|
"src/",
|
|
73
73
|
"public/",
|
|
74
74
|
"utils.js",
|
|
75
|
-
"config-utils.js",
|
|
76
|
-
"empty-entry.js",
|
|
77
75
|
"vue.config.js",
|
|
78
76
|
"vue.config.base.js",
|
|
79
77
|
"vue.config.dev.js",
|
package/src/main.js
CHANGED
package/utils.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
2
|
const fs = require('fs');
|
|
3
|
+
const { parseScopesFromWorkspaces, getWorkspaceEntries, createCandidate, findComponentCandidates, getComponentScope, resolveComponent } = require('@bams-app/configs/resolve-component');
|
|
3
4
|
|
|
4
5
|
/** 启用颜色输出的条件 */
|
|
5
6
|
const ENABLE_COLOR = process.stdout.isTTY && process.env.NO_COLOR === undefined;
|
|
@@ -35,215 +36,6 @@ function getProjectPackageJson(rootDir) {
|
|
|
35
36
|
return require(path.join(projectDir, 'package.json'));
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
/**
|
|
39
|
-
* 判断目标路径是否为目录
|
|
40
|
-
* @param {string} targetPath - 目标路径
|
|
41
|
-
* @returns {boolean} 是否为目录
|
|
42
|
-
*/
|
|
43
|
-
function isDirectory(targetPath) {
|
|
44
|
-
return fs.existsSync(targetPath) && fs.statSync(targetPath).isDirectory();
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* 标准化路径用于显示(统一使用 / 分隔符)
|
|
49
|
-
* @param {string} targetPath - 目标路径
|
|
50
|
-
* @returns {string} 标准化后的路径
|
|
51
|
-
*/
|
|
52
|
-
function normalizePathForDisplay(targetPath) {
|
|
53
|
-
return targetPath.split(path.sep).join('/');
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* 将目录名添加到 scope 映射中
|
|
58
|
-
* @param {Object} scopes - scope 到目录的映射
|
|
59
|
-
* @param {string} dirName - 目录名
|
|
60
|
-
*/
|
|
61
|
-
function addScopeDir(scopes, dirName) {
|
|
62
|
-
// 排除不是 ui 相关的目录
|
|
63
|
-
if (['work', 'bams-components', 'bams-ui'].includes(dirName)) {
|
|
64
|
-
if (!scopes['bams-app']) scopes['bams-app'] = [];
|
|
65
|
-
if (!scopes['bams-app'].includes(dirName)) {
|
|
66
|
-
scopes['bams-app'].push(dirName);
|
|
67
|
-
}
|
|
68
|
-
} else {
|
|
69
|
-
// 其他目录用目录名作为 scope
|
|
70
|
-
if (!scopes[dirName]) scopes[dirName] = [];
|
|
71
|
-
if (!scopes[dirName].includes(dirName)) {
|
|
72
|
-
scopes[dirName].push(dirName);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* 从项目根目录查找 -ui 结尾的目录并补充到 scope 映射
|
|
79
|
-
* @param {Object} scopes - scope 到目录的映射
|
|
80
|
-
* @param {string} rootDir - 项目根目录
|
|
81
|
-
*/
|
|
82
|
-
function appendUiDirsFromRoot(scopes, rootDir) {
|
|
83
|
-
if (!rootDir || !isDirectory(rootDir)) {
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const dirEntries = fs.readdirSync(rootDir, { withFileTypes: true });
|
|
88
|
-
dirEntries.forEach((entry) => {
|
|
89
|
-
if (!entry.isDirectory() || !entry.name.endsWith('-ui')) {
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
addScopeDir(scopes, entry.name);
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* 从 workspaces 配置中解析出 scope 和目录映射
|
|
99
|
-
* @param {Object} packageJson - package.json 对象
|
|
100
|
-
* @param {string} rootDir - 项目根目录
|
|
101
|
-
* @returns {Object} scope 到目录的映射
|
|
102
|
-
*/
|
|
103
|
-
function parseScopesFromWorkspaces(packageJson, rootDir) {
|
|
104
|
-
const workspaces = packageJson.workspaces || [];
|
|
105
|
-
const scopes = {};
|
|
106
|
-
|
|
107
|
-
workspaces.forEach(pattern => {
|
|
108
|
-
// 跳过排除项
|
|
109
|
-
if (pattern.startsWith('!')) return;
|
|
110
|
-
|
|
111
|
-
// 处理类似 "pds-ui/*" 或 "pds-ui" 这样的模式
|
|
112
|
-
const match = pattern.match(/^([^/*]+)(\/\*)?$/);
|
|
113
|
-
if (match) {
|
|
114
|
-
addScopeDir(scopes, match[1]);
|
|
115
|
-
}
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
appendUiDirsFromRoot(scopes, rootDir);
|
|
119
|
-
|
|
120
|
-
// 默认总是包含 bams-app 的 fallback
|
|
121
|
-
if (!scopes['bams-app']) scopes['bams-app'] = [];
|
|
122
|
-
if (!scopes['bams-app'].includes('work/packages')) {
|
|
123
|
-
scopes['bams-app'].push('work/packages');
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
return scopes;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* 获取所有 workspace 条目
|
|
131
|
-
* @param {Object} packageJson - package.json 对象
|
|
132
|
-
* @param {string} rootDir - 项目根目录
|
|
133
|
-
* @returns {Array<{scope: string, dir: string}>} workspace 条目列表
|
|
134
|
-
*/
|
|
135
|
-
function getWorkspaceEntries(packageJson, rootDir) {
|
|
136
|
-
const scopes = parseScopesFromWorkspaces(packageJson, rootDir);
|
|
137
|
-
const entries = [];
|
|
138
|
-
|
|
139
|
-
for (const [scope, dirs] of Object.entries(scopes)) {
|
|
140
|
-
for (const dir of dirs) {
|
|
141
|
-
entries.push({ scope, dir });
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
return entries;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* 创建组件候选对象
|
|
150
|
-
* @param {string} scope - scope 名称
|
|
151
|
-
* @param {string} dir - 目录路径
|
|
152
|
-
* @param {string} componentDirName - 组件目录名
|
|
153
|
-
* @param {string} componentPath - 组件完整路径
|
|
154
|
-
* @param {string} requestedName - 用户请求的原始组件名
|
|
155
|
-
* @returns {Object} 组件候选对象
|
|
156
|
-
*/
|
|
157
|
-
function createCandidate(scope, dir, componentDirName, componentPath, requestedName) {
|
|
158
|
-
return {
|
|
159
|
-
scope,
|
|
160
|
-
dir,
|
|
161
|
-
requestedName,
|
|
162
|
-
componentDirName,
|
|
163
|
-
componentPath,
|
|
164
|
-
packageName: `@${scope}/${componentDirName}`,
|
|
165
|
-
displayPath: normalizePathForDisplay(path.join(dir, componentDirName))
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* 根据组件名在所有 workspaces 中查找候选组件
|
|
171
|
-
* @param {string} componentName - 组件名
|
|
172
|
-
* @param {string} rootDir - 项目根目录
|
|
173
|
-
* @param {Object} packageJson - package.json 对象
|
|
174
|
-
* @returns {Array<Object>} 组件候选列表
|
|
175
|
-
*/
|
|
176
|
-
function findComponentCandidates(componentName, rootDir, packageJson) {
|
|
177
|
-
const candidates = [];
|
|
178
|
-
const seen = new Set();
|
|
179
|
-
const searchNames = [componentName];
|
|
180
|
-
|
|
181
|
-
// 如果没有前缀,自动尝试添加 ui- 和 page- 前缀
|
|
182
|
-
if (!componentName.startsWith('ui-') && !componentName.startsWith('page-')) {
|
|
183
|
-
searchNames.push(`ui-${componentName}`, `page-${componentName}`);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
for (const { scope, dir } of getWorkspaceEntries(packageJson, rootDir)) {
|
|
187
|
-
for (const searchName of searchNames) {
|
|
188
|
-
const componentPath = path.resolve(rootDir, dir, searchName);
|
|
189
|
-
|
|
190
|
-
// 跳过不存在或不是目录的路径
|
|
191
|
-
if (!isDirectory(componentPath)) {
|
|
192
|
-
continue;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
const packageName = `@${scope}/${searchName}`;
|
|
196
|
-
// 跳过重复的 packageName
|
|
197
|
-
if (seen.has(packageName)) {
|
|
198
|
-
continue;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
seen.add(packageName);
|
|
202
|
-
candidates.push(createCandidate(scope, dir, searchName, componentPath, componentName));
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
return candidates;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* 根据 componentName 自动识别作用域
|
|
211
|
-
* @param {string} componentName - 组件名
|
|
212
|
-
* @param {string} rootDir - 根目录路径
|
|
213
|
-
* @param {Object} packageJson - package.json 对象
|
|
214
|
-
* @returns {string} 完整的包名
|
|
215
|
-
*/
|
|
216
|
-
function getComponentScope(componentName, rootDir, packageJson) {
|
|
217
|
-
const candidates = findComponentCandidates(componentName, rootDir, packageJson);
|
|
218
|
-
|
|
219
|
-
if (candidates.length > 0) {
|
|
220
|
-
return candidates[0].packageName;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// 默认回退到 bams-app
|
|
224
|
-
return `@bams-app/${componentName}`;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* 解析组件名,返回完整的包名或路径
|
|
229
|
-
* @param {string} componentName - 组件名
|
|
230
|
-
* @param {string} rootDir - 根目录路径
|
|
231
|
-
* @param {Object} packageJson - package.json 对象
|
|
232
|
-
* @returns {string} 完整的包名或路径
|
|
233
|
-
*/
|
|
234
|
-
function resolveComponent(componentName, rootDir, packageJson) {
|
|
235
|
-
// 优先识别完整包名(以 @ 开头)
|
|
236
|
-
if (componentName.startsWith('@')) {
|
|
237
|
-
return componentName;
|
|
238
|
-
}
|
|
239
|
-
// 再识别路径(包含 / 但不是包名)
|
|
240
|
-
if (componentName.includes('/')) {
|
|
241
|
-
return path.resolve(rootDir, componentName);
|
|
242
|
-
}
|
|
243
|
-
// 最后尝试自动识别 scope
|
|
244
|
-
return getComponentScope(componentName, rootDir, packageJson);
|
|
245
|
-
}
|
|
246
|
-
|
|
247
39
|
/**
|
|
248
40
|
* 解析 dev/build 时 @target-component 别名实际指向的组件目录
|
|
249
41
|
* - 完整包名(@scope/name):在候选中按 packageName 精确匹配,避免同名组件始终落到第一个
|
package/vue.config.base.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
|
-
const { merge, applyCommonConfig } = require('
|
|
3
|
+
const { merge, applyCommonConfig } = require('@bams-app/configs/config-utils');
|
|
4
4
|
const { getRootDir, getProjectPackageJson } = require('./utils');
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -92,7 +92,7 @@ function getBaseConfig(options = {}) {
|
|
|
92
92
|
modules: ['node_modules', path.resolve(rootDir, 'node_modules')],
|
|
93
93
|
alias: {
|
|
94
94
|
// 设置别名,如果文件不存在则指向空文件,保证编译不报错
|
|
95
|
-
'@components-entry': hasComponentsEntry ? componentsEntryPath :
|
|
95
|
+
'@components-entry': hasComponentsEntry ? componentsEntryPath : require.resolve('@bams-app/configs/empty-entry.js'),
|
|
96
96
|
...commonContext.aliases,
|
|
97
97
|
},
|
|
98
98
|
},
|
package/config-utils.js
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
const { resolveComponent } = require("./utils");
|
|
2
|
-
const globalComponentDefaults = require("@bams-app/configs/component-defaults.js");
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* 简单的深度合并对象
|
|
6
|
-
* @param {Object} target 目标对象
|
|
7
|
-
* @param {...Object} sources 源对象
|
|
8
|
-
* @returns {Object} 合并后的对象
|
|
9
|
-
*/
|
|
10
|
-
function merge(target, ...sources) {
|
|
11
|
-
if (!sources.length) return target;
|
|
12
|
-
const source = sources.shift();
|
|
13
|
-
|
|
14
|
-
if (source !== undefined && source !== null) {
|
|
15
|
-
Object.keys(source).forEach(key => {
|
|
16
|
-
const targetValue = target[key];
|
|
17
|
-
const sourceValue = source[key];
|
|
18
|
-
|
|
19
|
-
if (Array.isArray(targetValue) && Array.isArray(sourceValue)) {
|
|
20
|
-
target[key] = targetValue.concat(sourceValue);
|
|
21
|
-
} else if (typeof targetValue === 'object' && targetValue !== null &&
|
|
22
|
-
typeof sourceValue === 'object' && sourceValue !== null &&
|
|
23
|
-
!Array.isArray(sourceValue)) {
|
|
24
|
-
target[key] = merge({ ...targetValue }, sourceValue);
|
|
25
|
-
} else {
|
|
26
|
-
target[key] = sourceValue;
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return merge(target, ...sources);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* 将环境变量名转换为可配置插槽名
|
|
36
|
-
* @param {string} envKey 环境变量名
|
|
37
|
-
* @returns {string} 插槽名,如 login、home-card
|
|
38
|
-
*/
|
|
39
|
-
function normalizeConfigurableSlotName(envKey) {
|
|
40
|
-
return envKey
|
|
41
|
-
.replace(/^(VUE_APP_COMPONENT_|COMPONENT_)/, "")
|
|
42
|
-
.toLowerCase()
|
|
43
|
-
.replace(/_/g, "-");
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* 根据环境变量和默认值生成可配置组件 alias
|
|
48
|
-
* @param {Object} options 配置项
|
|
49
|
-
* @param {Object} options.env 环境变量对象
|
|
50
|
-
* @param {string} options.rootDir 项目根目录
|
|
51
|
-
* @param {Object} options.packageJson 根 package.json
|
|
52
|
-
* @param {Object} [options.defaults] 额外默认插槽组件映射,会覆盖全局默认值
|
|
53
|
-
* @returns {Object} webpack alias 对象
|
|
54
|
-
*/
|
|
55
|
-
function getConfigurableComponentAliases({ env, rootDir, packageJson, defaults = {} }) {
|
|
56
|
-
const slotToComponent = { ...globalComponentDefaults, ...defaults };
|
|
57
|
-
|
|
58
|
-
Object.entries(env).forEach(([key, value]) => {
|
|
59
|
-
if (!/^(VUE_APP_COMPONENT_|COMPONENT_).+$/.test(key) || !value) {
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
slotToComponent[normalizeConfigurableSlotName(key)] = value;
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
return Object.entries(slotToComponent).reduce((aliases, [slotName, componentName]) => {
|
|
67
|
-
aliases[`@configurable/${slotName}`] = resolveComponent(componentName, rootDir, packageJson);
|
|
68
|
-
return aliases;
|
|
69
|
-
}, {});
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* 生成通用的 webpack alias 片段,包含所有可配置组件插槽
|
|
74
|
-
* @param {Object} [options]
|
|
75
|
-
* @param {string} options.rootDir 项目根目录
|
|
76
|
-
* @param {Object} [options.env=process.env] 环境变量对象
|
|
77
|
-
* @param {Object} options.packageJson 根 package.json
|
|
78
|
-
* @param {Object} [options.defaults] 额外默认插槽组件映射
|
|
79
|
-
* @returns {{rootDir: string, packageJson: object, aliases: Object}}
|
|
80
|
-
*/
|
|
81
|
-
function applyCommonConfig(options = {}) {
|
|
82
|
-
const { rootDir, env = process.env, packageJson, defaults } = options;
|
|
83
|
-
|
|
84
|
-
if (!rootDir || !packageJson) {
|
|
85
|
-
throw new Error("applyCommonConfig requires rootDir and packageJson");
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const configurableAliases = getConfigurableComponentAliases({
|
|
89
|
-
env,
|
|
90
|
-
rootDir,
|
|
91
|
-
packageJson,
|
|
92
|
-
defaults
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
return {
|
|
96
|
-
rootDir,
|
|
97
|
-
packageJson,
|
|
98
|
-
aliases: configurableAliases
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
module.exports = {
|
|
103
|
-
merge,
|
|
104
|
-
applyCommonConfig
|
|
105
|
-
};
|
package/empty-entry.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { };
|