github biomejs/biome @biomejs/biome@2.6.4
Biome CLI v2.6.4

3 hours ago

2.6.4

Patch Changes

  • #12261 19fbfb2 Thanks @dyc3! - Added the new nursery rule noConsoleSpaces, which reports a leading or trailing space in a console.log(), console.debug(), console.info(), console.warn(), or console.error() argument that sits next to another argument. These methods already put a space between arguments, so such a space prints twice.

    console.log("abc ", "def");
  • #12469 cd716d3 Thanks @dyc3! - Added the new nursery rule noMagicArrayFlatDepth, which reports number literals other than 1 passed as the depth of Array.prototype.flat() unless a comment inside the parentheses explains them.

    const items = array.flat(2);
  • #12470 92c9e81 Thanks @dyc3! - Added the nursery rule noNull, which reports uses of the null literal and suggests undefined instead. Strict comparisons such as foo === null are allowed.

    let foo = null;
  • #12483 9bd3527 Thanks @dyc3! - Added the nursery rule noReturnArrayPush, which reports code that uses the return value of push() or unshift(). These methods return the new length of the array, not the added item or the array.

    function add(item) {
      return items.push(item);
    }
  • #12477 a384892 Thanks @dyc3! - Added the nursery rule noUnreadableIife, which reports arrow functions that are called right where they are defined and whose body is wrapped in parentheses.

    const foo = (bar => (bar ? bar.baz : baz))(getBar());
  • #12447 0a963e4 Thanks @dyc3! - Added the nursery rule noUselessRecursion, which reports functions that return a call to themselves when a loop can do the same work. Too many nested calls can crash the program with a stack overflow error.

    function findRoot(node) {
        if (node.parent) {
            return findRoot(node.parent);
        }
        return node;
    }
  • #12554 2eddda9 Thanks @dyc3! - Added the nursery rule noVueComputedPropertiesInData, which reports computed properties used inside the data function of a Vue component. Vue runs data before it sets up computed properties, so the value read there is undefined.

    <script>
    export default {
      data() {
        return { total: this.doubled };
      },
      computed: {
        doubled() {
          return 2;
        },
      },
    };
    </script>
  • #12586 824df15 Thanks @dyc3! - Added the nursery rule noVueDeprecatedDeleteSet, which reports calls to the $set and $delete functions, Vue.set and Vue.delete, and set and del imported from vue. Vue 3 removed these functions, so calling them throws an error.

    <script>
    export default {
      mounted() {
        this.$set(this.user, "name", "Alice");
      },
    };
    </script>
  • #12648 6fc1a51 Thanks @dyc3! - Added the nursery rule noVueDeprecatedRouterLinkTagProp, which disallows the tag prop on RouterLink. Vue Router 4 ignores this prop, so the link still renders as an <a> element.

    <template>
      <RouterLink tag="li" to="/">Home</RouterLink>
    </template>
  • #12631 de1188f Thanks @dyc3! - Added the new nursery rule noVueDeprecatedScopeAttribute, which reports the scope attribute on <template> elements in Vue files. Vue no longer supports this attribute, so use v-slot to receive slot props instead.

    <template>
      <ListComponent>
        <template scope="props">{{ props.title }}</template>
      </ListComponent>
    </template>
  • #12562 5d7553b Thanks @dyc3! - Added the new nursery rule noVueMultipleSlotArgs, which disallows passing more than one argument to a Vue slot from a render function. Slot content written in a template receives only the first argument.

    <script>
    export default {
      render() {
        return this.$slots.default(item, index); // reported
      },
    };
    </script>
  • #12513 2e520d8 Thanks @dyc3! - Added the nursery rule noVueMutatingProps, which reports code that changes the props of a Vue component, in the script or in the template. Props belong to the parent component, so the child should emit an event or copy the value instead.

    <script setup>
    const props = defineProps({ items: Array });
    
    props.items.push("new item");
    </script>
  • #12567 144b786 Thanks @dyc3! - Added the nursery rule noVueSideEffectsInComputed, which reports Vue computed properties that change state. Vue decides when to run a computed property, so changes made inside one happen at unpredictable times.

    <script setup>
    import { computed, ref } from "vue";
    
    const items = ref([]);
    // `reverse()` changes `items.value` in place.
    const reversedItems = computed(() => items.value.reverse());
    </script>
  • #12603 861b288 Thanks @dyc3! - Added the new nursery rule noVueUnusedRefs, which reports template refs in Vue components that nothing reads through $refs, useTemplateRef(), or a variable of the same name in <script setup>. The rule needs html.experimentalFullSupportEnabled to be true.

    <template>
      <input ref="input" />
    </template>
  • #12285 68770e0 Thanks @dyc3! - Added the new nursery rule noYamlBooleanKeys, which disallows boolean values as keys in YAML. For example, the following key is a boolean instead of text, so it is reported:

    true: enabled
  • #12338 f46411b Thanks @dyc3! - Added the nursery rule useSvelteEventDispatcherTypes, which reports createEventDispatcher() calls that don't declare the types of their events in Svelte components written in TypeScript.

    The rule accepts a call that declares its events:

    <script lang="ts">
      import { createEventDispatcher } from "svelte";
    
      const dispatch = createEventDispatcher<{ save: string }>();
    </script>
  • #12615 ade9845 Thanks @dyc3! - Added the nursery rule useVueDefineOptions, which reports the default export of a plain <script> block in Vue components that also use <script setup>, and suggests setting those options with defineOptions() instead.

    <script>
    export default { name: "MyComponent" }; // reported
    </script>
    
    <script setup>
    const props = defineProps(["title"]);
    </script>
  • #12514 e74b4dc Thanks @dyc3! - Added the nursery rule useVueDefinePropsDestructuring, which requires destructuring the props returned by defineProps() in Vue <script setup> blocks. It also reports withDefaults(), because destructured props can set their default values directly.

    <script setup lang="ts">
    const props = defineProps<{ foo?: string }>();
    </script>
  • #12559 94985ba Thanks @dyc3! - Added the nursery rule useVueTemplateRef, which requires useTemplateRef() instead of ref() or shallowRef() to access elements of the template in <script setup>.

    <template>
      <input ref="input" />
    </template>
    
    <script setup>
    import { ref } from "vue";
    
    const input = ref(); // reported
    </script>
  • #12512 6be5078 Thanks @dyc3! - Added the nursery rule useVueTypedProps, which reports Vue props declared without a type, in the props option, defineProps(), or defineModel(). Without a type, Vue accepts any value for the prop and can't warn when a component receives the wrong kind of value.

    <script setup>
    defineProps(["title"]);
    </script>
  • #12653 f307633 Thanks @dyc3! - Added the nursery rule useVueVModel, which reports a prop binding on a Vue component paired with an update: listener that only writes the new value back, and suggests v-model instead.

    <template>
      <MyComponent :title="title" @update:title="title = $event" />
    </template>
  • #12591 a810209 Thanks @dyc3! - Added the nursery rule useVueValidDefineEmits, which enforces valid usage of Vue's defineEmits macro in <script setup>.

    For example, the following code is now reported, because defineEmits declares its events with both a type and an argument:

    <script setup lang="ts">
    const emit = defineEmits<(e: "notify") => void>(["submit"]);
    </script>
  • #12614 9308110 Thanks @dyc3! - Added the nursery rule useVueValidDefineProps, which reports defineProps() calls that Vue can't compile or that declare props incorrectly. For example, it reports a component that calls defineProps() twice, or whose defineProps() argument uses a variable declared in <script setup>:

    <script setup>
    const definition = { msg: String };
    defineProps(definition);
    </script>
  • #12570 222a230 Thanks @dyc3! - Added the nursery rule useVueValidVIs, which reports v-is directives that have an argument or modifiers, have no value, or are used on a component instead of a native HTML element.

    For example, the following v-is directive has no value:

    <template>
      <tr v-is></tr>
    </template>
  • #12521 4010bb7 Thanks @dyc3! - Added the nursery rule useVueValidVMemo, which reports invalid v-memo directives in Vue templates. A v-memo directive must have an array value, can't have an argument or modifiers, and doesn't work inside an element with v-for.

    For example, the following value is an object instead of an array:

    <template>
      <div v-memo="{ id }"></div>
    </template>
  • #12597 aff42a7 Thanks @dyc3! - Added the nursery rule useVueValidVModel, which reports v-model directives that Vue can't use: on unsupported elements or file inputs, with an argument or unknown modifier on a native element, without a value, or with a value that can't be assigned to.

    For example, the following v-model directives are invalid:

    <template>
      <div v-model="foo"></div>
      <input v-model="foo + bar" />
    </template>
  • #12569 3058597 Thanks @dyc3! - Added the new nursery rule useVueValidVShow, which reports v-show directives that have an argument, a modifier, or no value, or that are placed on a <template> element.

    <template v-show="isVisible"><div></div></template>
  • #12525 e2e5a36 Thanks @dyc3! - Added the nursery rule useVueValidVSlot, which reports misplaced, duplicated, or malformed v-slot directives in Vue templates.

    For example, the rule reports two <template> elements that fill the same slot:

    <MyComponent>
      <template #header>First title</template>
      <template #header>Second title</template>
    </MyComponent>
  • #12472 efd16bd Thanks @dyc3! - Added the new nursery rule useWhileLoopCondition, which reports loops such as while (true) and for (;;) that start with an if statement containing only a break, and moves that condition into the while statement.

    while (true) {
      if (!hasMore()) {
        break;
      } // reported
      processNext();
    }
  • #12640 167bb00 Thanks @latin-1! - Updated useSortedProperties to follow stylelint-config-recess-order 7.9.0, adding sorting support for scroll-behavior, anchor positioning, multi-column layout, and other properties known to Biome.

  • #12719 40a82b0 Thanks @dyc3! - Improved the performance of the linter. Biome now spends less time setting up the enabled rules for each file it analyzes.

  • #12722 f074730 Thanks @dyc3! - Improved the performance of biome lint by about 1% to 3% on large projects, most noticeably with Biome's default rules and with rules that track variables or unreachable code.

  • #12501 90a4d74 Thanks @ematipico! - Fixed #12466: the Biome daemon used more memory with every biome check --use-server run. The daemon now reuses the data that it stores for each file and project, and it keeps syntax trees only for the files that it read most recently.

  • #12501 90a4d74 Thanks @ematipico! - Fixed biomejs/biome-vscode#923: when a file open in the editor changed on disk, the language server replaced the editor's text with the text on disk. Biome now keeps the editor's text of open files until they are closed, so diagnostics, code actions and formatting stay at the right positions.

  • #12652 59ff42a Thanks @kurovskyiii! - Fixed #12651: an imported name that the other module exports as both a type and a value now resolves to the type in type annotations, so noBaseToString no longer reports slug below as an object.

    // rule-slug.ts
    export type RuleSlug = string;
    export const RuleSlug = { create: (text: string): RuleSlug => text } as const;
    
    // main.ts
    import { RuleSlug } from "./rule-slug";
    export const label = (slug: RuleSlug): string => `rule ${slug}`;
  • #12678 301402f Thanks @nhedger! - Fixed biomejs/biome-vscode#1113: the language server now shows a warning when the configuration file can't be parsed. Previously, Biome stopped processing files without telling the user why.

  • #12662 8c836eb Thanks @dyc3! - Fixed #12645: the Markdown formatter no longer removes the blank line between a blockquote and the list that follows it, matching Prettier.

    > A note.
    
    - one
    - two
  • #12662 8c836eb Thanks @dyc3! - Fixed #12663: the Markdown formatter no longer removes the blank line between a table and the list that follows it, matching Prettier.

    | Table |
    | ----- |
    | Value |
    
    - Hello
  • #12576 735d370 Thanks @jfmcdowell! - Fixed #12541: Markdown list items whose markers are indented 4 or more spaces now nest at the correct level. Previously the formatter could move such an item under the item before it, or join it to that item's text.

     1. Step
        - a
          - x
    -       - y
    -         - b
    +     - y
    +   - b
  • #12575 0da9080 Thanks @jfmcdowell! - Fixed formatting of Markdown block quotes inside deeply indented list items. With proseWrap: "always", consecutive quote lines now wrap together within the same quote, while setext headings and fenced code blocks keep their structure.

     10. item
    -    > first line
    -    > second line
    +    > first line second line
  • #12607 896d53e Thanks @xucian! - Fixed #12542: the Markdown formatter is no longer idempotent when it formats tables.

    - | a        | b     |
    - | -------- | ----- |
    - | x        | `y` z |
    - | `p` z`q` | r     |
    + | a         | b     |
    + | --------- | ----- |
    + | x         | `y` z |
    + | `p` z `q` | r     |
  • #12692 8ff63f4 Thanks @NikitaCOEUR! - Fixed the linux-x64-musl binary not using jemalloc, which it already ships: it fell back to musl's allocator, and biome check on several threads could take minutes instead of seconds, for example in Alpine-based CI images.

  • #12682 fa7cf4c Thanks @dyc3! - Fixed #12679: when markdown.parser.frontmatter and markdown.formatter.formatEmbeds are enabled, the Markdown formatter keeps the frontmatter of a fenced Markdown code block as written. Previously, it formatted the frontmatter as a thematic break and a paragraph, which removed the indentation of its YAML.

    ```markdown
    ---
    verified:
      by: human
    ---
    # Policy
    ```
  • #12649 343c8ca Thanks @JamBalaya56562! - Fixed #12643 and #12669: Biome now migrates the Prettier option bracketSpacing to formatter.bracketSpacing, both at the top level and inside overrides. JSON and GraphQL files are now formatted with the same bracket spacing as JavaScript files.

  • #12640 167bb00 Thanks @latin-1! - Fixed useSortedProperties to withhold sorting fixes that would change the effective values of overlapping declarations, physical/logical border or corner properties, or declarations followed by all.
    Updated noShorthandPropertyOverrides to recognize logical border, corner shape, position-try, text-box, and transition-behavior overrides.

  • #12723 b6cbec8 Thanks @dyc3! - Improved the performance of biome lint, biome check, and biome ci on files where rules report diagnostics with code fixes, by up to 12% with the default rules.

  • #12664 6021da0 Thanks @MindTooth! - Fixed Biome processing pnpm-lock.yaml files. These generated lockfiles are now protected from processing.

  • #12501 90a4d74 Thanks @ematipico! - Fixed an issue where the CLI, when it ran with --use-server alongside an editor connected to the same daemon, checked the unsaved text of the files open in the editor instead of the files on disk, and could make the editor's text get lost. The CLI now checks the files on disk, and every editor and CLI run connected to the daemon keeps its own text of the files it opens.

  • #12519 9ae56ba Thanks @dyc3! - The rule noVueVIfWithVFor now also reports v-else-if and v-else on the same element as v-for.

    <div v-if="loading">Loading...</div>
    <TodoItem v-else v-for="todo in todos" :todo="todo" />
  • #12702 df0f7cc Thanks @dyc3! - Fixed parsing of default values in Vue v-for bindings. Biome now parses the default value as JavaScript, so it is formatted and linted like other template expressions instead of being reported as a parse error.

    <div v-for="{ value = gt('v-for default') } in rows" />
  • #12656 25a00a2 Thanks @dyc3! - Fixed non-JSON files inside the global settings directories of Zed, VS Code, and Cursor being parsed as JSON.

  • #12501 90a4d74 Thanks @ematipico! - Fixed an issue where the language server kept using the previous parser options for open files after the configuration changed. Open files are now parsed again with the new options, for example json.parser.allowComments.

  • #12656 25a00a2 Thanks @dyc3! - Improved the performance of Biome when it processes many files by up to 7%.

  • #12661 066a077 Thanks @dyc3! - Added the nursery rule noVueDeprecatedListeners. It reports references to $listeners, which Vue 3 removed, in Vue templates and component objects. For example, Biome now reports <div v-on="$listeners" /> and this.$listeners inside a Vue component.

