generator-mico-cli 0.2.23 → 0.2.24

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.
@@ -34,11 +34,21 @@ fi
34
34
  export CDN_PUBLIC_PATH="https://cdn-portal-dev.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/${VERSION}/"
35
35
  echo "CDN_PUBLIC_PATH: $CDN_PUBLIC_PATH"
36
36
 
37
+ # 开发环境,不上传 sourcemap。调试时如有需要再解开
38
+ # # ========== Sentry Auth Token ==========
39
+ # # SENTRY_AUTH_TOKEN 从 Jenkins 服务器文件读取(敏感信息,不写在脚本中)
40
+ # SENTRY_TOKEN_FILE="/var/lib/jenkins/.portal_sentry_auth_token"
41
+ # if [ -f "$SENTRY_TOKEN_FILE" ]; then
42
+ # export SENTRY_AUTH_TOKEN=$(cat "$SENTRY_TOKEN_FILE")
43
+ # fi
44
+
45
+ # if [ -z "$SENTRY_AUTH_TOKEN" ]; then
46
+ # echo "警告:SENTRY_AUTH_TOKEN 未设置(文件 $SENTRY_TOKEN_FILE 不存在),跳过 sourcemap 上传"
47
+ # fi
48
+
37
49
  pnpm run build:development
38
50
 
39
51
  # 只有在 CI 环境时才写入版本号文件(覆盖写入)
40
52
  if [ "${CI}" = "true" ]; then
41
53
  echo "VERSION=$VERSION" > .env_x_<%= projectName %>
42
54
  fi
43
-
44
-
@@ -34,10 +34,20 @@ fi
34
34
  export CDN_PUBLIC_PATH="https://cdn-portal.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/${VERSION}/"
35
35
  echo "CDN_PUBLIC_PATH: $CDN_PUBLIC_PATH"
36
36
 
37
+ # ========== Sentry Auth Token ==========
38
+ # SENTRY_AUTH_TOKEN 从 Jenkins 服务器文件读取(敏感信息,不写在脚本中)
39
+ SENTRY_TOKEN_FILE="/var/lib/jenkins/.portal_sentry_auth_token"
40
+ if [ -f "$SENTRY_TOKEN_FILE" ]; then
41
+ export SENTRY_AUTH_TOKEN=$(cat "$SENTRY_TOKEN_FILE")
42
+ fi
43
+
44
+ if [ -z "$SENTRY_AUTH_TOKEN" ]; then
45
+ echo "警告:SENTRY_AUTH_TOKEN 未设置(文件 $SENTRY_TOKEN_FILE 不存在),跳过 sourcemap 上传"
46
+ fi
47
+
37
48
  pnpm run build:production
38
49
 
39
50
  # 只有在 CI 环境时才写入版本号文件(覆盖写入)
40
51
  if [ "${CI}" = "true" ]; then
41
52
  echo "VERSION=$VERSION" > .env_x_<%= projectName %>
42
53
  fi
43
-
@@ -35,10 +35,21 @@ fi
35
35
  export CDN_PUBLIC_PATH="https://cdn-portal-test.micoplatform.com/<%= cdnPrefixPath %><%= projectName %>/${VERSION}/"
36
36
  echo "CDN_PUBLIC_PATH: $CDN_PUBLIC_PATH"
37
37
 
38
+ # 测试环境,不上传 sourcemap。调试时如有需要再解开
39
+ # # ========== Sentry Auth Token ==========
40
+ # # SENTRY_AUTH_TOKEN 从 Jenkins 服务器文件读取(敏感信息,不写在脚本中)
41
+ # SENTRY_TOKEN_FILE="/var/lib/jenkins/.portal_sentry_auth_token"
42
+ # if [ -f "$SENTRY_TOKEN_FILE" ]; then
43
+ # export SENTRY_AUTH_TOKEN=$(cat "$SENTRY_TOKEN_FILE")
44
+ # fi
45
+
46
+ # if [ -z "$SENTRY_AUTH_TOKEN" ]; then
47
+ # echo "警告:SENTRY_AUTH_TOKEN 未设置(文件 $SENTRY_TOKEN_FILE 不存在),跳过 sourcemap 上传"
48
+ # fi
49
+
38
50
  pnpm run build:testing
39
51
 
40
52
  # 只有在 CI 环境时才写入版本号文件(覆盖写入)
41
53
  if [ "${CI}" = "true" ]; then
42
54
  echo "VERSION=$VERSION" > .env_x_<%= projectName %>
43
55
  fi
44
-
@@ -1,8 +1,19 @@
1
1
  // https://umijs.org/config/
2
2
 
3
3
  import { defineConfig } from '@umijs/max';
4
+ // 开发环境,不上传 sourcemap。调试时如有需要再解开
5
+ // import { applySentryPlugin } from "../../../scripts/apply-sentry-plugin";
4
6
 
