chore(quality): 接入 ESLint 与 GitLab CI,开启严格未用检查,构建期设计令牌守卫
- eslint.config.mjs(flat config):react-hooks/react-refresh/tseslint;自定义 no-restricted-syntax 规则禁止 className 手拼基元类名(error 级,JSXAttribute 选择器精确限定,探针双向验证)与硬编码色值 - tsconfig:noUnusedLocals/noUnusedParameters 置 true - package.json 新增 typecheck/lint/test/verify:tokens 脚本;build 串联令牌校验(verify-tokens.sh 防止 <alpha-value> 类静默失效回归);pnpm-lock.yaml 入库供 CI --frozen-lockfile - .gitlab-ci.yml:lint/typecheck/test/build 四作业,MR 与默认分支触发,dist 产物留存一周
This commit is contained in:
+104
@@ -0,0 +1,104 @@
|
|||||||
|
# Profeto CI —— 首次引入自动化质量防线。
|
||||||
|
#
|
||||||
|
# 背景:此前仓库无任何 CI。唯一的测试文件 frontend/src/lib/http.test.ts
|
||||||
|
# 从未被自动执行过,类型检查也仅靠本地手跑 tsc。本流水线把
|
||||||
|
# 「类型检查 + 单元测试 + 构建」固化为 MR 门禁。
|
||||||
|
#
|
||||||
|
# 复用项目自带的 Docker 镜像(与 docker-compose.yml 同源),
|
||||||
|
# 避免 CI 环境与本地/线上不一致。
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- verify
|
||||||
|
|
||||||
|
default:
|
||||||
|
image: node:22-alpine
|
||||||
|
|
||||||
|
# ── 前端:Lint ────────────────────────────────────────────────────
|
||||||
|
# 拦截「机器能看出来、人容易漏掉」的问题:幻影 CSS 变体、
|
||||||
|
# 硬编码色值、渲染期间副作用、未使用符号。
|
||||||
|
# 当前基线为 0 error / 56 warning,故本 job 会真实失败于新增 error。
|
||||||
|
frontend-lint:
|
||||||
|
stage: verify
|
||||||
|
before_script:
|
||||||
|
- cd frontend
|
||||||
|
- corepack enable
|
||||||
|
- pnpm install --frozen-lockfile
|
||||||
|
script:
|
||||||
|
- pnpm lint
|
||||||
|
cache:
|
||||||
|
key:
|
||||||
|
files:
|
||||||
|
- frontend/pnpm-lock.yaml
|
||||||
|
paths:
|
||||||
|
- frontend/node_modules/
|
||||||
|
rules:
|
||||||
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||||
|
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
||||||
|
|
||||||
|
# ── 前端:类型检查 ────────────────────────────────────────────────
|
||||||
|
frontend-typecheck:
|
||||||
|
stage: verify
|
||||||
|
before_script:
|
||||||
|
- cd frontend
|
||||||
|
- corepack enable
|
||||||
|
- pnpm install --frozen-lockfile
|
||||||
|
script:
|
||||||
|
- pnpm typecheck
|
||||||
|
# 缓存 pnpm store,避免每次 MR 重新下载依赖
|
||||||
|
cache:
|
||||||
|
key:
|
||||||
|
files:
|
||||||
|
- frontend/pnpm-lock.yaml
|
||||||
|
paths:
|
||||||
|
- frontend/node_modules/
|
||||||
|
rules:
|
||||||
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||||
|
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
||||||
|
|
||||||
|
# ── 前端:单元测试 ────────────────────────────────────────────────
|
||||||
|
# 这是 http.test.ts 第一次被自动化调用。它覆盖 HTTP 层的
|
||||||
|
# method/body/Content-Type 组装与 /health 免前缀豁免 —— 后者的
|
||||||
|
# 回归会导致管理后台右上角永远显示「系统异常」。
|
||||||
|
frontend-test:
|
||||||
|
stage: verify
|
||||||
|
before_script:
|
||||||
|
- cd frontend
|
||||||
|
- corepack enable
|
||||||
|
- pnpm install --frozen-lockfile
|
||||||
|
script:
|
||||||
|
- pnpm test
|
||||||
|
cache:
|
||||||
|
key:
|
||||||
|
files:
|
||||||
|
- frontend/pnpm-lock.yaml
|
||||||
|
paths:
|
||||||
|
- frontend/node_modules/
|
||||||
|
rules:
|
||||||
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||||
|
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
||||||
|
|
||||||
|
# ── 前端:生产构建 ────────────────────────────────────────────────
|
||||||
|
# 独立于 typecheck:构建会暴露类型检查覆盖不到的问题
|
||||||
|
# (Tailwind 配置错误、资源缺失、chunk 拆分失败等)。
|
||||||
|
frontend-build:
|
||||||
|
stage: verify
|
||||||
|
before_script:
|
||||||
|
- cd frontend
|
||||||
|
- corepack enable
|
||||||
|
- pnpm install --frozen-lockfile
|
||||||
|
script:
|
||||||
|
- pnpm build
|
||||||
|
artifacts:
|
||||||
|
name: "frontend-dist-$CI_COMMIT_SHORT_SHA"
|
||||||
|
paths:
|
||||||
|
- frontend/dist/
|
||||||
|
expire_in: 1 week
|
||||||
|
cache:
|
||||||
|
key:
|
||||||
|
files:
|
||||||
|
- frontend/pnpm-lock.yaml
|
||||||
|
paths:
|
||||||
|
- frontend/node_modules/
|
||||||
|
rules:
|
||||||
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||||
|
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
||||||
@@ -0,0 +1,236 @@
|
|||||||
|
/**
|
||||||
|
* ESLint 配置 —— 工程的自动化质量防线。
|
||||||
|
*
|
||||||
|
* 本文件的核心目的不只是「常规 lint」,而是把审查报告里
|
||||||
|
* 「只能靠人肉 review 发现」的几类问题固化成机器规则:
|
||||||
|
*
|
||||||
|
* 1. 幻影变体:此前 `btn-ghost` 被使用但从未在 CSS 中定义,
|
||||||
|
* 样式静默失效,类型检查和构建都不报错。
|
||||||
|
* 2. 裸控件:components/ui 已提供 Button/Input/Select 基元,
|
||||||
|
* 但页面里仍有人直接写原生标签 + 手拼 className,
|
||||||
|
* 导致样式与无障碍行为再次分叉。
|
||||||
|
* 3. 硬编码色值:设计令牌是唯一颜色来源,十六进制字面量
|
||||||
|
* 会让改令牌时产生「漏网之鱼」。
|
||||||
|
*
|
||||||
|
* 规则原则:宁可少而准,不要多而吵。无法修复的告警只会被忽略。
|
||||||
|
*/
|
||||||
|
|
||||||
|
import js from '@eslint/js'
|
||||||
|
import globals from 'globals'
|
||||||
|
import reactHooks from 'eslint-plugin-react-hooks'
|
||||||
|
import reactRefresh from 'eslint-plugin-react-refresh'
|
||||||
|
import tseslint from 'typescript-eslint'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CSS 变体类名总表 —— index.css 的 @layer components 里定义的全部类。
|
||||||
|
*
|
||||||
|
* 分两组,因为二者的处置方式完全不同:
|
||||||
|
*
|
||||||
|
* - `PRIMITIVE_CLASSES`:已有组件基元等价物(Button / Input / Select / Tabs)。
|
||||||
|
* 页面里**手拼**这些类名 = 绕过基元,样式与无障碍行为会再次分叉。
|
||||||
|
* 这类用法由 `no-restricted-syntax` 报错拦截。
|
||||||
|
*
|
||||||
|
* - `COMPOSITE_CLASSES`:组合型排版类(类似 Tailwind 工具类),
|
||||||
|
* 本就设计成裸用(如 `className="section-head mb-2"`)。
|
||||||
|
* 它们没有、也不该有组件基元,因此不拦截。
|
||||||
|
*
|
||||||
|
* 之所以要专门拦「单独出现」而非子串匹配:因为 `btn` 是 `btn-solid`
|
||||||
|
* 的前缀,`tab` 是 `tab-on` 的前缀。只有被当作独立 token 使用时才是问题。
|
||||||
|
*/
|
||||||
|
const PRIMITIVE_CLASSES = [
|
||||||
|
// Button 基元覆盖
|
||||||
|
'btn',
|
||||||
|
'btn-sm',
|
||||||
|
'btn-solid',
|
||||||
|
'btn-outline',
|
||||||
|
'btn-danger',
|
||||||
|
'btn-ghost',
|
||||||
|
// Input / Select 基元覆盖
|
||||||
|
'field',
|
||||||
|
// Tabs 基元覆盖
|
||||||
|
'tab',
|
||||||
|
'tab-on',
|
||||||
|
]
|
||||||
|
|
||||||
|
const COMPOSITE_CLASSES = [
|
||||||
|
'section-head',
|
||||||
|
'skeleton',
|
||||||
|
'empty-state',
|
||||||
|
'empty-state-title',
|
||||||
|
'empty-state-sub',
|
||||||
|
'empty-state-action',
|
||||||
|
'error-banner',
|
||||||
|
'error-banner-title',
|
||||||
|
'error-banner-detail',
|
||||||
|
'nav-icon',
|
||||||
|
'masthead-rule',
|
||||||
|
'font-brush',
|
||||||
|
]
|
||||||
|
|
||||||
|
/** 保留导出,兼容既有引用;内容为全部组件类名。 */
|
||||||
|
const CSS_VARIANT_CLASSES = [...PRIMITIVE_CLASSES, ...COMPOSITE_CLASSES]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 匹配「className 值里单独出现的某个基元类名」的正则。
|
||||||
|
*
|
||||||
|
* 只匹配独立 token(前后必须是空白或字符串边界),避免两类误判:
|
||||||
|
* - `btn-solid` 里的 `btn`(前缀子串,合法,由 Button 基元自己输出)
|
||||||
|
* - `searchParams.get('tab')` 这类**非样式**字符串
|
||||||
|
* —— 这正是不能用裸正则扫全量 Literal 的原因(第一版曾误报)。
|
||||||
|
*
|
||||||
|
* 该正则只配合下面的 AST 选择器使用:
|
||||||
|
* `JSXAttribute[name.name="className"] Literal[...]` 把匹配范围
|
||||||
|
* 严格限定在 className 属性值内,字符串里出现同名 token 不再误伤。
|
||||||
|
*/
|
||||||
|
function barePrimitivePattern() {
|
||||||
|
const names = PRIMITIVE_CLASSES.join('|')
|
||||||
|
return new RegExp(`(^|\\s)(${names})(?=\\s|$)`)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default tseslint.config(
|
||||||
|
{
|
||||||
|
// 只检查 TS/TSX。CSS 由 Tailwind/PostCSS 管线负责,
|
||||||
|
// 交给 ESLint 解析只会得到 "Declaration expected" 噪声。
|
||||||
|
// 配置类文件自身不参与 lint(它们是规则的声明方,不是被约束方)。
|
||||||
|
ignores: ['dist', 'node_modules', '*.config.js', '*.config.mjs', '*.config.ts'],
|
||||||
|
},
|
||||||
|
|
||||||
|
js.configs.recommended,
|
||||||
|
...tseslint.configs.recommended,
|
||||||
|
|
||||||
|
// ── 全局:浏览器环境 ────────────────────────────────────────────
|
||||||
|
{
|
||||||
|
files: ['src/**/*.{ts,tsx}'],
|
||||||
|
languageOptions: {
|
||||||
|
ecmaVersion: 2022,
|
||||||
|
globals: {
|
||||||
|
...globals.browser,
|
||||||
|
...globals.es2022,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
'react-hooks': reactHooks,
|
||||||
|
'react-refresh': reactRefresh,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
...reactHooks.configs.recommended.rules,
|
||||||
|
|
||||||
|
// ── hooks 规则调整 ───────────────────────────────────────────
|
||||||
|
// `set-state-in-effect`:加载类 effect(挂载时发起请求 → 回调里
|
||||||
|
// setState)是 React 官方文档明确认可的模式,该规则在此场景下
|
||||||
|
// 误报率过高。当前有 19 处这类写法,逐条改写属于行为等价的
|
||||||
|
// 大范围重构,不适合混在本次质量修复里。降级为 warn 保留可见性。
|
||||||
|
// 注:真正的「渲染期间副作用」已由 react-hooks/purity 单独拦下
|
||||||
|
// (Collection.tsx 里的 Date.now() 即被它捕获并已修复)。
|
||||||
|
'react-hooks/set-state-in-effect': 'warn',
|
||||||
|
|
||||||
|
// ── 死代码 ───────────────────────────────────────────────────
|
||||||
|
// tsconfig 里 noUnusedLocals/noUnusedParameters 是关的
|
||||||
|
// (存量太多,一次性打开会淹没信号)。这里先用 ESLint 的
|
||||||
|
// 同型规则,允许下划线前缀显式豁免,便于渐进清理。
|
||||||
|
'@typescript-eslint/no-unused-vars': [
|
||||||
|
'warn',
|
||||||
|
{
|
||||||
|
argsIgnorePattern: '^_',
|
||||||
|
varsIgnorePattern: '^_',
|
||||||
|
caughtErrorsIgnorePattern: '^_',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
// ── 类型安全 ─────────────────────────────────────────────────
|
||||||
|
// `any` 在数据访问层是真实的类型漏洞来源(dal.ts 曾有 14 处)。
|
||||||
|
// 用 warn 而非 error:存量需要分批处理,但不该被遗忘。
|
||||||
|
'@typescript-eslint/no-explicit-any': 'warn',
|
||||||
|
|
||||||
|
// 空接口等价于无约束类型参数,通常是想写 type 而非 interface
|
||||||
|
'@typescript-eslint/no-empty-object-type': 'warn',
|
||||||
|
|
||||||
|
// ── React ────────────────────────────────────────────────────
|
||||||
|
// 本仓库是纯 SPA(无 RSC、无服务端渲染),Fast Refresh 的粒度为
|
||||||
|
// 整个模块。兼容壳文件(admin/components.tsx、matches/ui.tsx)与
|
||||||
|
// 混装常量+组件的文件会命中此规则,但它们本就是刻意保留的
|
||||||
|
// 再导出层,热更新退化不影响开发体验。关闭以免噪声掩盖真问题。
|
||||||
|
'react-refresh/only-export-components': 'off',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── 组件基元层:自身必然使用原生标签,豁免相关规则 ──────────────
|
||||||
|
{
|
||||||
|
files: ['src/components/ui/**'],
|
||||||
|
rules: {
|
||||||
|
'react-refresh/only-export-components': 'off',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── 禁止硬编码设计令牌色值 + 禁止手拼组件基元类名 ────────────────
|
||||||
|
{
|
||||||
|
files: ['src/**/*.{ts,tsx}'],
|
||||||
|
// 组件基元层自身必然要写这些类名 —— 它是唯一的合法使用点
|
||||||
|
ignores: ['src/components/ui/**'],
|
||||||
|
rules: {
|
||||||
|
'no-restricted-syntax': [
|
||||||
|
// error 级:两类问题(硬编码色值、手拼基元类名)存量均已清零,
|
||||||
|
// 此后任何新增都应在提交前就地修正,CI 可直接阻断。
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
selector: 'Literal[value=/^#[0-9a-fA-F]{3,8}$/]',
|
||||||
|
message:
|
||||||
|
'禁止硬编码颜色字面量。请使用设计令牌(press/ink/paper 等)或 CSS 变量。',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
selector: 'TemplateElement[value.raw=/rgba?\\(/]',
|
||||||
|
message:
|
||||||
|
'禁止在模板字符串中硬编码 rgb/rgba 颜色。请使用设计令牌或 CSS 变量。',
|
||||||
|
},
|
||||||
|
// ── 手拼基元类名 ────────────────────────────────────────────
|
||||||
|
// error 级:这类写法会让组件层形同虚设,且样式/无障碍分叉
|
||||||
|
// 只在运行时显形,类型检查完全沉默。合法写点(components/ui)
|
||||||
|
// 已被本块的 ignores 排除。
|
||||||
|
//
|
||||||
|
// 用 JSXAttribute 选择器把范围钉死在 className 属性值上:
|
||||||
|
// 裸 `Literal[...]` 会误伤 `searchParams.get('tab')` 这类
|
||||||
|
// 恰好含同名 token 的普通字符串。两种写法分别覆盖:
|
||||||
|
// className="field w-full" → String Literal
|
||||||
|
// className={`btn ${x ? 'btn-solid' : ''}`} → TemplateLiteral
|
||||||
|
{
|
||||||
|
selector: `JSXAttribute[name.name="className"] Literal[value=/${barePrimitivePattern().source}/]`,
|
||||||
|
message:
|
||||||
|
'禁止手拼组件基元类名(btn/field/tab 系列)。请改用 components/ui 的 Button / Input / Select / Tabs 基元 —— 它们统一了变体与无障碍行为。',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
selector: `JSXAttribute[name.name="className"] TemplateElement[value.raw=/${barePrimitivePattern().source}/]`,
|
||||||
|
message:
|
||||||
|
'禁止在模板字符串中手拼组件基元类名(btn/field/tab 系列)。请改用 components/ui 的基元组件。',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// 色值豁免:调色板与主题定义是颜色「来源」,不是「使用点」
|
||||||
|
{
|
||||||
|
files: [
|
||||||
|
'src/index.css',
|
||||||
|
'tailwind.config.js',
|
||||||
|
'src/components/ui/**',
|
||||||
|
],
|
||||||
|
rules: {
|
||||||
|
'no-restricted-syntax': 'off',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── 测试文件 ────────────────────────────────────────────────────
|
||||||
|
{
|
||||||
|
files: ['src/**/*.test.{ts,tsx}'],
|
||||||
|
languageOptions: {
|
||||||
|
globals: {
|
||||||
|
...globals.node,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'@typescript-eslint/no-explicit-any': 'off',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
// 导出变体列表供后续规则扩展使用,避免魔法字符串散落
|
||||||
|
export { CSS_VARIANT_CLASSES }
|
||||||
+12
-2
@@ -5,8 +5,12 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "tsc && vite build",
|
"build": "tsc && vite build && sh scripts/verify-tokens.sh",
|
||||||
"preview": "vite preview"
|
"preview": "vite preview",
|
||||||
|
"typecheck": "tsc --noEmit",
|
||||||
|
"lint": "eslint \"src/**/*.{ts,tsx}\"",
|
||||||
|
"test": "node --experimental-strip-types --test \"src/**/*.test.ts\"",
|
||||||
|
"verify:tokens": "sh scripts/verify-tokens.sh"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
@@ -14,13 +18,19 @@
|
|||||||
"react-router-dom": "^6.30.6"
|
"react-router-dom": "^6.30.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@eslint/js": "^10.0.1",
|
||||||
"@types/react": "^18.3.3",
|
"@types/react": "^18.3.3",
|
||||||
"@types/react-dom": "^18.3.0",
|
"@types/react-dom": "^18.3.0",
|
||||||
"@vitejs/plugin-react": "^4.3.1",
|
"@vitejs/plugin-react": "^4.3.1",
|
||||||
"autoprefixer": "^10.4.19",
|
"autoprefixer": "^10.4.19",
|
||||||
|
"eslint": "^9.39.5",
|
||||||
|
"eslint-plugin-react-hooks": "^7.1.1",
|
||||||
|
"eslint-plugin-react-refresh": "^0.5.7",
|
||||||
|
"globals": "^17.12.0",
|
||||||
"postcss": "^8.4.39",
|
"postcss": "^8.4.39",
|
||||||
"tailwindcss": "^3.4.6",
|
"tailwindcss": "^3.4.6",
|
||||||
"typescript": "^5.5.3",
|
"typescript": "^5.5.3",
|
||||||
|
"typescript-eslint": "^8.70.1",
|
||||||
"vite": "^5.3.4"
|
"vite": "^5.3.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+2601
File diff suppressed because it is too large
Load Diff
Executable
+46
@@ -0,0 +1,46 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# 设计令牌完整性守卫 —— 确认关键颜色类真的生成了 CSS。
|
||||||
|
#
|
||||||
|
# 背景:把商标色改为 CSS 变量时踩过一个坑 —— 变量若写成完整十六进制
|
||||||
|
# (#9E1B1B)而非 RGB 三元组(158 27 27),Tailwind 的透明度修饰符
|
||||||
|
# (bg-press-wash/60)会**静默不生成任何 CSS**。构建通过、类型检查通过、
|
||||||
|
# 控制台无警告,只是样式没了。这类问题只能靠检查产物发现。
|
||||||
|
#
|
||||||
|
# 用法: pnpm build && sh scripts/verify-tokens.sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
CSS=$(ls dist/assets/*.css 2>/dev/null | head -1)
|
||||||
|
if [ -z "$CSS" ]; then
|
||||||
|
echo "✗ 未找到构建产物 CSS,请先执行 pnpm build"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
fail=0
|
||||||
|
check() {
|
||||||
|
if grep -q -F -- "$1" "$CSS"; then
|
||||||
|
echo " ✓ $1"
|
||||||
|
else
|
||||||
|
echo " ✗ $1 缺失"
|
||||||
|
fail=1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "校验设计令牌在构建产物中的存在性:"
|
||||||
|
check '.bg-press{'
|
||||||
|
check '.text-ink-900{'
|
||||||
|
check '.bg-paper-50{'
|
||||||
|
check '.border-press{'
|
||||||
|
check 'press-wash\/60'
|
||||||
|
check '.masthead-rule{'
|
||||||
|
check '--press:'
|
||||||
|
|
||||||
|
if [ "$fail" -ne 0 ]; then
|
||||||
|
echo ""
|
||||||
|
echo "设计令牌校验失败。"
|
||||||
|
echo "最常见原因:tailwind.config.js 中颜色值未写成"
|
||||||
|
echo " 'rgb(var(--x) / <alpha-value>)'"
|
||||||
|
echo "而写成了完整十六进制或 'var(--x)' —— 前者会丢掉透明度修饰符。"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "设计令牌校验通过"
|
||||||
@@ -12,8 +12,8 @@
|
|||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"jsx": "react-jsx",
|
"jsx": "react-jsx",
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"noUnusedLocals": false,
|
"noUnusedLocals": true,
|
||||||
"noUnusedParameters": false,
|
"noUnusedParameters": true,
|
||||||
"noFallthroughCasesInSwitch": true
|
"noFallthroughCasesInSwitch": true
|
||||||
},
|
},
|
||||||
"include": ["src"],
|
"include": ["src"],
|
||||||
|
|||||||
Reference in New Issue
Block a user