/
githubmirror
/
styled-components
Обзор
Документация
Войти
/
githubmirror
/
styled-components
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
biome.jsonc
190 строк
9 KB
Evan Jacobs
build: close two holes in the effect gate
08 авг 2026, 01:36
08 авг 2026, 01:36
4fcf7e3
Код
Авторство
О чём код?
{ "$schema": "https://biomejs.dev/schemas/2.5.7/schema.json", // The effect ban. `no-effects` covers every file the linter sees. The // `useInsertionEffect` fence names its exceptions below rather than in prose, // so "stylesheet writes only" is enforced instead of asserted. // // Suppress with `biome-ignore lint/plugin/<file stem>:`. The stem is // validated, so a typo still reports the error rather than passing silently, // and `biome-ignore-start`/`-end` ranges work. The exclusion globs must be // `**/`-prefixed; a repo-root-relative path silently excludes nothing. // Tests are exempt from both. A test that renders a consumer component // calling useEffect is exercising the guarantee, not breaking it: the // promise is that this library adds no effects of its own, never that a // consumer below a styled component cannot have them. "plugins": [ { "path": "./.biome/no-effects.grit", "includes": ["**", "!**/test/**", "!**/*.test.*"] }, { "path": "./.biome/no-insertion-effect.grit", "includes": [ "**", "!**/test/**", "!**/*.test.*", "!**/models/StyledComponent.ts", "!**/constructors/createGlobalStyle.ts" ] } ], "vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": true }, // One exclusion list for every Biome tool. Scoping it under `formatter` would // make it a formatter-only fact, so enabling anything else later would read // generated corpora and build output. // // `ignoreUnknown` because Biome has no Markdown or YAML formatter yet, so // those files are not understood rather than misformatted; skip them instead // of reporting each one. The CHANGELOG and lockfile entries below are for when // that changes. "files": { "ignoreUnknown": true, "includes": [ "**", "!**/__snapshots__", "!**/node_modules", "!**/dist", "!**/native/dist", "!**/plugins/dist", "!**/coverage", "!**/CHANGELOG.md", "!**/pnpm-lock.yaml", "!packages/styled-components/src/utils/errors.ts", "!packages/styled-components/src/parser/wpt-corpus/raw", "!packages/styled-components/src/parser/wpt-corpus/corpus.json", "!**/vendor/bundle", "!**/.bundle", "!**/ios/build", "!**/android/build", "!**/.gradle" ] }, // Only the settings that differ from Biome's defaults, which are the settings // the old .prettierrc carried. `expand` is the exception: `auto` is the // default everywhere EXCEPT package.json, which Biome expands unless told // otherwise, so stating it is what keeps package.json arrays on one line. "formatter": { "enabled": true, "indentStyle": "space", "lineWidth": 100, "expand": "auto", "useEditorconfig": true }, // Library source only, and rules opted into one at a time. // // `correctness/useHookAtTopLevel` is on, with every legitimate placement // carrying a suppression that states why it is safe. The rule is syntactic, // so it cannot tell a data-dependent condition from a build-time constant and // reports all 33 gates on `__SERVER__`, `IS_RSC` and `__DEV__`. Annotating // them beats disabling the rule: each suppression documents a decision at the // site, and anything new is still caught. Verified by planting a // data-dependent conditional hook in an already-suppressed file and watching // it fail. // // Suppress a legitimate placement with a reason naming the constant that // makes the branch stable, and prefer a `biome-ignore-start`/`-end` range for // a whole block behind one build-constant gate. Never reach for a suppression // to quiet a condition that depends on props, state or context; that is the // bug the rule exists to find. The render cache's hit/miss branch is the one // this codebase invites, and `src/test/memoization.test.tsx` gates it by // comparing recorded hook sequences, which the rule alone cannot do. // // Wanted but blocked on pre-existing violations, mostly in test files: // `correctness/noUnusedImports` (30), `suspicious/useIterableCallbackReturn` // (10), `suspicious/noDoubleEquals` (4). See them with // `biome lint . --only=<rule>`. The first would have caught a dead import in // this very change, so it is worth a dedicated pass. "linter": { "enabled": true, "includes": ["packages/styled-components/src/**", "packages/styled-components/scripts/**"], // MUST NOT be "none". A domain of "none" switches its rules off even when a // rule is named "error" under `rules` below, so `useHookAtTopLevel` went // silent while its 33 suppressions stayed in place and CI still passed the // rule. `--only=correctness/useHookAtTopLevel` bypasses the domain and does // report, so a spot check with `--only` cannot detect this: verify by // planting a conditional hook and running a PLAIN `biome ci`. // // "recommended" rather than "all": "all" adds ~150 style and perf opinions // this repo has not opted into (`useComponentExportOnlyModules`, // `noJsxPropsBind`, `noLeakedRender` and kin). "domains": { "react": "recommended" }, "rules": { "preset": "none", "complexity": { "noUselessCatch": "error", "noUselessLoneBlockStatements": "error", "noUselessSwitchCase": "error", // Load-bearing for the effect ban below, not only tidiness. A GritQL // pattern matches the callee text, so `React['useEffect'](…)` slips // past `no-effects.grit` while `React.useEffect(…)` does not. This // rule rejects the computed spelling outright, which leaves only // `React[someVariable](…)` uncovered, and that is beyond any static // rule. Verified by planting all four spellings and running `biome ci`. "useLiteralKeys": "error" }, "correctness": { // Arrived with the react domain, which carries its own recommended set // that `"recommended": false` above does not reach. Off deliberately: // both fight decisions this repo already made and documented. // // `noChildrenProp`: the SSR and RSC paths build a `<style>` prop bag // programmatically, so `children` belongs in the object. // `useExhaustiveDependencies`: it wants `renderDeps` inlined in // createGlobalStyle, which exists so a static global skips effect // re-runs, and it wants the `globalStyle` dep dropped, which was added // to fix HMR cleanup. "noChildrenProp": "off", "useExhaustiveDependencies": "off", "noConstantCondition": "error", "noInvalidUseBeforeDeclaration": "error", "noPrecisionLoss": "error", "noSwitchDeclarations": "error", "noUnreachable": "error", "useHookAtTopLevel": "error", "noVoidTypeReturn": "error" }, "style": { // The other half of the effect ban. The GritQL plugin matches a call, // so it sees `React.useEffect(...)` and a bare `useEffect(...)`, but it // cannot see the import that produced the bare name. This rule closes // that spelling. Not theoretical: `native/responsive.ts` already // imports hooks by name. "noRestrictedImports": { "level": "error", "options": { "paths": { "react": { "importNames": ["useEffect", "useLayoutEffect"], "message": "This library performs no work in a passive or layout effect. Use a ref callback for attach or teardown, useSyncExternalStore for external state, or useInsertionEffect for stylesheet writes only." } } } } }, "suspicious": { // Also from the react domain. The five hits are all test fixtures with // a fixed, non-reordering list, where the index is a stable key. Worth // turning on if it ever reaches library source; see the hits with // `biome lint . --only=suspicious/noArrayIndexKey`. "noArrayIndexKey": "off", "noDuplicateCase": "error", "noDuplicateObjectKeys": "error", "noDuplicateParameters": "error", "noFallthroughSwitchClause": "error", "noSparseArray": "error", "noUnsafeNegation": "error", "useDefaultSwitchClauseLast": "error" } } }, "javascript": { "formatter": { "trailingCommas": "es5", "quoteStyle": "single", "arrowParentheses": "asNeeded" } }, // Import sorting is off on purpose: it is not what Prettier did, and this // codebase has side-effect imports whose order is load-bearing. "assist": { "enabled": false } }