5
7
  const config: ReturnType<typeof defineConfig> = {
8
+ // 开发环境,不上传 sourcemap。调试时如有需要再解开
9
+ // devtool: 'hidden-source-map',
10
+
11
+ // chainWebpack(memo) {
12
+ // // 开发环境,不上传 sourcemap。调试时如有需要再解开
13
+ // applySentryPlugin({ memo, appName: 'layout' });
14
+ // return memo;
15
+ // },
16
+
6
17
  externals: {
7
18
  react: 'React',
8
19
  'react-dom': 'ReactDOM',
@@ -1,8 +1,19 @@
1
1
  // https://umijs.org/config/
2
2
 
3
3
  import { defineConfig } from '@umijs/max';
4
+ // 测试环境,不上传 sourcemap。调试时如有需要再解开
5
+ // import { applySentryPlugin } from "../../../scripts/apply-sentry-plugin";
4
6
 
5
7
  const config: ReturnType<typeof defineConfig> = {
8
+ // 测试环境,不上传 sourcemap。调试时如有需要再解开
9
+ // devtool: 'hidden-source-map',
10
+
11
+ // chainWebpack(memo) {
12
+ // // 测试环境,不上传 sourcemap。调试时如有需要再解开
13
+ // applySentryPlugin({ memo, appName: 'layout' });
14
+ // return memo;
15
+ // },
16
+
6
17
  externals: {
7
18
  react: 'React',
8
19
  'react-dom': 'ReactDOM',
@@ -32,7 +32,6 @@
32
32
  "spark-md5": "^3.0.2"
33
33
  },
34
34
  "devDependencies": {
35
- "@common-web/sentry": "^0.0.3",
36
35
  "@types/react": "^18.0.33",
37
36
  "@types/react-dom": "^18.0.11",
38
37
  "@types/spark-md5": "^3.0.5",
@@ -341,6 +341,10 @@ export const parseMenuItems = (items: MenuItem[]): ParsedMenuItem[] => {
341
341
  });
342
342
  };
343
343
 
344
+ /** 去除尾部斜杠(根路径 "/" 保持不变) */
345
+ const stripTrailingSlash = (path: string): string =>
346
+ path.length > 1 && path.endsWith('/') ? path.slice(0, -1) : path;
347
+
344
348
  /**
345
349
  * 根据路径查找对应的路由配置
346
350
  */
@@ -348,18 +352,19 @@ export const findRouteByPath = (
348
352
  routes: ParsedRoute[],
349
353
  pathname: string,
350
354
  ): ParsedRoute | undefined => {
355
+ const normalizedPathname = stripTrailingSlash(pathname);
351
356
  let exact: ParsedRoute | undefined;
352
357
  let bestWildcard: { route: ParsedRoute; basePath: string } | undefined;
353
358
 
354
359
  for (const route of routes) {
355
- if (route.path === pathname) {
360
+ if (stripTrailingSlash(route.path) === normalizedPathname) {
356
361
  exact = route;
357
362
  continue;
358
363
  }
359
364
 
360
365
  if (route.path.endsWith('/*')) {
361
366
  const basePath = route.path.slice(0, -2);
362
- if (pathname === basePath || pathname.startsWith(`${basePath}/`)) {
367
+ if (normalizedPathname === basePath || normalizedPathname.startsWith(`${basePath}/`)) {
363
368
  if (!bestWildcard || basePath.length > bestWildcard.basePath.length) {
364
369
  bestWildcard = { route, basePath };
365
370
  }
@@ -164,7 +164,7 @@ export const initDefaultInterceptors = (
164
164
  return data;
165
165
  });
166
166
 
167
- // 处理业务错误码
167
+ // 处理业务错误码({ result: { code, desc } } 格式)
168
168
  addResponseInterceptor(async (data: unknown) => {
169
169
  if (data && typeof data === 'object' && 'result' in data) {
170
170
  const typedData = data as { result?: { code?: number; desc?: string } };
@@ -183,4 +183,32 @@ export const initDefaultInterceptors = (
183
183
  }
184
184
  return data;
185
185
  });
186
+
187
+
188
+ // 处理业务错误码({ code, msg, data } 格式)
189
+ addResponseInterceptor(async (data: unknown) => {
190
+ if (
191
+ data &&
192
+ typeof data === 'object' &&
193
+ 'code' in data &&
194
+ !('result' in data) &&
195
+ !('success' in data)
196
+ ) {
197
+ const typedData = data as { code?: number; msg?: string };
198
+ if (typeof typedData.code === 'number' && typedData.code !== 200) {
199
+ const error = new Error(
200
+ typedData.msg || `请求失败 (${typedData.code})`,
201
+ ) as Error & {
202
+ code: number;
203
+ msg: string;
204
+ response: unknown;
205
+ };
206
+ error.code = typedData.code;
207
+ error.msg = typedData.msg || '';
208
+ error.response = data;
209
+ throw error;
210
+ }
211
+ }
212
+ return data;
213
+ });
186
214
  };
@@ -32,6 +32,7 @@
32
32
  "devDependencies": {
33
33
  "@commitlint/cli": "^19.5.0",
34
34
  "@commitlint/config-conventional": "^19.5.0",
35
+ "@common-web/sentry": "^0.0.4",
35
36
  "@sentry/webpack-plugin": "^4.9.1",
36
37
  "@typescript-eslint/eslint-plugin": "^8.54.0",
37
38
  "@typescript-eslint/parser": "^8.54.0",
@@ -32,7 +32,7 @@ export function applySentryPlugin({
32
32
  name: version,
33
33
  uploadLegacySourcemaps: {
34
34
  paths: ['./dist'],
35
- urlPrefix: `~/portal-center/<%= projectName %>/${version}/${appName}`,
35
+ urlPrefix: `~/<%= cdnPrefixPath %><%= projectName %>/${version}/${appName}`,
36
36
  },
37
37
  },
38
38
  sourcemaps: {
@@ -48,6 +48,16 @@ async function collectDist() {
48
48
 
49
49
  // 移动 dist 目录到目标位置
50
50
  await fs.rename(appDistPath, targetDistPath);
51
+
52
+ // 删除 .map 文件(sourcemap 已由 webpack 插件上传到 Sentry,无需部署到 CDN)
53
+ const files = await fs.readdir(targetDistPath);
54
+ for (const file of files) {
55
+ if (file.endsWith('.map')) {
56
+ await fs.unlink(path.join(targetDistPath, file));
57
+ console.log(` 🗑 已删除 sourcemap: ${appName}/${file}`);
58
+ }
59
+ }
60
+
51
61
  console.log(`✓ ${appName}: apps/${appName}/dist -> dist/${appName}/`);
52
62
  } catch (error) {
53
63
  if (error.code === 'ENOENT') {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://turbo.build/schema.json",
3
- "globalEnv": ["CDN_PUBLIC_PATH"],
3
+ "globalEnv": ["CDN_PUBLIC_PATH", "SENTRY_AUTH_TOKEN"],
4
4
  "tasks": {
5
5
  "build": {
6
6
  "dependsOn": ["^build"],
@@ -1,8 +1,13 @@
1
1
  // https://umijs.org/config/
2
2
 
3
3
  import { defineConfig } from '@umijs/max';
4
+ // 开发环境,不上传 sourcemap。调试时如有需要再解开
5
+ // import { applySentryPlugin } from "../../../scripts/apply-sentry-plugin";
4
6
 
5
7
  const config: ReturnType<typeof defineConfig> = {
8
+ // 开发环境,不上传 sourcemap。调试时如有需要再解开
9
+ // devtool: 'hidden-source-map',
10
+
6
11
  // 测试环境:将所有代码打包到一个文件
7
12
  extraBabelPlugins: ['babel-plugin-dynamic-import-node'],
8
13
 
@@ -12,6 +17,8 @@ const config: ReturnType<typeof defineConfig> = {
12
17
  memo.optimization.splitChunks(false);
13
18
  // 禁用 runtimeChunk
14
19
  memo.optimization.runtimeChunk(false);
20
+ // 开发环境,不上传 sourcemap。调试时如有需要再解开
21
+ // applySentryPlugin({ memo, appName: '<%= appName %>' });
15
22
  return memo;
16
23
  },
17
24
 
@@ -1,8 +1,13 @@
1
1
  // https://umijs.org/config/
2
2
 
3
3
  import { defineConfig } from '@umijs/max';
4
+ // 测试环境,不上传 sourcemap。调试时如有需要再解开
5
+ // import { applySentryPlugin } from "../../../scripts/apply-sentry-plugin";
4
6
 
5
7
  const config: ReturnType<typeof defineConfig> = {
8
+ // 测试环境,不上传 sourcemap。调试时如有需要再解开
9
+ // devtool: 'hidden-source-map',
10
+
6
11
  // 测试环境:将所有代码打包到一个文件
7
12
  extraBabelPlugins: ['babel-plugin-dynamic-import-node'],
8
13
 
@@ -12,6 +17,8 @@ const config: ReturnType<typeof defineConfig> = {
12
17
  memo.optimization.splitChunks(false);
13
18
  // 禁用 runtimeChunk
14
19
  memo.optimization.runtimeChunk(false);
20
+ // 测试环境,不上传 sourcemap。调试时如有需要再解开
21
+ // applySentryPlugin({ memo, appName: '<%= appName %>' });
15
22
  return memo;
16
23
  },
17
24
 
@@ -15,13 +15,13 @@
15
15
  "start": "npm run dev"
16
16
  },
17
17
  "dependencies": {
18
+ "@mico-platform/ui": "<%= micoUiVersion %>",
18
19
  "@mico-platform/theme": "<%= themeVersion %>",
19
20
  "@umijs/max": "^4.4.8",
20
21
  "react": "^18.2.0",
21
22
  "react-dom": "^18.2.0"
22
23
  },
23
24
  "devDependencies": {
24
- "@common-web/sentry": "^0.0.3",
25
25
  "@mico-platform/ui": "<%= micoUiVersion %>",
26
26
  "@types/react": "^18.0.33",
27
27
  "@types/react-dom": "^18.0.11",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "generator-mico-cli",
3
- "version": "0.2.23",
3
+ "version": "0.2.24",
4
4
  "description": "Yeoman generator for Mico CLI projects",
5
5
  "keywords": ["yeoman-generator", "generator", "cli"],
6
6
  "license": "MIT",