mirror of
https://github.com/langgenius/dify.git
synced 2026-07-19 16:38:31 +08:00
chore: migrate static checks to vp check (#38850)
This commit is contained in:
parent
b03385ffb0
commit
e35187f376
@ -126,8 +126,8 @@ For the current file being tested:
|
||||
|
||||
- [ ] Run full directory test: `pnpm test path/to/directory/`
|
||||
- [ ] Check coverage report: `pnpm test:coverage`
|
||||
- [ ] Run `pnpm lint:fix` on all test files
|
||||
- [ ] Run `pnpm type-check`
|
||||
- [ ] Run `pnpm check:fix`
|
||||
- [ ] Run `pnpm check`
|
||||
|
||||
## Common Issues to Watch
|
||||
|
||||
|
||||
12
.github/workflows/autofix.yml
vendored
12
.github/workflows/autofix.yml
vendored
@ -169,19 +169,13 @@ jobs:
|
||||
if: github.event_name != 'merge_group' && steps.frontend-contract-changes.outputs.any_changed == 'true'
|
||||
run: pnpm --dir packages/contracts gen-api-contract
|
||||
|
||||
- name: Oxlint autofix
|
||||
if: github.event_name != 'merge_group' && steps.web-changes.outputs.any_changed == 'true'
|
||||
run: |
|
||||
pnpm lint:oxlint:fix --prune-suppressions --quiet || true
|
||||
|
||||
- name: ESLint fallback autofix
|
||||
if: github.event_name != 'merge_group' && steps.web-changes.outputs.any_changed == 'true'
|
||||
run: |
|
||||
pnpm lint:eslint:fix --quiet || true
|
||||
run: pnpm lint:eslint:fix --quiet || true
|
||||
|
||||
- name: Format frontend files
|
||||
- name: Vite+ static autofix
|
||||
if: github.event_name != 'merge_group' && (steps.web-changes.outputs.any_changed == 'true' || steps.frontend-contract-changes.outputs.any_changed == 'true')
|
||||
run: vp fmt
|
||||
run: vp check --fix || true
|
||||
|
||||
- if: github.event_name != 'merge_group'
|
||||
uses: autofix-ci/action@c5b2d67aa2274e7b5a18224e8171550871fc7e4a # v1.3.4
|
||||
|
||||
14
.github/workflows/style.yml
vendored
14
.github/workflows/style.yml
vendored
@ -137,7 +137,7 @@ jobs:
|
||||
|
||||
ts-common-style:
|
||||
name: TS Common
|
||||
runs-on: depot-ubuntu-24.04
|
||||
runs-on: depot-ubuntu-24.04-4
|
||||
permissions:
|
||||
checks: write
|
||||
pull-requests: read
|
||||
@ -176,17 +176,9 @@ jobs:
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
uses: ./.github/actions/setup-web
|
||||
|
||||
- name: Format check
|
||||
- name: Static check
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: vp fmt --check
|
||||
|
||||
- name: Style check
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: pnpm -w lint:ci
|
||||
|
||||
- name: Type check
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: pnpm -w type-check
|
||||
run: pnpm -w check
|
||||
|
||||
superlinter:
|
||||
name: SuperLinter
|
||||
|
||||
@ -31,7 +31,7 @@ The codebase is split into:
|
||||
## Language Style
|
||||
|
||||
- **Python**: Keep type hints on functions and attributes, and implement relevant special methods (e.g., `__repr__`, `__str__`). Prefer `TypedDict` over `dict` or `Mapping` for type safety and better code documentation.
|
||||
- **TypeScript**: Use the strict config, format with `vp fmt`, run `pnpm lint` for Oxlint code checks plus ESLint non-code checks, run `pnpm type-check`, and avoid `any` types.
|
||||
- **TypeScript**: Use the strict config, run `pnpm check` for formatting, Oxlint, ESLint non-code checks, and type checking, and avoid `any` types.
|
||||
|
||||
## General Practices
|
||||
|
||||
|
||||
@ -57,10 +57,8 @@ pnpm install # one-time
|
||||
pnpm dev <command> [args...] # run CLI from source (no -- separator)
|
||||
pnpm test # vitest
|
||||
pnpm test:coverage # with coverage
|
||||
pnpm -w type-check # repository-wide type check
|
||||
pnpm -w lint # repository-wide lint
|
||||
pnpm -w lint:fix # repository-wide lint fixes
|
||||
vp fmt # format with Oxfmt
|
||||
pnpm -w check # repository-wide static check
|
||||
pnpm -w check:fix # repository-wide static fixes
|
||||
pnpm build # production bundle (vp pack)
|
||||
pnpm tree:gen # regenerate src/commands/tree.ts (registry)
|
||||
pnpm tree:check # verify tree.ts is up-to-date with the fs
|
||||
@ -72,7 +70,7 @@ Release binaries (5 platform targets, Bun-compiled) are produced by `pnpm build:
|
||||
|
||||
- Behavior tests run against real Hono mock at `test/fixtures/dify-mock/`. No `nock`, `msw`, or `fetchMock` — every test exercises real HTTP.
|
||||
- Test files co-located: `foo.test.ts` next to `foo.ts`.
|
||||
- Repository-wide type-check and lint, plus the full test suite, must be green before any commit.
|
||||
- The repository-wide static check and full test suite must be green before any commit.
|
||||
|
||||
## Spec docs (`docs/specs/`)
|
||||
|
||||
|
||||
@ -306,10 +306,8 @@ expect(JSON.parse(out).workspaces).toHaveLength(2)
|
||||
| `pnpm dev <cmd> [args]` | Run CLI from source during dev |
|
||||
| `pnpm test` | Full vitest suite — run before every commit |
|
||||
| `pnpm test:coverage` | Coverage report |
|
||||
| `pnpm -w type-check` | Repository-wide TypeScript type check |
|
||||
| `pnpm -w lint` | Repository-wide Oxlint and ESLint checks |
|
||||
| `pnpm -w lint:fix` | Repository-wide Oxlint and ESLint fixes |
|
||||
| `vp fmt` | Oxfmt formatting and import sorting |
|
||||
| `pnpm -w check` | Repository-wide static check |
|
||||
| `pnpm -w check:fix` | Repository-wide static fixes |
|
||||
| `pnpm build` | Production bundle (`vp pack`) |
|
||||
| `pnpm tree:gen` | Regenerate `src/commands/tree.ts` (registry) |
|
||||
| `pnpm tree:check` | Verify `tree.ts` matches the filesystem |
|
||||
@ -333,7 +331,7 @@ The repository runs Vite+ Oxlint as the primary code-quality linter, an explicit
|
||||
| `unicorn/no-new-array` | Use `Array.from({ length: n })` not `new Array(n)` |
|
||||
| `noUncheckedIndexedAccess` (tsc) | `arr[i]` is `T \| undefined`; guard before use |
|
||||
|
||||
Run `pnpm -w lint:fix` for Oxlint and ESLint fixes, then `vp fmt` so Oxfmt produces the final layout.
|
||||
Run `pnpm -w check:fix` for Oxlint, ESLint, TypeScript, and Oxfmt fixes and diagnostics.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -12,6 +12,7 @@ import { defineConfig, globalIgnores } from 'eslint/config'
|
||||
import dify from './web/plugins/eslint/index.js'
|
||||
|
||||
const codeFiles = '**/*.{js,cjs,mjs,jsx,ts,cts,mts,tsx}'
|
||||
const mdPlugin = /** @type {import('eslint').ESLint.Plugin} */ (/** @type {unknown} */ (md))
|
||||
|
||||
/**
|
||||
* Migration tradeoff: ESLint is intentionally restricted to non-code files.
|
||||
@ -385,7 +386,7 @@ export default defineConfig([
|
||||
plugins: {
|
||||
markdown,
|
||||
'markdown-preferences': markdownPreferences,
|
||||
md,
|
||||
md: mdPlugin,
|
||||
},
|
||||
rules: {
|
||||
'markdown/fenced-code-language': 'off',
|
||||
|
||||
@ -91,7 +91,7 @@ export const lintConfig = {
|
||||
reportUnusedDisableDirectives: 'warn',
|
||||
respectEslintDisableDirectives: false,
|
||||
typeAware: true,
|
||||
typeCheck: false,
|
||||
typeCheck: true,
|
||||
},
|
||||
settings: {
|
||||
'better-tailwindcss': {
|
||||
|
||||
@ -3,15 +3,10 @@
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"check": "vp check && pnpm lint:eslint",
|
||||
"check:fix": "pnpm lint:eslint:fix && vp check --fix",
|
||||
"dev": "concurrently -k -n vinext,proxy \"vp run dify-web#dev:vinext\" \"vp run dify-web#dev:proxy\"",
|
||||
"fmt": "vp fmt",
|
||||
"fmt:check": "vp fmt --check",
|
||||
"prepare": "vp config",
|
||||
"type-check": "vp run -r type-check",
|
||||
"lint": "pnpm lint:oxlint && pnpm lint:eslint",
|
||||
"lint:ci": "pnpm lint:oxlint && pnpm lint:eslint",
|
||||
"lint:fix": "pnpm lint:oxlint:fix && pnpm lint:eslint:fix",
|
||||
"lint:quiet": "pnpm lint:oxlint:quiet && pnpm lint:eslint:quiet",
|
||||
"lint:oxlint": "vp lint",
|
||||
"lint:oxlint:fix": "vp lint --fix",
|
||||
"lint:oxlint:quiet": "vp lint --quiet",
|
||||
|
||||
1
packages/dify-ui/src/styles.d.ts
vendored
Normal file
1
packages/dify-ui/src/styles.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
declare module '*.css'
|
||||
@ -3,6 +3,13 @@
|
||||
"compilerOptions": {
|
||||
"types": ["vite-plus/test/globals", "vite-plus/test/matchers"]
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.tsx", "vite.config.ts"],
|
||||
"include": [
|
||||
".storybook/**/*.ts",
|
||||
".storybook/**/*.tsx",
|
||||
"src/**/*.ts",
|
||||
"src/**/*.tsx",
|
||||
"vite.config.ts",
|
||||
"vitest.config.ts"
|
||||
],
|
||||
"exclude": ["node_modules", "dist", "storybook-static", "coverage"]
|
||||
}
|
||||
|
||||
@ -4,10 +4,9 @@ import { lintConfig } from './lint.config'
|
||||
const lintFiles = '*.{js,cjs,mjs,jsx,ts,cts,mts,tsx}'
|
||||
const eslintFiles = '*.{json,jsonc,json5,md,yml,yaml,toml}'
|
||||
const formatOnlyFiles = '*.{mdx,css,scss,less,html,vue,svelte,gql,graphql,hbs,handlebars}'
|
||||
const lintFix = 'vp lint --fix --no-error-on-unmatched-pattern'
|
||||
const checkFix = 'vp check --fix --no-error-on-unmatched-pattern'
|
||||
const eslintFix =
|
||||
'eslint --fix --pass-on-unpruned-suppressions --no-error-on-unmatched-pattern --no-warn-ignored'
|
||||
const format = 'vp fmt --no-error-on-unmatched-pattern'
|
||||
|
||||
const nonFrontendIgnores = [
|
||||
'.agents/**',
|
||||
@ -47,9 +46,9 @@ const formatterUnstableInputs = ['web/app/components/develop/template/*.mdx']
|
||||
export default defineConfig({
|
||||
lint: lintConfig,
|
||||
staged: {
|
||||
[lintFiles]: [lintFix, format],
|
||||
[eslintFiles]: [eslintFix, format],
|
||||
[formatOnlyFiles]: format,
|
||||
[lintFiles]: checkFix,
|
||||
[eslintFiles]: [eslintFix, checkFix],
|
||||
[formatOnlyFiles]: checkFix,
|
||||
},
|
||||
fmt: {
|
||||
ignorePatterns: [...nonFrontendIgnores, ...generatedIgnores, ...formatterUnstableInputs],
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import type { Preview } from '@storybook/react'
|
||||
import type { Decorator, Preview } from '@storybook/react'
|
||||
import type { Resource } from 'i18next'
|
||||
import { ToastHost } from '@langgenius/dify-ui/toast'
|
||||
import { withThemeByDataAttribute } from '@storybook/addon-themes'
|
||||
@ -24,7 +24,7 @@ const storyResources: Resource = {
|
||||
},
|
||||
}
|
||||
|
||||
export const decorators = [
|
||||
export const decorators: Decorator[] = [
|
||||
withThemeByDataAttribute({
|
||||
themes: {
|
||||
light: 'light',
|
||||
|
||||
@ -37,7 +37,6 @@ describe('useDocumentActions', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
|
||||
// Setup all mocks with default values
|
||||
const createMockMutation = () => ({
|
||||
mutateAsync: mockMutateAsync,
|
||||
isPending: false,
|
||||
@ -1,50 +1,38 @@
|
||||
# Format and Lint Guide
|
||||
# Static Check Guide
|
||||
|
||||
We use Vite+ Oxfmt for formatting, Vite+ Oxlint for code-quality linting, ESLint for non-code file types that Oxlint cannot parse, and TypeScript for type safety.
|
||||
Vite+ provides the primary static check through `vp check`, which combines Oxfmt formatting, Oxlint code-quality rules, and TypeScript diagnostics. The root command also runs ESLint for non-code file types that Oxlint cannot parse.
|
||||
|
||||
## Format
|
||||
## Check
|
||||
|
||||
Format the supported frontend and TypeScript workspace files from the repository root:
|
||||
Run the complete repository check from the root:
|
||||
|
||||
```sh
|
||||
vp fmt
|
||||
pnpm check
|
||||
```
|
||||
|
||||
Check formatting without writing changes:
|
||||
Apply safe fixes before running the same checks:
|
||||
|
||||
```sh
|
||||
vp fmt --check
|
||||
pnpm check:fix
|
||||
```
|
||||
|
||||
The shared formatter options and ignore boundaries live in the root `vite.config.ts`.
|
||||
Editor format-on-save must point Oxc at that file so local edits match the commit hook and CI.
|
||||
CI and local development use the same root `vite.config.ts` configuration.
|
||||
|
||||
## Lint
|
||||
|
||||
Run the repository lint from the root:
|
||||
For a smaller code scope, pass paths directly to Vite+:
|
||||
|
||||
```sh
|
||||
pnpm lint
|
||||
vp check web/app/components packages/dify-ui/src/button
|
||||
vp check --fix web/app/components packages/dify-ui/src/button
|
||||
```
|
||||
|
||||
Run the two lint paths separately when targeting a smaller scope:
|
||||
Run the ESLint fallback separately when targeting JSON, JSONC, JSON5, YAML, TOML, or Markdown:
|
||||
|
||||
```sh
|
||||
pnpm lint:oxlint web/app/components packages/dify-ui/src/button
|
||||
pnpm lint:eslint package.json pnpm-workspace.yaml web/docs
|
||||
```
|
||||
|
||||
Apply safe fixes, then format the result:
|
||||
|
||||
```sh
|
||||
pnpm lint:oxlint:fix web/app/components
|
||||
pnpm lint:eslint:fix package.json pnpm-workspace.yaml web/docs
|
||||
vp fmt web/app/components
|
||||
```
|
||||
|
||||
Use `pnpm lint:quiet` to hide warnings from both linters. Oxlint runs in parallel by default, and the root ESLint scripts enable automatic concurrency.
|
||||
|
||||
The default and CI lint commands do not pass file lists on the command line. Oxlint's repository scope is defined by `lint.config.ts` `ignorePatterns`, and ESLint's scope is defined by `eslint.config.mjs` global ignores. The individual linter commands above accept explicit paths for ad hoc local subsets.
|
||||
Oxlint and Vite+ type-check scope is defined by `lint.config.ts` `ignorePatterns`, and ESLint's scope is defined by `eslint.config.mjs` global ignores.
|
||||
|
||||
The primary rule baseline lives in `lint.config.ts` and is connected through the root `vite.config.ts` `lint` block. Oxlint-native rules are preferred, and compatible ESLint rules can run through Oxlint's `jsPlugins` support. The rules are explicit snapshots of the ESLint configurations that were active at migration time. Do not import an upstream preset wholesale: enable a new rule intentionally and review its existing violations first.
|
||||
|
||||
@ -52,13 +40,13 @@ The non-code baseline and its repository-wide file scope live in `eslint.config.
|
||||
|
||||
### Auto-fix Workflow
|
||||
|
||||
Configure the Oxc and ESLint editor extensions to apply their respective fixes on save. The commit hook runs `vp staged`: JavaScript and TypeScript pass through Oxlint and Oxfmt, while data and Markdown files pass through ESLint and Oxfmt. The autofix workflow also prunes resolved bulk suppressions.
|
||||
Configure the Oxc and ESLint editor extensions to apply their respective fixes on save. The commit hook runs `vp staged`, which delegates staged files to `vp check --fix` and adds the ESLint fallback for non-code files. The autofix workflow uses the same combined Vite+ check.
|
||||
|
||||
Always review automatic fixes before committing. JS plugins are allowed to provide fixes, and their behavior is not necessarily identical to a native Oxlint rule.
|
||||
|
||||
### Type-aware Linting
|
||||
|
||||
The root configuration enables `typeAware` without enabling Oxlint's full `typeCheck` diagnostics. This preserves the Node SDK's existing type-aware lint rules without making lint duplicate the repository type-check task.
|
||||
The root configuration enables both `typeAware` and `typeCheck`, so `vp check` runs type-aware rules and full TypeScript diagnostics through the TypeScript Go toolchain.
|
||||
|
||||
The web package still runs its existing TSSLint rule separately:
|
||||
|
||||
@ -66,10 +54,10 @@ The web package still runs its existing TSSLint rule separately:
|
||||
pnpm --dir web lint:tss
|
||||
```
|
||||
|
||||
Run the regular type check before committing or pushing:
|
||||
Run the complete static check before committing or pushing:
|
||||
|
||||
```sh
|
||||
pnpm type-check
|
||||
pnpm check
|
||||
```
|
||||
|
||||
### Bulk Suppressions
|
||||
@ -99,8 +87,8 @@ ESLint is intentionally limited to non-code files. The remaining limitations and
|
||||
| Area | Current status |
|
||||
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Code-only fallback rules | ESLint globally ignores all code files. Six core fallback rules, JS `dot-notation`, and other code-only ESLint checks are listed only in comments rather than executable configuration. |
|
||||
| Declaration files | Oxlint excludes declaration files and ESLint no longer processes code. The former 223-rule declaration snapshot and CLI declaration import restriction are not enforced; TypeScript still checks these files. |
|
||||
| Generated contracts | Both linters ignore `packages/contracts/**`; Oxfmt remains the only staged quality step for the contracts package. |
|
||||
| Declaration files | Oxlint excludes declaration files and ESLint no longer processes code. The former 223-rule declaration snapshot and CLI declaration import restriction are not enforced. |
|
||||
| Generated contracts | Both linters and Vite+ type checking ignore `packages/contracts/**`; Oxfmt remains the only staged quality step for the contracts package. |
|
||||
| Non-JavaScript formats | Oxlint plugins cannot provide custom parsers or file languages. ESLint covers JSON, JSONC, YAML, TOML, and Markdown semantic rules, while Oxfmt remains responsible for their formatting. |
|
||||
| Markdown code blocks | ESLint validates the Markdown document, but fenced JavaScript and TypeScript blocks are not passed through the former overlapping preset. This remains deferred rather than duplicating the Oxlint rule set. |
|
||||
| Override-scoped settings | The three Dify UI Tailwind rules are disabled with the rest of ESLint's code path. Oxlint still applies the web `react-x.additionalStateHooks` setting globally because it cannot scope settings to an override. |
|
||||
@ -114,14 +102,14 @@ Prefer a native Oxlint rule. If none exists, verify that the rule works through
|
||||
|
||||
For overlay import policy and composition rules, see [Overlay Guide].
|
||||
|
||||
## Type Check
|
||||
## Type Checking
|
||||
|
||||
You should be able to see suggestions from TypeScript in your editor for all open files.
|
||||
|
||||
Run the repository type check from the root:
|
||||
Type checking is part of the repository check:
|
||||
|
||||
```sh
|
||||
pnpm type-check
|
||||
pnpm check
|
||||
```
|
||||
|
||||
Type checking is powered by [`tsgo`] (the native TypeScript 7 compiler), which is significantly faster than `tsc`.
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
"dev:proxy": "dev-proxy --config ./dev-proxy.config.ts --env-file ./.env.local",
|
||||
"dev:vinext": "vinext dev",
|
||||
"gen-doc-paths": "tsx ./scripts/gen-doc-paths.ts && vp fmt types/doc-paths.ts",
|
||||
"gen-icons": "pnpm --filter @dify/iconify-collections generate && node ./scripts/gen-icons.mjs && pnpm -w lint:oxlint:fix -- web/app/components/base/icons/src/ && vp fmt app/components/base/icons/src/",
|
||||
"gen-icons": "pnpm --filter @dify/iconify-collections generate && node ./scripts/gen-icons.mjs && pnpm -w exec vp check --fix web/app/components/base/icons/src/",
|
||||
"i18n:check": "tsx ./scripts/check-i18n.js",
|
||||
"i18n:migrate-selectors": "tsx ./scripts/migrate-i18n-selectors.ts",
|
||||
"i18n:prune-unused": "tsx ./scripts/prune-unused-i18n.ts",
|
||||
|
||||
@ -13,6 +13,8 @@
|
||||
},
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
".storybook/**/*.ts",
|
||||
".storybook/**/*.tsx",
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
".next/types/**/*.ts",
|
||||
|
||||
2
web/types/assets.d.ts
vendored
2
web/types/assets.d.ts
vendored
@ -1,3 +1,5 @@
|
||||
declare module '*.css'
|
||||
|
||||
declare module '*.svg' {
|
||||
const value: any
|
||||
export default value
|
||||
|
||||
Loading…
Reference in New Issue
Block a user