refactor(projects): 代码优化

This commit is contained in:
Soybean 2022-07-16 00:13:19 +08:00
parent 872bb84502
commit 6143605297
24 changed files with 107 additions and 104 deletions

View File

@ -1,30 +1,30 @@
/** 请求环境配置 */ /** 请求环境配置 */
type ServiceEnv = Record<EnvType, EnvConfig>; type ServiceEnv = Record<ServiceEnvType, ServiceEnvConfig>;
/** 环境配置 */ /** 不同服务的环境配置 */
const serviceEnvConfig: ServiceEnv = { const serviceEnv: ServiceEnv = {
dev: { dev: {
url: 'http://localhost:8080', url: 'http://localhost:8080',
proxy: '/api' proxy: '/proxy-flag'
}, },
test: { test: {
url: 'http://localhost:8080', url: 'http://localhost:8080',
proxy: '/api' proxy: '/proxy-flag'
}, },
prod: { prod: {
url: 'http://localhost:8080', url: 'http://localhost:8080',
proxy: '/api' proxy: '/proxy-flag'
} }
}; };
/** /**
* *
* @param env * @param env
*/ */
export function getEnvConfig(env: ImportMetaEnv) { export function getEnvConfig(env: ImportMetaEnv) {
const { VITE_ENV_TYPE = 'dev' } = env; const { VITE_ENV_TYPE = 'dev' } = env;
const envConfig = serviceEnvConfig[VITE_ENV_TYPE]; const envConfig = serviceEnv[VITE_ENV_TYPE];
return envConfig; return envConfig;
} }

View File

@ -1 +1 @@
VITE_HTTP_PROXY=1 VITE_HTTP_PROXY=Y

View File

@ -1,6 +1,6 @@
VITE_VISUALIZER=0 VITE_VISUALIZER=N
VITE_COMPRESS=0 VITE_COMPRESS=N
# gzip | brotliCompress | deflate | deflateRaw # gzip | brotliCompress | deflate | deflateRaw
VITE_COMPRESS_TYPE=gzip VITE_COMPRESS_TYPE=gzip

View File

@ -1,8 +1,7 @@
module.exports = { module.exports = {
env: { env: {
browser: true, browser: true,
es2021: true, es2021: true
'vue/setup-compiler-macros': true
}, },
globals: { globals: {
PROJECT_BUILD_TIME: 'readonly', PROJECT_BUILD_TIME: 'readonly',
@ -26,40 +25,6 @@ module.exports = {
'@vue/eslint-config-prettier', '@vue/eslint-config-prettier',
'@vue/typescript/recommended' '@vue/typescript/recommended'
], ],
overrides: [
{
files: ['*.vue'],
rules: {
'no-undef': 'off'
}
},
{
files: ['*.html'],
rules: {
'vue/comment-directive': 'off'
}
},
{
files: ['*.json'],
rules: {
'no-unused-expressions': 'off'
}
}
],
settings: {
'import/resolver': {
alias: {
map: [
['~', '.'],
['@', './src']
],
extensions: ['.js', '.jsx', '.mjs', '.ts', '.tsx', '.d.ts']
},
node: {
extensions: ['.js', '.jsx', '.mjs', '.ts', '.tsx', '.d.ts']
}
}
},
rules: { rules: {
'import/extensions': [ 'import/extensions': [
'warn', 'warn',
@ -69,7 +34,8 @@ module.exports = {
jsx: 'never', jsx: 'never',
mjs: 'never', mjs: 'never',
ts: 'never', ts: 'never',
tsx: 'never' tsx: 'never',
mts: 'never'
} }
], ],
'import/no-extraneous-dependencies': ['error', { devDependencies: true, peerDependencies: true }], 'import/no-extraneous-dependencies': ['error', { devDependencies: true, peerDependencies: true }],
@ -145,12 +111,12 @@ module.exports = {
position: 'before' position: 'before'
}, },
{ {
pattern: '@/store', pattern: '@/service',
group: 'internal', group: 'internal',
position: 'before' position: 'before'
}, },
{ {
pattern: '@/composables', pattern: '@/store',
group: 'internal', group: 'internal',
position: 'before' position: 'before'
}, },
@ -160,12 +126,12 @@ module.exports = {
position: 'before' position: 'before'
}, },
{ {
pattern: '@/hooks', pattern: '@/composables',
group: 'internal', group: 'internal',
position: 'before' position: 'before'
}, },
{ {
pattern: '@/service', pattern: '@/hooks',
group: 'internal', group: 'internal',
position: 'before' position: 'before'
}, },
@ -183,11 +149,6 @@ module.exports = {
pattern: '@/**', pattern: '@/**',
group: 'internal', group: 'internal',
position: 'before' position: 'before'
},
{
pattern: '@/interface',
group: 'internal',
position: 'before'
} }
], ],
pathGroupsExcludedImportTypes: ['vue', 'vue-router', 'vuex', 'pinia', 'naive-ui'] pathGroupsExcludedImportTypes: ['vue', 'vue-router', 'vuex', 'pinia', 'naive-ui']
@ -227,5 +188,39 @@ module.exports = {
{ vars: 'all', args: 'all', ignoreRestSiblings: false, varsIgnorePattern: '^_', argsIgnorePattern: '^_' } { vars: 'all', args: 'all', ignoreRestSiblings: false, varsIgnorePattern: '^_', argsIgnorePattern: '^_' }
], ],
'@typescript-eslint/no-use-before-define': ['error', { classes: true, functions: false, typedefs: false }] '@typescript-eslint/no-use-before-define': ['error', { classes: true, functions: false, typedefs: false }]
} },
settings: {
'import/resolver': {
alias: {
map: [
['~', '.'],
['@', './src']
],
extensions: ['.js', '.jsx', '.mjs', '.ts', '.tsx', 'mts', '.d.ts']
},
node: {
extensions: ['.js', '.jsx', '.mjs', '.ts', '.tsx', 'mts', '.d.ts']
}
}
},
overrides: [
{
files: ['*.vue'],
rules: {
'no-undef': 'off'
}
},
{
files: ['*.html'],
rules: {
'vue/comment-directive': 'off'
}
},
{
files: ['*.json'],
rules: {
'no-unused-expressions': 'off'
}
}
]
}; };

