perf: add eslint import rules, improve the coupling of some components
parent
fbe0fc1738
commit
e68e1b40ce
|
@ -30,7 +30,10 @@ const tokenTheme = computed(() => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<GlobalProvider>
|
<GlobalProvider
|
||||||
|
:enable-ai-assistant="preferences.app.aiAssistant"
|
||||||
|
:is-mobile="preferences.app.isMobile"
|
||||||
|
>
|
||||||
<ConfigProvider :locale="antdLocale" :theme="tokenTheme">
|
<ConfigProvider :locale="antdLocale" :theme="tokenTheme">
|
||||||
<App>
|
<App>
|
||||||
<RouterView />
|
<RouterView />
|
||||||
|
|
|
@ -1,12 +1,125 @@
|
||||||
import type { Linter } from 'eslint';
|
import type { Linter } from 'eslint';
|
||||||
|
|
||||||
|
const restrictedImportIgnores = [
|
||||||
|
'**/vite.config.mts',
|
||||||
|
'**/tailwind.config.mjs',
|
||||||
|
'**/postcss.config.mjs',
|
||||||
|
];
|
||||||
|
|
||||||
const customConfig: Linter.FlatConfig[] = [
|
const customConfig: Linter.FlatConfig[] = [
|
||||||
|
// shadcn-ui 内部组件是自动生成的,这里忽略
|
||||||
{
|
{
|
||||||
files: ['packages/@core/ui-kit/shadcn-ui/**/**'],
|
files: ['packages/@core/ui-kit/shadcn-ui/**/**'],
|
||||||
rules: {
|
rules: {
|
||||||
'vue/require-default-prop': 'off',
|
'vue/require-default-prop': 'off',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
// apps内部的一些基础规则
|
||||||
|
files: ['apps/**/**'],
|
||||||
|
ignores: restrictedImportIgnores,
|
||||||
|
rules: {
|
||||||
|
'no-restricted-imports': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
patterns: [
|
||||||
|
{
|
||||||
|
group: ['#/api/*'],
|
||||||
|
message:
|
||||||
|
'The #/api package cannot be imported, please use the @core package itself',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: ['#/layouts/*'],
|
||||||
|
message:
|
||||||
|
'The #/layouts package cannot be imported, please use the @core package itself',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: ['#/locales/*'],
|
||||||
|
message:
|
||||||
|
'The #/locales package cannot be imported, please use the @core package itself',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: ['#/stores/*'],
|
||||||
|
message:
|
||||||
|
'The #/stores package cannot be imported, please use the @core package itself',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: ['#/forward/*'],
|
||||||
|
message:
|
||||||
|
'The #/forward package cannot be imported, please use the @core package itself',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// @core内部组件,不能引入@vben/* 里面的包
|
||||||
|
files: ['packages/@core/**/**'],
|
||||||
|
ignores: restrictedImportIgnores,
|
||||||
|
rules: {
|
||||||
|
'no-restricted-imports': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
// 如果需要,可以指定禁止特定的子路径
|
||||||
|
patterns: [
|
||||||
|
{
|
||||||
|
group: ['@vben/*'],
|
||||||
|
message:
|
||||||
|
'The @core package cannot import the @vben package, please use the @core package itself',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// @core/shared内部组件,不能引入@vben/* 或者 @vben-core/* 里面的包
|
||||||
|
files: ['packages/@core/shared/**/**'],
|
||||||
|
ignores: restrictedImportIgnores,
|
||||||
|
rules: {
|
||||||
|
'no-restricted-imports': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
// 如果需要,可以指定禁止特定的子路径
|
||||||
|
patterns: [
|
||||||
|
{
|
||||||
|
group: ['@vben/*', '@vben-core/*'],
|
||||||
|
message:
|
||||||
|
'The @vben-core/shared package cannot import the @vben package, please use the @core/shared package itself',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// 不能引入@vben/*里面的包
|
||||||
|
files: [
|
||||||
|
'packages/types/**/**',
|
||||||
|
'packages/utils/**/**',
|
||||||
|
'packages/icons/**/**',
|
||||||
|
'packages/constants/**/**',
|
||||||
|
'packages/styles/**/**',
|
||||||
|
],
|
||||||
|
ignores: restrictedImportIgnores,
|
||||||
|
rules: {
|
||||||
|
'no-restricted-imports': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
// 如果需要,可以指定禁止特定的子路径
|
||||||
|
patterns: [
|
||||||
|
{
|
||||||
|
group: ['@vben/*'],
|
||||||
|
message:
|
||||||
|
'The @vben package cannot be imported, please use the @core package itself',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 后端模拟代码,不需要太多规则
|
||||||
{
|
{
|
||||||
files: ['apps/backend-mock/**/**'],
|
files: ['apps/backend-mock/**/**'],
|
||||||
rules: {
|
rules: {
|
||||||
|
|
|
@ -8,7 +8,6 @@ import { createI18n } from 'vue-i18n';
|
||||||
|
|
||||||
const loadedLanguages = new Set<string>();
|
const loadedLanguages = new Set<string>();
|
||||||
|
|
||||||
// TODO:import.meta.env,会导致该包依赖外部项目必须是vite才可以
|
|
||||||
const i18n = createI18n({
|
const i18n = createI18n({
|
||||||
globalInjection: true,
|
globalInjection: true,
|
||||||
legacy: false,
|
legacy: false,
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* 获取元素可见高度
|
* 获取元素可见高度
|
||||||
* @param element
|
* @param element
|
||||||
* @returns
|
|
||||||
*/
|
*/
|
||||||
function getElementVisibleHeight(
|
function getElementVisibleHeight(
|
||||||
element?: HTMLElement | null | undefined,
|
element?: HTMLElement | null | undefined,
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* eslint-disable no-restricted-imports */
|
||||||
import type { RouteMeta as IRouteMeta } from '@vben-core/typings';
|
import type { RouteMeta as IRouteMeta } from '@vben-core/typings';
|
||||||
|
|
||||||
import 'vue-router';
|
import 'vue-router';
|
||||||
|
|
|
@ -1,16 +1,22 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { preferences } from '@vben-core/preferences';
|
|
||||||
import { Toaster } from '@vben-core/shadcn-ui';
|
import { Toaster } from '@vben-core/shadcn-ui';
|
||||||
|
|
||||||
import { CozeAssistant } from '../coze-assistant';
|
import { CozeAssistant } from '../coze-assistant';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
enableAiAssistant?: boolean;
|
||||||
|
isMobile?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
defineOptions({ name: 'GlobalProvider' });
|
defineOptions({ name: 'GlobalProvider' });
|
||||||
|
|
||||||
|
withDefaults(defineProps<Props>(), {
|
||||||
|
enableAiAssistant: false,
|
||||||
|
isMobile: false,
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<Toaster />
|
<Toaster />
|
||||||
<CozeAssistant
|
<CozeAssistant v-if="enableAiAssistant" :is-mobile="isMobile" />
|
||||||
v-if="preferences.app.aiAssistant"
|
|
||||||
:is-mobile="preferences.app.isMobile"
|
|
||||||
/>
|
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -26,7 +26,7 @@ const emit = defineEmits<{ close: [] }>();
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const searchHistory = useLocalStorage<MenuRecordRaw[]>(
|
const searchHistory = useLocalStorage<MenuRecordRaw[]>(
|
||||||
`__search-history-${import.meta.env.PROD ? 'prod' : 'dev'}__`,
|
`__search-history-${location.hostname}__`,
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
const activeIndex = ref(-1);
|
const activeIndex = ref(-1);
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
import type { CAC } from 'cac';
|
|
||||||
|
|
||||||
import { extname } from 'node:path';
|
|
||||||
|
|
||||||
import { getStagedFiles } from '@vben/node-utils';
|
|
||||||
|
|
||||||
import { circularDepsDetect, printCircles } from 'circular-dependency-scanner';
|
|
||||||
|
|
||||||
const IGNORE_DIR = [
|
|
||||||
'dist',
|
|
||||||
'.turbo',
|
|
||||||
'output',
|
|
||||||
'.cache',
|
|
||||||
'scripts',
|
|
||||||
'internal',
|
|
||||||
// 'packages/@vben-core/shared/shadcn-ui/',
|
|
||||||
'packages/@vben-core/ui-kit/menu-ui/src/',
|
|
||||||
].join(',');
|
|
||||||
|
|
||||||
const IGNORE = [`**/{${IGNORE_DIR}}/**`];
|
|
||||||
|
|
||||||
interface CommandOptions {
|
|
||||||
staged: boolean;
|
|
||||||
verbose: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function checkCircular({ staged, verbose }: CommandOptions) {
|
|
||||||
const results = await circularDepsDetect({
|
|
||||||
absolute: staged,
|
|
||||||
cwd: process.cwd(),
|
|
||||||
ignore: IGNORE,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (staged) {
|
|
||||||
let files = await getStagedFiles();
|
|
||||||
|
|
||||||
files = files.filter((file) =>
|
|
||||||
['.cjs', '.js', '.jsx', '.mjs', '.ts', '.tsx', '.vue'].includes(
|
|
||||||
extname(file),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
const circularFiles: string[][] = [];
|
|
||||||
|
|
||||||
for (const file of files) {
|
|
||||||
for (const result of results) {
|
|
||||||
const resultFiles = result.flat();
|
|
||||||
if (resultFiles.includes(file)) {
|
|
||||||
circularFiles.push(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
verbose && printCircles(circularFiles);
|
|
||||||
} else {
|
|
||||||
verbose && printCircles(results);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function defineCheckCircularCommand(cac: CAC) {
|
|
||||||
cac
|
|
||||||
.command('check-circular')
|
|
||||||
.option(
|
|
||||||
'--staged',
|
|
||||||
'Whether it is the staged commit mode, in which mode, if there is a circular dependency, an alarm will be given.',
|
|
||||||
)
|
|
||||||
.usage(`Analysis of project circular dependencies.`)
|
|
||||||
.action(async ({ staged }) => {
|
|
||||||
await checkCircular({ staged, verbose: true });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export { defineCheckCircularCommand };
|
|
Loading…
Reference in New Issue