mirror of https://github.com/usememos/memos
chore(web): migrate from ESLint+Prettier to Biome
- Install @biomejs/biome@2.3.5 as unified linter and formatter - Remove ESLint, Prettier and all related plugins (221 packages removed) - Migrate linting rules from ESLint to Biome configuration - Migrate formatting rules from Prettier to Biome configuration - Exclude auto-generated proto files from linting (src/types/proto/**) - Exclude CSS files from Biome (Tailwind syntax not yet supported) - Update package.json scripts: - lint: tsc + biome check - lint:fix: biome check --write - format: biome format --write - Auto-fix import organization across 60+ files - Fix duplicate key in Russian locale (ru.json) - Update CLAUDE.md documentation to reflect Biome usage Benefits: - 10-100x faster linting performance - Simplified toolchain with single configuration file - 221 fewer npm dependencies - Unified linting, formatting, and import organizationpull/5259/head
parent
64111369d3
commit
156908c77f
@ -1,8 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
printWidth: 140,
|
|
||||||
useTabs: false,
|
|
||||||
semi: true,
|
|
||||||
singleQuote: false,
|
|
||||||
plugins: [require.resolve("@trivago/prettier-plugin-sort-imports")],
|
|
||||||
importOrder: ["<BUILTIN_MODULES>", "<THIRD_PARTY_MODULES>", "^@/((?!css).+)", "^[./]", "^(.+).css"],
|
|
||||||
};
|
|
||||||
@ -0,0 +1,202 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://biomejs.dev/schemas/2.3.5/schema.json",
|
||||||
|
"vcs": {
|
||||||
|
"enabled": true,
|
||||||
|
"clientKind": "git",
|
||||||
|
"useIgnoreFile": true
|
||||||
|
},
|
||||||
|
"files": {
|
||||||
|
"includes": [
|
||||||
|
"**",
|
||||||
|
"!!**/dist",
|
||||||
|
"!src/types/proto"
|
||||||
|
],
|
||||||
|
"ignoreUnknown": true
|
||||||
|
},
|
||||||
|
"formatter": {
|
||||||
|
"enabled": true,
|
||||||
|
"formatWithErrors": false,
|
||||||
|
"indentStyle": "space",
|
||||||
|
"indentWidth": 2,
|
||||||
|
"lineEnding": "lf",
|
||||||
|
"lineWidth": 140,
|
||||||
|
"attributePosition": "auto",
|
||||||
|
"bracketSameLine": false,
|
||||||
|
"bracketSpacing": true,
|
||||||
|
"expand": "auto",
|
||||||
|
"useEditorconfig": true
|
||||||
|
},
|
||||||
|
"linter": {
|
||||||
|
"enabled": true,
|
||||||
|
"rules": {
|
||||||
|
"recommended": false,
|
||||||
|
"complexity": {
|
||||||
|
"noAdjacentSpacesInRegex": "error",
|
||||||
|
"noExtraBooleanCast": "error",
|
||||||
|
"noUselessCatch": "error",
|
||||||
|
"noUselessEscapeInRegex": "error",
|
||||||
|
"noUselessTypeConstraint": "error"
|
||||||
|
},
|
||||||
|
"correctness": {
|
||||||
|
"noConstAssign": "error",
|
||||||
|
"noConstantCondition": "error",
|
||||||
|
"noEmptyCharacterClassInRegex": "error",
|
||||||
|
"noEmptyPattern": "error",
|
||||||
|
"noGlobalObjectCalls": "error",
|
||||||
|
"noInvalidBuiltinInstantiation": "error",
|
||||||
|
"noInvalidConstructorSuper": "error",
|
||||||
|
"noNonoctalDecimalEscape": "error",
|
||||||
|
"noPrecisionLoss": "error",
|
||||||
|
"noSelfAssign": "error",
|
||||||
|
"noSetterReturn": "error",
|
||||||
|
"noSwitchDeclarations": "error",
|
||||||
|
"noUndeclaredVariables": "error",
|
||||||
|
"noUnreachable": "error",
|
||||||
|
"noUnreachableSuper": "error",
|
||||||
|
"noUnsafeFinally": "error",
|
||||||
|
"noUnsafeOptionalChaining": "error",
|
||||||
|
"noUnusedLabels": "error",
|
||||||
|
"noUnusedPrivateClassMembers": "error",
|
||||||
|
"noUnusedVariables": "error",
|
||||||
|
"useIsNan": "error",
|
||||||
|
"useValidForDirection": "error",
|
||||||
|
"useValidTypeof": "error",
|
||||||
|
"useYield": "error"
|
||||||
|
},
|
||||||
|
"style": {
|
||||||
|
"noCommonJs": "error",
|
||||||
|
"noNamespace": "error",
|
||||||
|
"useArrayLiterals": "error",
|
||||||
|
"useAsConstAssertion": "error",
|
||||||
|
"useBlockStatements": "off"
|
||||||
|
},
|
||||||
|
"suspicious": {
|
||||||
|
"noAsyncPromiseExecutor": "error",
|
||||||
|
"noCatchAssign": "error",
|
||||||
|
"noClassAssign": "error",
|
||||||
|
"noCompareNegZero": "error",
|
||||||
|
"noConstantBinaryExpressions": "error",
|
||||||
|
"noControlCharactersInRegex": "error",
|
||||||
|
"noDebugger": "error",
|
||||||
|
"noDuplicateCase": "error",
|
||||||
|
"noDuplicateClassMembers": "error",
|
||||||
|
"noDuplicateElseIf": "error",
|
||||||
|
"noDuplicateObjectKeys": "error",
|
||||||
|
"noDuplicateParameters": "error",
|
||||||
|
"noEmptyBlockStatements": "off",
|
||||||
|
"noExplicitAny": "off",
|
||||||
|
"noExtraNonNullAssertion": "error",
|
||||||
|
"noFallthroughSwitchClause": "error",
|
||||||
|
"noFunctionAssign": "error",
|
||||||
|
"noGlobalAssign": "error",
|
||||||
|
"noImportAssign": "error",
|
||||||
|
"noIrregularWhitespace": "error",
|
||||||
|
"noMisleadingCharacterClass": "error",
|
||||||
|
"noMisleadingInstantiator": "error",
|
||||||
|
"noNonNullAssertedOptionalChain": "error",
|
||||||
|
"noPrototypeBuiltins": "error",
|
||||||
|
"noRedeclare": "error",
|
||||||
|
"noShadowRestrictedNames": "error",
|
||||||
|
"noSparseArray": "error",
|
||||||
|
"noUnsafeDeclarationMerging": "error",
|
||||||
|
"noUnsafeNegation": "error",
|
||||||
|
"noUselessRegexBackrefs": "error",
|
||||||
|
"noWith": "error",
|
||||||
|
"useGetterReturn": "error",
|
||||||
|
"useNamespaceKeyword": "error"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"includes": [
|
||||||
|
"**",
|
||||||
|
"!**/dist/**",
|
||||||
|
"!**/node_modules/**",
|
||||||
|
"!src/types/proto/**"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"javascript": {
|
||||||
|
"formatter": {
|
||||||
|
"jsxQuoteStyle": "double",
|
||||||
|
"quoteProperties": "asNeeded",
|
||||||
|
"trailingCommas": "all",
|
||||||
|
"semicolons": "always",
|
||||||
|
"arrowParentheses": "always",
|
||||||
|
"bracketSameLine": false,
|
||||||
|
"quoteStyle": "double",
|
||||||
|
"attributePosition": "auto",
|
||||||
|
"bracketSpacing": true
|
||||||
|
},
|
||||||
|
"globals": []
|
||||||
|
},
|
||||||
|
"css": {
|
||||||
|
"parser": {
|
||||||
|
"cssModules": false,
|
||||||
|
"allowWrongLineComments": true,
|
||||||
|
"tailwindDirectives": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"html": {
|
||||||
|
"formatter": {
|
||||||
|
"indentScriptAndStyle": false,
|
||||||
|
"selfCloseVoidElements": "always"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"includes": [
|
||||||
|
"**/*.ts",
|
||||||
|
"**/*.tsx",
|
||||||
|
"**/*.mts",
|
||||||
|
"**/*.cts"
|
||||||
|
],
|
||||||
|
"linter": {
|
||||||
|
"rules": {
|
||||||
|
"complexity": {
|
||||||
|
"noArguments": "error"
|
||||||
|
},
|
||||||
|
"correctness": {
|
||||||
|
"noConstAssign": "off",
|
||||||
|
"noGlobalObjectCalls": "off",
|
||||||
|
"noInvalidBuiltinInstantiation": "off",
|
||||||
|
"noInvalidConstructorSuper": "off",
|
||||||
|
"noSetterReturn": "off",
|
||||||
|
"noUndeclaredVariables": "off",
|
||||||
|
"noUnreachable": "off",
|
||||||
|
"noUnreachableSuper": "off"
|
||||||
|
},
|
||||||
|
"style": {
|
||||||
|
"useConst": "error"
|
||||||
|
},
|
||||||
|
"suspicious": {
|
||||||
|
"noClassAssign": "off",
|
||||||
|
"noDuplicateClassMembers": "off",
|
||||||
|
"noDuplicateObjectKeys": "off",
|
||||||
|
"noDuplicateParameters": "off",
|
||||||
|
"noFunctionAssign": "off",
|
||||||
|
"noImportAssign": "off",
|
||||||
|
"noRedeclare": "off",
|
||||||
|
"noUnsafeNegation": "off",
|
||||||
|
"noVar": "error",
|
||||||
|
"noWith": "off",
|
||||||
|
"useGetterReturn": "off"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"includes": [
|
||||||
|
"src/utils/i18n.ts"
|
||||||
|
],
|
||||||
|
"linter": {
|
||||||
|
"rules": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"assist": {
|
||||||
|
"enabled": true,
|
||||||
|
"actions": {
|
||||||
|
"source": {
|
||||||
|
"organizeImports": "on"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,34 +0,0 @@
|
|||||||
import eslint from "@eslint/js";
|
|
||||||
import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended";
|
|
||||||
import tseslint from "typescript-eslint";
|
|
||||||
|
|
||||||
export default [
|
|
||||||
...tseslint.config(eslint.configs.recommended, tseslint.configs.recommended),
|
|
||||||
eslintPluginPrettierRecommended,
|
|
||||||
{
|
|
||||||
ignores: ["**/dist/**", "**/node_modules/**", "**/proto/**"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
rules: {
|
|
||||||
"no-unused-vars": "off",
|
|
||||||
"@typescript-eslint/no-unused-vars": "error",
|
|
||||||
"@typescript-eslint/no-explicit-any": ["off"],
|
|
||||||
"react/react-in-jsx-scope": "off",
|
|
||||||
"react/jsx-no-target-blank": "off",
|
|
||||||
"no-restricted-syntax": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
selector:
|
|
||||||
"VariableDeclarator[init.callee.name='useTranslation'] > ObjectPattern > Property[key.name='t']:not([parent.declarations.0.init.callee.object.name='i18n'])",
|
|
||||||
message: "Destructuring 't' from useTranslation is not allowed. Please use the 'useTranslate' hook from '@/utils/i18n'.",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
files: ["src/utils/i18n.ts"],
|
|
||||||
rules: {
|
|
||||||
"no-restricted-syntax": "off",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,25 +1,22 @@
|
|||||||
// Main component
|
// Main component
|
||||||
export { default } from "./MasonryView";
|
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
export { MINIMUM_MEMO_VIEWPORT_WIDTH, REDISTRIBUTION_DEBOUNCE_MS } from "./constants";
|
||||||
|
// Utilities
|
||||||
|
export { distributeItemsToColumns } from "./distributeItems";
|
||||||
// Sub-components (exported for testing or advanced usage)
|
// Sub-components (exported for testing or advanced usage)
|
||||||
export { MasonryColumn } from "./MasonryColumn";
|
export { MasonryColumn } from "./MasonryColumn";
|
||||||
export { MasonryItem } from "./MasonryItem";
|
export { MasonryItem } from "./MasonryItem";
|
||||||
|
export { default } from "./MasonryView";
|
||||||
// Hooks
|
|
||||||
export { useMasonryLayout } from "./useMasonryLayout";
|
|
||||||
|
|
||||||
// Utilities
|
|
||||||
export { distributeItemsToColumns } from "./distributeItems";
|
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
export type {
|
export type {
|
||||||
MasonryViewProps,
|
|
||||||
MasonryItemProps,
|
|
||||||
MasonryColumnProps,
|
|
||||||
DistributionResult,
|
DistributionResult,
|
||||||
MemoWithHeight,
|
MasonryColumnProps,
|
||||||
|
MasonryItemProps,
|
||||||
|
MasonryViewProps,
|
||||||
MemoRenderContext,
|
MemoRenderContext,
|
||||||
|
MemoWithHeight,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
// Hooks
|
||||||
// Constants
|
export { useMasonryLayout } from "./useMasonryLayout";
|
||||||
export { MINIMUM_MEMO_VIEWPORT_WIDTH, REDISTRIBUTION_DEBOUNCE_MS } from "./constants";
|
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
export * from "./useLoading";
|
|
||||||
export * from "./useCurrentUser";
|
|
||||||
export * from "./useNavigateTo";
|
|
||||||
export * from "./useAsyncEffect";
|
export * from "./useAsyncEffect";
|
||||||
export * from "./useResponsiveWidth";
|
export * from "./useCurrentUser";
|
||||||
|
export * from "./useFilteredMemoStats";
|
||||||
|
export * from "./useLoading";
|
||||||
export * from "./useMemoFilters";
|
export * from "./useMemoFilters";
|
||||||
export * from "./useMemoSorting";
|
export * from "./useMemoSorting";
|
||||||
export * from "./useFilteredMemoStats";
|
export * from "./useNavigateTo";
|
||||||
|
export * from "./useResponsiveWidth";
|
||||||
|
|||||||
Loading…
Reference in New Issue