2
.gitignore vendored
View File

@ -31,3 +31,5 @@ stats.html
/src/typings/components.d.ts /src/typings/components.d.ts
pnpm-lock.yaml pnpm-lock.yaml
package-lock.json
yarn.lock

View File

@ -5,7 +5,7 @@ import type { ProxyOptions } from 'vite';
* @param isOpenProxy - * @param isOpenProxy -
* @param envConfig - env环境配置 * @param envConfig - env环境配置
*/ */
export function createViteProxy(isOpenProxy: boolean, envConfig: EnvConfig) { export function createViteProxy(isOpenProxy: boolean, envConfig: ServiceEnvConfig) {
if (!isOpenProxy) return undefined; if (!isOpenProxy) return undefined;
const proxy: Record<string, string | ProxyOptions> = { const proxy: Record<string, string | ProxyOptions> = {

View File

@ -14,10 +14,10 @@ import compress from './compress';
export function setupVitePlugins(viteEnv: ImportMetaEnv): (PluginOption | PluginOption[])[] { export function setupVitePlugins(viteEnv: ImportMetaEnv): (PluginOption | PluginOption[])[] {
const plugins = [...vue, html(viteEnv), ...unplugin, unocss, mock]; const plugins = [...vue, html(viteEnv), ...unplugin, unocss, mock];
if (viteEnv.VITE_VISUALIZER === '1') { if (viteEnv.VITE_VISUALIZER === 'Y') {
plugins.push(visualizer); plugins.push(visualizer);
} }
if (viteEnv.VITE_COMPRESS === '1') { if (viteEnv.VITE_COMPRESS === 'Y') {
plugins.push(compress(viteEnv)); plugins.push(compress(viteEnv));
} }

View File

@ -2,7 +2,7 @@ import path from 'path';
/** /**
* *
* @descrition * @descrition
*/ */
export function getRootPath() { export function getRootPath() {
return path.resolve(process.cwd()); return path.resolve(process.cwd());
@ -11,7 +11,7 @@ export function getRootPath() {
/** /**
* src路径 * src路径
* @param srcName - src目录名称(: "src") * @param srcName - src目录名称(: "src")
* @descrition * @descrition
*/ */
export function getSrcPath(srcName = 'src') { export function getSrcPath(srcName = 'src') {
const rootPath = getRootPath(); const rootPath = getRootPath();

View File

@ -13,7 +13,7 @@
"build": "npm run typecheck && cross-env VITE_ENV_TYPE=prod vite build", "build": "npm run typecheck && cross-env VITE_ENV_TYPE=prod vite build",
"build:dev": "npm run typecheck && cross-env VITE_ENV_TYPE=dev vite build", "build:dev": "npm run typecheck && cross-env VITE_ENV_TYPE=dev vite build",
"build:test": "npm run typecheck && cross-env VITE_ENV_TYPE=test vite build", "build:test": "npm run typecheck && cross-env VITE_ENV_TYPE=test vite build",
"build:vercel": "cross-env VITE_HASH_ROUTE=1 VITE_VERCEL=1 vite build", "build:vercel": "cross-env VITE_HASH_ROUTE=Y VITE_VERCEL=Y vite build",
"preview": "vite preview", "preview": "vite preview",
"typecheck": "vue-tsc --noEmit --skipLibCheck", "typecheck": "vue-tsc --noEmit --skipLibCheck",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts,.json --fix", "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts,.json --fix",

View File

@ -42,5 +42,5 @@ export const ERROR_STATUS = {
/** 不弹出错误信息的code */ /** 不弹出错误信息的code */
export const NO_ERROR_MSG_CODE: (string | number)[] = []; export const NO_ERROR_MSG_CODE: (string | number)[] = [];
/** token失效需要刷新token的code */ /** token失效需要刷新token的code(这里的66666只是个例子需要将后端表示token过期的code填进来) */
export const REFRESH_TOKEN_CODE: (string | number)[] = [66666]; export const REFRESH_TOKEN_CODE: (string | number)[] = [66666];

View File

@ -51,7 +51,7 @@ defineProps<Props>();
const theme = useThemeStore(); const theme = useThemeStore();
const { isMobile } = useBasicLayout(); const { isMobile } = useBasicLayout();
const showButton = import.meta.env.PROD && import.meta.env.VITE_VERCEL !== '1'; const showButton = import.meta.env.PROD && import.meta.env.VITE_VERCEL !== 'Y';
</script> </script>
<style scoped> <style scoped>

View File

@ -20,7 +20,7 @@ defineOptions({ name: 'SettingDrawer' });
const app = useAppStore(); const app = useAppStore();
const showButton = import.meta.env.DEV || import.meta.env.VITE_VERCEL === '1'; const showButton = import.meta.env.DEV || import.meta.env.VITE_VERCEL === 'Y';
</script> </script>
<style scoped></style> <style scoped></style>

View File

@ -5,10 +5,10 @@ import { constantRoutes } from './routes';
import { scrollBehavior } from './helpers'; import { scrollBehavior } from './helpers';
import { createRouterGuard } from './guard'; import { createRouterGuard } from './guard';
const { VITE_HASH_ROUTE = '0', VITE_BASE_URL } = import.meta.env; const { VITE_HASH_ROUTE = 'N', VITE_BASE_URL } = import.meta.env;
export const router = createRouter({ export const router = createRouter({
history: VITE_HASH_ROUTE === '1' ? createWebHashHistory(VITE_BASE_URL) : createWebHistory(VITE_BASE_URL), history: VITE_HASH_ROUTE === 'Y' ? createWebHashHistory(VITE_BASE_URL) : createWebHistory(VITE_BASE_URL),
routes: transformAuthRoutesToVueRoutes(constantRoutes), routes: transformAuthRoutesToVueRoutes(constantRoutes),
scrollBehavior scrollBehavior
}); });

View File

@ -2,7 +2,7 @@ import { getEnvConfig } from '~/.env-config';
import { createRequest } from './request'; import { createRequest } from './request';
const envConfig = getEnvConfig(import.meta.env); const envConfig = getEnvConfig(import.meta.env);
const isHttpProxy = import.meta.env.VITE_HTTP_PROXY === '1'; const isHttpProxy = import.meta.env.VITE_HTTP_PROXY === 'Y';
export const request = createRequest({ baseURL: isHttpProxy ? envConfig.proxy : envConfig.url }); export const request = createRequest({ baseURL: isHttpProxy ? envConfig.proxy : envConfig.url });

View File

@ -1,8 +1,8 @@
import { unref } from 'vue'; import { unref } from 'vue';
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import { router } from '@/router'; import { router } from '@/router';
import { useRouterPush } from '@/composables';
import { fetchLogin, fetchUserInfo } from '@/service'; import { fetchLogin, fetchUserInfo } from '@/service';
import { useRouterPush } from '@/composables';
import { getUserInfo, getToken, setUserInfo, setToken, setRefreshToken, clearAuthStorage } from '@/utils'; import { getUserInfo, getToken, setUserInfo, setToken, setRefreshToken, clearAuthStorage } from '@/utils';
import { useTabStore } from '../tab'; import { useTabStore } from '../tab';
import { useRouteStore } from '../route'; import { useRouteStore } from '../route';

26
src/typings/env.d.ts vendored
View File

@ -1,17 +1,17 @@
/** /**
* env环境类 *
* - dev: 后台开发环境 * - dev: 后台开发环境
* - test: 后台测试环境 * - test: 后台测试环境
* - prod: 后台生产环境 * - prod: 后台生产环境
*/ */
type EnvType = 'dev' | 'test' | 'prod'; type ServiceEnvType = 'dev' | 'test' | 'prod';
/** env环境配置 */ /** 后台服务的环境配置 */
interface EnvConfig { interface ServiceEnvConfig {
/** 后端的请求地址 */ /** 请求地址 */
url: string; url: string;
/** 代理标识, 用于拦截地址转发代理(如:"/api",这个和后端路径有无 "/api" 路径没有任何关系) */ /** 代理标识, 用于拦截地址转发代理(和后端请求路径中有无该路径没有关系) */
proxy: string; proxy: '/proxy-flag';
} }
interface ImportMetaEnv { interface ImportMetaEnv {
@ -32,19 +32,19 @@ interface ImportMetaEnv {
/** 路由首页的路径 */ /** 路由首页的路径 */
readonly VITE_ROUTE_HOME_PATH: Exclude<AuthRoute.RoutePath, '/' | '/not-found-page' | '/:pathMatch(.*)*'>; readonly VITE_ROUTE_HOME_PATH: Exclude<AuthRoute.RoutePath, '/' | '/not-found-page' | '/:pathMatch(.*)*'>;
/** vite环境类型 */ /** vite环境类型 */
readonly VITE_ENV_TYPE?: EnvType; readonly VITE_ENV_TYPE?: ServiceEnvType;
/** 开启请求代理 */ /** 开启请求代理 */
readonly VITE_HTTP_PROXY?: '1' | '0'; readonly VITE_HTTP_PROXY?: 'Y' | 'N';
/** 是否开启打包文件大小结果分析 */ /** 是否开启打包文件大小结果分析 */
readonly VITE_VISUALIZER?: '1' | '0'; readonly VITE_VISUALIZER?: 'Y' | 'N';
/** 是否开启打包压缩 */ /** 是否开启打包压缩 */
readonly VITE_COMPRESS?: '1' | '0'; readonly VITE_COMPRESS?: 'Y' | 'N';
/** 压缩算法类型 */ /** 压缩算法类型 */
readonly VITE_COMPRESS_TYPE?: 'gzip' | 'brotliCompress' | 'deflate' | 'deflateRaw'; readonly VITE_COMPRESS_TYPE?: 'gzip' | 'brotliCompress' | 'deflate' | 'deflateRaw';
/** hash路由模式 */ /** hash路由模式 */
readonly VITE_HASH_ROUTE?: '1' | '0'; readonly VITE_HASH_ROUTE?: 'Y' | 'N';
/** 是否是部署的vercel */ /** 是否是部署的vercel */
readonly VITE_VERCEL?: '1' | '0'; readonly VITE_VERCEL?: 'Y' | 'N';
} }
interface ImportMeta { interface ImportMeta {

View File

@ -3,4 +3,9 @@ declare namespace Expose {
interface BetterScroll { interface BetterScroll {
instance: import('@better-scroll/core').BScrollInstance; instance: import('@better-scroll/core').BScrollInstance;
} }
interface ImageVerify {
/** 获取图片验证码 */
getImgCode(): void;
}
} }

View File

@ -24,8 +24,8 @@ declare namespace Service {
/** /**
* *
* - axios: axios错误, , * - axios: axios错误, ,
* - http: 请求成功200 * - http: 请求成功http状态码非200的错
* - backend: 请求成功200 * - backend: 请求成功http状态码为200
*/ */
type RequestErrorType = 'axios' | 'http' | 'backend'; type RequestErrorType = 'axios' | 'http' | 'backend';

View File

@ -1,4 +1,7 @@
/** 执行策略模式 */ /**
*
* @param actions
*/
export function exeStrategyActions(actions: Common.StrategyAction[]) { export function exeStrategyActions(actions: Common.StrategyAction[]) {
actions.some(item => { actions.some(item => {
const [flag, action] = item; const [flag, action] = item;

View File

@ -15,7 +15,7 @@ type ErrorStatus = keyof typeof ERROR_STATUS;
/** /**
* axios请求失败的错误 * axios请求失败的错误
* @param error - * @param axiosError -
*/ */
export function handleAxiosError(axiosError: AxiosError) { export function handleAxiosError(axiosError: AxiosError) {
const error: Service.RequestError = { const error: Service.RequestError = {
@ -75,7 +75,7 @@ export function handleResponseError(response: AxiosResponse) {
// 请求成功的状态码非200的错误 // 请求成功的状态码非200的错误
const errorCode: ErrorStatus = response.status as ErrorStatus; const errorCode: ErrorStatus = response.status as ErrorStatus;
const msg = ERROR_STATUS[errorCode] || DEFAULT_REQUEST_ERROR_MSG; const msg = ERROR_STATUS[errorCode] || DEFAULT_REQUEST_ERROR_MSG;
Object.assign(error, { type: 'backend', code: errorCode, msg }); Object.assign(error, { type: 'http', code: errorCode, msg });
} }
showErrorMsg(error); showErrorMsg(error);

View File

@ -18,15 +18,12 @@ function hasErrorMsg(error: Service.RequestError) {
* @param error * @param error
*/ */
export function showErrorMsg(error: Service.RequestError) { export function showErrorMsg(error: Service.RequestError) {
if (!error.msg) return; if (!error.msg || NO_ERROR_MSG_CODE.includes(error.code) || hasErrorMsg(error)) return;
if (!NO_ERROR_MSG_CODE.includes(error.code)) {
if (!hasErrorMsg(error)) { addErrorMsg(error);
addErrorMsg(error); window.console.warn(error.code, error.msg);
window.console.warn(error.code, error.msg); window.$message?.error(error.msg, { duration: ERROR_MSG_DURATION });
window.$message?.error(error.msg, { duration: ERROR_MSG_DURATION }); setTimeout(() => {
setTimeout(() => { removeErrorMsg(error);
removeErrorMsg(error); }, ERROR_MSG_DURATION);
}, ERROR_MSG_DURATION);
}
}
} }

View File

@ -56,6 +56,6 @@ async function transformFile(formData: FormData, key: string, file: File[] | Fil
); );
} else { } else {
// 单文件 // 单文件
await formData.append(key, file); formData.append(key, file);
} }
} }

View File

@ -6,6 +6,7 @@
"lib": ["DOM", "ESNext"], "lib": ["DOM", "ESNext"],
"strict": true, "strict": true,
"esModuleInterop": true, "esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"jsx": "preserve", "jsx": "preserve",
"moduleResolution": "node", "moduleResolution": "node",
"resolveJsonModule": true, "resolveJsonModule": true,
@ -16,7 +17,7 @@
"~/*": ["./*"], "~/*": ["./*"],
"@/*": ["./src/*"] "@/*": ["./src/*"]
}, },
"types": ["vite/client", "node", "unplugin-icons/types/vue", "naive-ui/volar"] "types": ["node", "vite/client", "unplugin-icons/types/vue", "naive-ui/volar"]
}, },
"exclude": ["node_modules", "dist"] "exclude": ["node_modules", "dist"]
} }

View File

@ -8,7 +8,7 @@ export default defineConfig(configEnv => {
const rootPath = getRootPath(); const rootPath = getRootPath();
const srcPath = getSrcPath(); const srcPath = getSrcPath();
const isOpenProxy = viteEnv.VITE_HTTP_PROXY === '1'; const isOpenProxy = viteEnv.VITE_HTTP_PROXY === 'Y';
const envConfig = getEnvConfig(viteEnv); const envConfig = getEnvConfig(viteEnv);
return { return {