wyt-cli 1.0.11 → 1.0.13

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.
@@ -12,6 +12,8 @@ import ora from 'ora';
12
12
  import inquirer from 'inquirer';
13
13
  import ejs from 'ejs';
14
14
 
15
+ import { checkTargetDir } from '../lib/dir.js';
16
+
15
17
  const spinner = ora();
16
18
  // 命令配置
17
19
  export default function () {
@@ -117,21 +119,6 @@ function createAction(projectName, options) {
117
119
  }
118
120
  }
119
121
 
120
- // 检查目标目录是否存在
121
- function checkTargetDir(currentPath) {
122
- const monoDirs = ['apps', 'packages'];
123
- const conflictDirs = monoDirs
124
- .map((dir) => ({
125
- name: dir,
126
- path: path.join(currentPath, dir),
127
- exists: fs.existsSync(path.join(currentPath, dir)),
128
- }))
129
- .filter((item) => item.exists)
130
- .map((item) => item.name);
131
-
132
- return conflictDirs.join(',') == monoDirs.join(',');
133
- }
134
-
135
122
  // 创建项目
136
123
  async function createProject(projectName, options) {
137
124
  const files = await glob('./wyt-cli/bin/templates/**/*', {
@@ -0,0 +1,135 @@
1
+ import path from 'path';
2
+ import { execa } from 'execa';
3
+ import { Command } from 'commander';
4
+ import fs from 'fs-extra';
5
+ import ora from 'ora';
6
+ import inquirer from 'inquirer';
7
+ import {
8
+ log_info,
9
+ log_error,
10
+ log_success,
11
+ getFormatTimeText,
12
+ getUnderlineText,
13
+ getInquirerOperationText,
14
+ } from '../lib/logger.js';
15
+ import { checkTargetDir, getProjects } from '../lib/dir.js';
16
+
17
+ const SYSTEM_DEPLOY_DIR = path.resolve('/', '.hrp3_deploy'); // 系统级部署目录
18
+ const startTime = Date.now(); // 计时器
19
+
20
+ export default function () {
21
+ const command = new Command('deploy');
22
+
23
+ command.description('项目部署命令').action(async () => {
24
+ try {
25
+ // 校验项目目录
26
+ if (!checkTargetDir(process.cwd())) {
27
+ log_error('请在 HRP3.0 项目根目录运行此命令!');
28
+ return;
29
+ }
30
+
31
+ // 项目根目录
32
+ const appsDir = path.resolve(process.cwd(), 'apps');
33
+
34
+ // 获取项目列表
35
+ const projects = await getProjects(appsDir);
36
+
37
+ // 交互选择项目
38
+ const answer = await inquirer.prompt([
39
+ {
40
+ type: 'rawlist',
41
+ name: 'deploystyle',
42
+ message: `请选择部署项目的方式:` + getInquirerOperationText('list'),
43
+ default: 0,
44
+ choices: [
45
+ { name: '方式1:部署所有项目', value: 0 },
46
+ { name: '方式2:部署指定项目', value: 1 },
47
+ ],
48
+ },
49
+ {
50
+ type: 'checkbox',
51
+ name: 'project',
52
+ message: '请选择要部署的项目:' + getInquirerOperationText('checkbox'),
53
+ when: (answers) => answers.deploystyle == 1,
54
+ choices: projects.map((p) => ({
55
+ name: p.name,
56
+ })),
57
+ },
58
+ ]);
59
+
60
+ // 准备部署目录
61
+ await initDeployDir();
62
+
63
+ // 构建并部署
64
+ if (answer.deploystyle === 0) {
65
+ await buildAndDeploy(projects.map((p) => p.name));
66
+ }
67
+
68
+ if (answer.deploystyle === 1 && answer.project) {
69
+ await buildAndDeploy(answer.project);
70
+ }
71
+ } catch (error) {
72
+ log_error(`部署失败: ${error.message}`);
73
+ process.exit(1);
74
+ }
75
+ });
76
+
77
+ return command;
78
+ }
79
+
80
+ // 初始化部署目录
81
+ async function initDeployDir() {
82
+ const spinner = ora('正在初始化部署环境').start();
83
+ try {
84
+ if (!fs.existsSync(SYSTEM_DEPLOY_DIR)) {
85
+ spinner.text = '正在读取项目配置';
86
+ const { deployRepo } = await fs.readJSON(path.join(process.cwd(), 'project.json'));
87
+
88
+ spinner.text = '首次部署,正在克隆远程仓库,请耐心等待...';
89
+ await execa('git', ['clone', deployRepo, SYSTEM_DEPLOY_DIR]);
90
+
91
+ spinner.succeed(`仓库初始化完成(耗时:${getFormatTimeText(Date.now() - startTime)})`);
92
+ log_info(`📁 系统部署目录已创建于:${getUnderlineText(SYSTEM_DEPLOY_DIR)}`);
93
+ } else {
94
+ spinner.text = '正在更新已有仓库';
95
+ await execa('git', ['-C', SYSTEM_DEPLOY_DIR, 'pull']);
96
+ spinner.succeed(`代码更新完成(耗时:${getFormatTimeText(Date.now() - startTime)})`);
97
+ log_info(`📁 系统部署目录更新于::${getUnderlineText(SYSTEM_DEPLOY_DIR)}`);
98
+ }
99
+ } catch (error) {
100
+ spinner.fail('初始化失败');
101
+ throw new Error(`初始化失败: ${error.stderr}`);
102
+ }
103
+ }
104
+
105
+ // 构建部署流程
106
+ async function buildAndDeploy(deployProjects) {
107
+ try {
108
+ // 批量部署执行器
109
+ const total_timer = Date.now();
110
+ for (const project of deployProjects) {
111
+ const timer = Date.now();
112
+ log_info(`🚀 开始部署项目 ${project}`);
113
+ // 动态构建命令
114
+ await execa('npm', ['run', 'build'], {
115
+ stdio: 'inherit',
116
+ cwd: path.resolve(process.cwd(), 'apps', project),
117
+ });
118
+ // 文件同步
119
+ const distPath = path.resolve(process.cwd(), 'dist', project);
120
+ const targetPath = path.resolve(SYSTEM_DEPLOY_DIR, 'dist', project);
121
+ fs.emptyDirSync(targetPath);
122
+ fs.copySync(distPath, targetPath);
123
+ log_info(`⏱ 构建${project}耗时: ${getFormatTimeText(Date.now() - timer)}`);
124
+ }
125
+ log_info(`⏱ 构建总耗时: ${getFormatTimeText(Date.now() - total_timer)}`);
126
+ await execa('git', ['-C', SYSTEM_DEPLOY_DIR, 'add', '.']);
127
+ await execa('git', ['-C', SYSTEM_DEPLOY_DIR, 'commit', '-m', 'chore: auto deploy']);
128
+ await execa('git', ['-C', SYSTEM_DEPLOY_DIR, 'push']);
129
+
130
+ const { apiUrl } = await fs.readJSON(path.join(process.cwd(), 'project.json'));
131
+ log_success(`✅ 成功部署 ${deployProjects.length} 个项目!请移步 ${apiUrl} 自行检测。`);
132
+ } catch (error) {
133
+ throw new Error(`部署流程异常: ${error.message}`);
134
+ }
135
+ }
@@ -0,0 +1,89 @@
1
+ import path from 'path';
2
+ import { execa } from 'execa';
3
+ import { Command } from 'commander';
4
+ import fs from 'fs-extra';
5
+ import inquirer from 'inquirer';
6
+
7
+ import { log_info, log_error, getInquirerOperationText } from '../lib/logger.js';
8
+ import { checkTargetDir, getProjects } from '../lib/dir.js';
9
+
10
+ export default function () {
11
+ const command = new Command('run');
12
+
13
+ command.description('运行指定项目').action(async () => {
14
+ try {
15
+ // 校验项目根目录是否合法
16
+ if (!checkTargetDir(process.cwd())) {
17
+ log_error('请在 HRP3.0 项目根目录下运行此命令!');
18
+ return;
19
+ }
20
+
21
+ // 项目根目录
22
+ const appsDir = path.resolve(process.cwd(), 'apps');
23
+
24
+ // 获取项目列表
25
+ const projects = await getProjects(appsDir);
26
+
27
+ // 交互选择项目
28
+ const answer = await inquirer.prompt([
29
+ {
30
+ type: 'rawlist',
31
+ name: 'runstyle',
32
+ message: `请选择项目运行方式:` + getInquirerOperationText('list'),
33
+ default: 1,
34
+ choices: [
35
+ { name: '方式1:运行所有项目', value: 0 },
36
+ { name: '方式2:运行指定项目', value: 1 },
37
+ ],
38
+ },
39
+ {
40
+ type: 'checkbox',
41
+ name: 'project',
42
+ message: '请选择要运行的项目:' + getInquirerOperationText('checkbox'),
43
+ when: (answers) => answers.runstyle == 1,
44
+ choices: projects.map((p) => ({
45
+ checked: p.name === 'core' || p.name === 'mw',
46
+ name: `${p.name} (端口号: ${p.port || '未配置'})`,
47
+ value: p,
48
+ })),
49
+ },
50
+ ]);
51
+
52
+ // 运行项目
53
+ if (answer.runstyle === 0) runProject(projects, appsDir);
54
+ if (answer.runstyle === 1 && answer.project) runProject(answer.project, appsDir);
55
+ } catch (error) {
56
+ log_error(error.message);
57
+ process.exit(1);
58
+ }
59
+ });
60
+
61
+ return command;
62
+ }
63
+
64
+ // 运行项目
65
+ function runProject(projects = [], appsDir) {
66
+ projects.forEach((project) => {
67
+ const projectName = project.name;
68
+ if (projectName) {
69
+ const projectPath = path.join(appsDir, projectName);
70
+ if (!fs.existsSync(projectPath)) {
71
+ throw new Error(`项目 ${projectName} 不存在`);
72
+ }
73
+ // 准备运行命令
74
+ const command = 'npm run dev';
75
+ // 执行命令
76
+ log_info(`🚀 启动项目 ${projectName}...`);
77
+ const subprocess = execa(command, {
78
+ cwd: projectPath,
79
+ stdio: 'inherit',
80
+ env: {
81
+ NODE_ENV: 'development',
82
+ },
83
+ });
84
+ subprocess.on('exit', (code) => {
85
+ if (code !== 0) log_error(`项目 ${projectName} 异常退出 (CODE: ${code})`);
86
+ });
87
+ }
88
+ });
89
+ }
package/bin/lib/const.js CHANGED
@@ -1 +1,13 @@
1
1
  export const LOWEST_NODE_VERSION = '18.0.0'; // 最低的 node 版本
2
+
3
+ // inquirer 操作信息提示文本
4
+ export const INQUIRER_OPERATION_TEXT = {
5
+ list: {
6
+ prefix: '操作:',
7
+ actions: ['↑↓ 导航', '回车键 ↩ 确认'],
8
+ },
9
+ checkbox: {
10
+ prefix: '操作:',
11
+ actions: ['↑↓ 导航', '空格键 -> 选择', 'a 全选', 'i 反选', '回车键 ↩ 确认'],
12
+ },
13
+ };
package/bin/lib/dir.js ADDED
@@ -0,0 +1,36 @@
1
+ import fs from 'fs-extra';
2
+ import path from 'path';
3
+
4
+ // 获取 apps 目录下,所有有效项目
5
+ export async function getProjects(appsDir) {
6
+ return fs
7
+ .readdirSync(appsDir)
8
+ .filter((name) => {
9
+ const projectPath = path.join(appsDir, name);
10
+ return fs.existsSync(path.join(projectPath, 'package.json'));
11
+ })
12
+ .map((name) => {
13
+ const pkgPath = path.join(appsDir, name, 'package.json');
14
+ const pkg = fs.readJSONSync(pkgPath);
15
+ return {
16
+ name,
17
+ port: pkg.devServer?.port || 3000,
18
+ scripts: pkg.scripts || {},
19
+ };
20
+ });
21
+ }
22
+
23
+ // 检查 root 根目录是否存在
24
+ export function checkTargetDir(currentPath) {
25
+ const monoDirs = ['apps', 'packages'];
26
+ const conflictDirs = monoDirs
27
+ .map((dir) => ({
28
+ name: dir,
29
+ path: path.join(currentPath, dir),
30
+ exists: fs.existsSync(path.join(currentPath, dir)),
31
+ }))
32
+ .filter((item) => item.exists)
33
+ .map((item) => item.name);
34
+
35
+ return conflictDirs.join(',') == monoDirs.join(',');
36
+ }
package/bin/lib/logger.js CHANGED
@@ -1,4 +1,6 @@
1
1
  import chalk from 'chalk';
2
+ import { INQUIRER_OPERATION_TEXT } from './const.js';
3
+
2
4
  const LOG_TYPES = {
3
5
  success: {
4
6
  label: '成功',
@@ -35,3 +37,22 @@ export const log_info = (msg, label) => log('info', msg, label); // 保持向后
35
37
  export function printError(err, label) {
36
38
  log_error(err instanceof Error ? err.message : err, label);
37
39
  }
40
+
41
+ // 获取 inquirer 操作信息提示文本
42
+ export const getInquirerOperationText = (type) =>
43
+ chalk.hex('#2ed573')(
44
+ [INQUIRER_OPERATION_TEXT[type].prefix].concat(INQUIRER_OPERATION_TEXT[type].actions).join(' | ')
45
+ );
46
+
47
+ // 获取分钟信息文本
48
+ export function getFormatTimeText(time) {
49
+ const totalSeconds = Math.floor(time / 1000);
50
+ const minutes = Math.floor(totalSeconds / 60);
51
+ const seconds = totalSeconds % 60;
52
+ return [minutes > 0 && `${minutes}分钟`, seconds > 0 && `${seconds}秒`].filter(Boolean).join(' ');
53
+ }
54
+
55
+ // 获取下划线信息文本
56
+ export function getUnderlineText(text) {
57
+ return chalk.cyan.underline(text);
58
+ }
package/bin/lib/utils.js CHANGED
@@ -13,17 +13,3 @@ export const projectRoot = path.resolve(__dirname, '../../');
13
13
  // ES6 自定义 require 函数,用于读取 .json 文件信息
14
14
  // import.meta.url 的路径基准点是 当前文件所在目录(即 bin/lib/index.js)
15
15
  export const require = createRequire(projectRoot + '/');
16
-
17
- // 初始化 TS 编译器
18
- // require('ts-node').register({
19
- // transpileOnly: true, // 禁用类型检查(提升性能)
20
- // files: ['**/*.config.ts'], // 只编译配置文件
21
- // compilerOptions: {
22
- // moduleResolution: 'NodeNext',
23
- // module: 'NodeNext',
24
- // },
25
- // });
26
- // // 支持 .ts 扩展名注册 (针对旧版 Node)
27
- // require.extensions['ts'] = function (module, filePath) {
28
- // module._compile(require('fs').readFileSync(filePath, 'utf8'), filePath);
29
- // };
package/bin/main.js CHANGED
@@ -1,8 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import configureCreateCommand from './commands/create.js';
3
2
  import { require } from './lib/utils.js';
4
3
  import { LOWEST_NODE_VERSION } from './lib/const.js';
5
4
  import { log_error, log_warning } from './lib/logger.js';
5
+ import configureCreateCommand from './commands/create.js';
6
+ import configureRunCommand from './commands/run.js';
7
+ import configureDeployCommand from './commands/deploy.js';
6
8
 
7
9
  // 外部依赖
8
10
  import semver from 'semver';
@@ -36,6 +38,8 @@ function handleProgramCommand() {
36
38
 
37
39
  // 注册子命令
38
40
  program.addCommand(configureCreateCommand());
41
+ program.addCommand(configureRunCommand());
42
+ program.addCommand(configureDeployCommand());
39
43
 
40
44
  // 解析命令行参数
41
45
  program.parse(program.argv);
@@ -1,12 +1,34 @@
1
1
  <template>
2
2
  <div class="app-container">
3
- <Home />
4
- <router-view></router-view>
3
+ <router-view v-slot="{ Component, route }">
4
+ <keep-alive>
5
+ <component :is="Component" v-if="route.meta.keepAlive" :key="route.path" />
6
+ </keep-alive>
7
+ <component :is="Component" v-if="!route.meta.keepAlive" :key="route.path" />
8
+ </router-view>
5
9
  </div>
6
10
  </template>
7
11
 
8
- <script setup scoped>
9
- import Home from './views/Home.vue';
12
+ <script setup>
13
+ import { onMounted, onUnmounted } from 'vue';
14
+ import { useRouter } from 'vue-router';
15
+
16
+ const router = useRouter();
17
+
18
+ // 事件处理器保持引用便于卸载
19
+ const handleRouterChange = (path) => {
20
+ router.push(path);
21
+ };
22
+ onMounted(() => {
23
+ const { props, bus } = window.$wujie;
24
+ // 第一次进入页面,主应用路由信息发送给子应用
25
+ if (props.routeName) handleRouterChange(props.routeName);
26
+
27
+ // 持续监听子应用路由信息变化
28
+
29
+ if (bus) bus.$on('<%= projectName %>-router-change', handleRouterChange);
30
+ });
31
+ onUnmounted(() => window.$wujie?.bus.$off('<%= projectName %>-router-change', handleRouterChange));
10
32
  </script>
11
33
 
12
34
  <style scoped>
@@ -1,5 +1,5 @@
1
1
  import { createRouter, createWebHashHistory } from 'vue-router';
2
- const basename = process.env.NODE_ENV === 'production' ? '/mw/' : '';
2
+ const basename = process.env.NODE_ENV === 'production' ? '/<%= projectName %>/' : '';
3
3
 
4
4
  const routes = [
5
5
  // {
@@ -1,6 +1,9 @@
1
1
  import { defineConfig } from 'vite';
2
2
  import vue from '@vitejs/plugin-vue';
3
- const ProxyURL = process.env.VITE_API_BASE_URL;
3
+ import path from 'path';
4
+ import fs from 'fs';
5
+ const projectConfig = JSON.parse(fs.readFileSync(path.resolve(process.cwd(), '../../', 'project.json'), 'utf-8'));
6
+ const ProxyURL = projectConfig.apiUrl || 'https://hrp3.wytdev.com';
4
7
 
5
8
  export default defineConfig({
6
9
  base: './',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wyt-cli",
3
- "version": "1.0.11",
3
+ "version": "1.0.13",
4
4
  "description": "HRP3.0 项目命令行工具",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -12,7 +12,9 @@
12
12
  },
13
13
  "type": "module",
14
14
  "scripts": {
15
- "publish": "npm version patch && npm publish"
15
+ "login": "npm login",
16
+ "patch": "npm version patch",
17
+ "publish": "npm publish"
16
18
  },
17
19
  "keywords": [],
18
20
  "author": "",
@@ -22,6 +24,7 @@
22
24
  "chalk": "^5.6.2",
23
25
  "commander": "^14.0.2",
24
26
  "ejs": "^4.0.1",
27
+ "execa": "^9.6.1",
25
28
  "fs-extra": "^11.3.3",
26
29
  "glob": "^13.0.0",
27
30
  "inquirer": "^13.2.0",
@@ -1,13 +0,0 @@
1
- <!doctype html>
2
- <html lang="zh-CN">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>test</title>
7
- </head>
8
-
9
- <body>
10
- <div id="app"></div>
11
- <script type="module" src="./src/main.js"></script>
12
- </body>
13
- </html>
@@ -1,28 +0,0 @@
1
- {
2
- "name": "test",
3
- "private": true,
4
- "version": "1.0.0",
5
- "type": "module",
6
- "description": "个人工作台",
7
- "scripts": {
8
- "dev": "vite",
9
- "build": "vite build",
10
- "preview": "vite preview"
11
- },
12
- "dependencies": {
13
- "@element-plus/icons-vue": "^2.3.1",
14
- "@wyt/components": "workspace:^",
15
- "@wyt/utils": "workspace:^",
16
- "element-plus": "^2.10.2",
17
- "pinia": "^2.0.28",
18
- "sass": "^1.89.2",
19
- "vue": "^3.5.13",
20
- "vue-router": "^4.5.0",
21
- "wujie-polyfill": "^1.1.3",
22
- "wujie-vue3": "^1.0.24"
23
- },
24
- "devDependencies": {
25
- "@vitejs/plugin-vue": "^5.2.1",
26
- "vite": "^6.0.5"
27
- }
28
- }
@@ -1,20 +0,0 @@
1
- <template>
2
- <div class="app-container">
3
- <Home />
4
- <router-view></router-view>
5
- </div>
6
- </template>
7
-
8
- <script setup scoped>
9
- import Home from './views/Home.vue';
10
- </script>
11
-
12
- <style scoped>
13
- .app-container {
14
- width: 100%;
15
- height: calc(100vh - 70px);
16
- background-color: #fff;
17
- overflow: auto;
18
- scrollbar-width: thin;
19
- }
20
- </style>
@@ -1,15 +0,0 @@
1
- /**
2
- * API 接口定义文件
3
- *
4
- */
5
- import { http } from '@wyt/utils';
6
-
7
- export const api_test = (data) => {
8
- return http({
9
- // method: 'POST',
10
- // url: '/finweb/?svr=FWS_20002',
11
- data,
12
- });
13
- };
14
-
15
- export default {};
@@ -1,5 +0,0 @@
1
- <template>
2
- <p>这是一个测试组件</p>
3
- </template>
4
-
5
- <script name="TestComponent" setup></script>
@@ -1,20 +0,0 @@
1
- import { createApp } from 'vue';
2
- import { createPinia } from 'pinia';
3
- import App from './App.vue';
4
- import router from './router';
5
- import './style.css';
6
- import ElementPlus from 'element-plus';
7
- import zhCn from 'element-plus/dist/locale/zh-cn.mjs';
8
- import 'element-plus/dist/index.css';
9
- import wytComponents from '@wyt/components';
10
- import '@wyt/components/dist/themes/index.css';
11
- import '@wyt/components/dist/index.css';
12
- import '@wyt/components/dist/assets/iconfont/iconfont.css';
13
- import '@wyt/form-designer/dist/style.css';
14
- import { initAndListenTheme } from '@wyt/utils';
15
-
16
- initAndListenTheme();
17
-
18
- const app = createApp(App);
19
-
20
- app.use(createPinia()).use(wytComponents).use(router).use(ElementPlus, { locale: zhCn }).mount('#app');
@@ -1,23 +0,0 @@
1
- import { createRouter, createWebHashHistory } from 'vue-router';
2
- const basename = process.env.NODE_ENV === 'production' ? '/mw/' : '';
3
-
4
- const routes = [
5
- // {
6
- // path: '*****',
7
- // name: '*****',
8
- // },
9
-
10
- // 404 路由配置
11
- {
12
- path: '/:pathMatch(.*)*',
13
- name: 'NotFound',
14
- component: () => import('../views/NotFound.vue'),
15
- },
16
- ];
17
-
18
- const router = createRouter({
19
- history: createWebHashHistory(basename),
20
- routes,
21
- });
22
-
23
- export default router;
@@ -1,20 +0,0 @@
1
- * {
2
- margin: 0;
3
- padding: 0;
4
- box-sizing: border-box;
5
- }
6
-
7
- ul {
8
- list-style: none;
9
- }
10
-
11
- /* 重置公共样式部分 */
12
- .drawer-header-box {
13
- padding: 0 !important;
14
- margin: 0 !important;
15
- }
16
-
17
- .drawer-body-box {
18
- padding: 0 !important;
19
- margin: 0 !important;
20
- }
@@ -1,8 +0,0 @@
1
- <template>
2
- <h1>这是一个测试页面</h1>
3
- <TestComponent />
4
- </template>
5
-
6
- <script setup scoped>
7
- import TestComponent from './components/TestComponent.vue';
8
- </script>
@@ -1,13 +0,0 @@
1
- <template>
2
- <div class="not-found">
3
- <h1>404</h1>
4
- <h2>您访问的页面不存在</h2>
5
- </div>
6
- </template>
7
-
8
- <style scoped lang="scss">
9
- .not-found {
10
- text-align: center;
11
- padding: 50px;
12
- }
13
- </style>
@@ -1,51 +0,0 @@
1
- import { defineConfig } from 'vite';
2
- import vue from '@vitejs/plugin-vue';
3
- const ProxyURL = process.env.VITE_API_BASE_URL;
4
-
5
- export default defineConfig({
6
- base: './',
7
- build: {
8
- outDir: '../../dist/test',
9
- emptyOutDir: true, // 清空输出目录
10
- },
11
- server: {
12
- port: '6003',
13
- open: false,
14
- proxy: {
15
- // 设置代理
16
- '/finweb': {
17
- target: ProxyURL,
18
- changeOrigin: true,
19
- rewrite: (path) => path.replace(/^\/finweb/, '/finweb'),
20
- // 添加 CORS 头
21
- configure: (proxy) => {
22
- proxy.on('proxyRes', (proxyRes, req, res) => {
23
- res.setHeader('Access-Control-Allow-Origin', req.headers.origin || '*');
24
- res.setHeader('Access-Control-Allow-Credentials', 'true');
25
- });
26
- },
27
- },
28
- },
29
- cors: true,
30
- },
31
- resolve: {
32
- dedupe: ['vue', 'pinia', 'element-plus'],
33
- alias: {
34
- '@': '/src',
35
- '@hooks': '/src/hooks/index.js',
36
- },
37
- },
38
- plugins: [
39
- vue({
40
- script: {
41
- defineModel: true,
42
- propsDestructure: true,
43
- },
44
- }),
45
- ],
46
- css: {
47
- preprocessorOptions: {
48
- scss: {},
49
- },
50
- },
51
- });