What's Changed

  • feat(lint): add useWhileLoopCondition by @dyc3 in #12472
  • refactor(analyze): remove the rule-count limit on analyzer groups by @dyc3 in #12637
  • fix(migrate): carry Prettier's bracketSpacing in overrides by @JamBalaya56562 in #12649
  • fix(format/md): preserve newline between block quote and list by @dyc3 in #12662
  • feat(lint): add noNull by @dyc3 in #12470
  • fix(migrate): carry Prettier's bracketSpacing into the top-level by @JamBalaya56562 in #12670
  • fix: mark pnpm-lock.yaml as protected file by @MindTooth in #12664
  • fix(markdown_parser): attach whitespace before a table pipe to the pipe by @xucian in #12607
  • feat(lint): add noYamlBooleanKeys by @dyc3 in #12285
  • feat(lint): add noUnreadableIife by @dyc3 in #12477
  • feat(lint): add useSvelteEventDispatcherTypes by @dyc3 in #12338
  • feat(lint): add noMagicArrayFlatDepth by @dyc3 in #12469
  • feat(lint): add noConsoleSpaces by @dyc3 in #12261
  • perf(languages): resolve editor settings directories once, and check less often by @dyc3 in #12656
  • feat(lint): add noUselessRecursion by @dyc3 in #12447
  • fix(css): sync recess property order and preserve cascade when sorting by @latin-1 in #12640
  • feat(lint): add noReturnArrayPush by @dyc3 in #12483
  • fix(lsp): warn when the configuration file can't be loaded by @nhedger in #12678
  • chore(deps): update rust crate notify to 8.2.1 by @renovate[bot] in #12689
  • fix(module_graph): resolve an imported type merged with a value to the type in annotations by @kurovskyiii in #12652
  • fix(markdown): keep frontmatter of fenced Markdown blocks when formatting embeds by @dyc3 in #12682
  • chore(deps): update rust crate serde_json to 1.0.154 by @renovate[bot] in #12690
  • chore(deps): update rust crate smallvec to 1.16.4 by @renovate[bot] in #12691
  • fix(markdown_parser): continue block quotes inside deep list items by @jfmcdowell in #12575
  • chore: update rule metadata by @dyc3 in #12699
  • perf(lint): make noDuplicateCase, noDuplicateElseIf and noFallthroughSwitchClause linear by @dyc3 in #12457
  • perf(lint): speed up useHookAtTopLevel, noUnusedImports and noUnusedPrivateClassMembers by @dyc3 in #12458
  • feat(lint): add useVueTemplateRef by @dyc3 in #12559
  • feat(lint): add useVueValidVShow by @dyc3 in #12569
  • feat(lint): add useVueDefinePropsDestructuring by @dyc3 in #12514
  • feat(lint): add useVueValidVIs by @dyc3 in #12570
  • feat(noVueVIfWithVFor): report v-else and v-else-if with v-for by @dyc3 in #12519
  • feat(lint): add noVueSideEffectsInComputed by @dyc3 in #12567
  • feat(lint): add noVueDeprecatedListeners by @dyc3 in #12661
  • feat(lint): add useVueValidVModel by @dyc3 in #12597
  • feat(lint): add useVueValidVSlot by @dyc3 in #12525
  • fix(markdown_parser): nest list items by enclosing content column by @jfmcdowell in #12576
  • chore(deps): update rust:1.98.0-bullseye docker digest to 4730e38 by @renovate[bot] in #11645
  • feat(lint): add useVueValidVMemo by @dyc3 in #12521
  • feat(lint): add useVueValidDefineProps by @dyc3 in #12614
  • feat(lint): add useVueTypedProps by @dyc3 in #12512
  • feat(lint): add useVueVModel by @dyc3 in #12653
  • feat(lint): add useVueValidDefineEmits by @dyc3 in #12591
  • feat(lint): add noVueDeprecatedRouterLinkTagProp by @dyc3 in #12648
  • chore: move myself to core by @Netail in #12713
  • feat(lint): add useVueDefineOptions by @dyc3 in #12615
  • feat(lint): add noVueMutatingProps by @dyc3 in #12513
  • feat(lint): add noVueDeprecatedScopeAttribute by @dyc3 in #12631
  • feat(lint): add noVueMultipleSlotArgs by @dyc3 in #12562
  • fix(cli): use jemalloc on x86_64 musl by @NikitaCOEUR in #12692
  • feat(lint): add noVueComputedPropertiesInData by @dyc3 in #12554
  • refactor: source text as input by @ematipico in #12501
  • refactor(core): scanner epoch and LRU eviction by @ematipico in #12694
  • perf(rowan): read node text from the green tree by @dyc3 in #12723
  • fix(parse/html/vue): parse v-for binding default values by @dyc3 in #12702
  • chore: fix advisory by @dyc3 in #12730
  • perf(rowan): iterate SyntaxKindSet by scanning set bits by @dyc3 in #12719
  • perf(rowan): resolve syntax node pointers through the green tree and near a known node by @dyc3 in #12722
  • feat(lint): add noVueUnusedRefs by @dyc3 in #12603
  • feat(lint): add noVueDeprecatedDeleteSet by @dyc3 in #12586
  • ci: release by @github-actions[bot] in #12647

New Contributors

Full Changelog: https://github.com/biomejs/biome/compare/@biomejs/biome@2.6.3...@biomejs/biome@2.6.4

Don't miss a new biome release

NewReleases is sending notifications on new releases.