Skip to content

Biome 格式化程序赢得 Prettier 挑战赛

The Prettier challenge banner, with the Biome logo over it The Prettier challenge banner, with the Biome logo over it

随着 Biome v1.4.0 的发布,我们正式启动 Prettier 挑战赛

¥With the release of Biome **v1.4.0 **, we claim the bounty of the Prettier challenge!

使用 v1.4.0,你将获得更佳的格式化体验、更多格式化选项、全新的 VSCode 功能、新的赞助商等等!

¥With v1.4.0, you’ll get a better formatter experience, more formatting options, new VSCode features, new sponsors and more!

你可以通过运行以下命令来升级 Biome:

¥You can upgrade Biome by running the following command:

Terminal window
npm install --save-dev --save-exact @biomejs/biome@1.4.0
pnpm update --save-exact @biomejs/biome@1.4.0
yarn upgrade --exact @biomejs/biome@1.4.0

¥Better formatter

Biome 格式化程序现在与 Prettier 的兼容性已超过 96%!此分数是针对 JavaScript、TypeScript 和 JSX 格式计算的。

¥Biome formatter has now **over 96% in terms of compatibility ** against Prettier! This score is computed for JavaScript, TypeScript, and JSX formatting.

这是 Prettier 的创建者之一 Christopher Chedeau 发起的挑战的成果。

¥Merit of challenge that was launched by Christopher Chedeau, one of the Prettier’s creators.

这项挑战吸引了许多人的关注,其中一些人决定为 Biome 项目做贡献,以领取部分赏金。我看到了一些令人惊叹的东西:贡献者们的协调能力令人惊叹,他们认真负责地承担任务,并在短短几个小时内就交付了解决方案。

¥The challenge attracted the attention of many people, and some of them decided to contribute to Biome to claim part of the bounty. I did see something amazing: contributors had an amazing coordination, they took ownership of the tasks and delivered the solution in a matter of hours.

我认为促成这一切的主要因素有三点:

¥I believe the main factors that made this possible are three:

  1. 货币。这是事实,如果有人决定贡献代码只是为了获得少量报酬,那也完全没问题。

    ¥Money. It’s a fact, and it’s completely fine if someone decides to contribute only for earning a small stipend out of it.

  2. 交流。我们仅使用 GitHub 作为协调媒介。我们提供了交付方式的相关信息、说明和帮助。

    ¥Communication. We used GitHub as only medium of coordination. We provided information, instructions and help on how to deliver.

  3. 基础架构。Biome 依赖于由 previous Rome Tools employeescontributors 构建的强大测试基础架构。它能够捕获所有格式错误,提供细粒度的差异比较,并在输出结果与 Prettier 的输出结果不同时警告用户。

    ¥Infrastructure. Biome relies on a solid testing infrastructure, built by previous Rome Tools employees and contributors. It’s able to catch every reformat bug, provide granular diffs and warn the user if the emitted output is the different from the one emitted by Prettier.

在遇到挑战之前,根据我们的内部指标(JavaScript、TypeScript 和 JSX,基于选项一致性),Biome 的兼容性约为 85%。虽然 85% 看起来很高,但即使是 15% 这样的小数字,对大型代码库的影响也是巨大的。如此多的变更可能会让人感到畏惧,导致早期用户在将 Biome 引入团队时遇到摩擦。我们社区的一位成员分享了一些见解:

¥Before the challenge, Biome had roughly a compatibility rate of 85%, based on our internal metrics (JavaScript, TypeScript and JSX, on options parity). Even though 85% might seem high, the impact of a low number such as 15% on big code bases is huge, and people might feel intimidated by so many changes, causing early adopters to receive frictions when bring Biome to their team. A member of our community shared some insights:

为了更好地说明即使只有最后 5% 的改进对大型代码库(特别是 bracketSpacing 和现在的 bracketSameLine)的提升有多大,我在我们的 monorepo 中的一个项目中运行了它 […]。

¥As a great example of how much even just that last 5% has improved things for large codebases (and specifically with bracketSpacing and now bracketSameLine implemented) i ran it one project in our monorepo […].

就在上周,[diagnostics] 的数量超过了 6000。即使忽略括号选项,组件数量仍然超过 1000 个,而现在只剩下 200 个了!

¥Just last week, this number [diagnostics] was more than 6,000. Even with the bracket options ignored, it was still more than 1000, and now there are only 200 left!

虽然挑战赛已经结束,但我们仍致力于进一步提升 Biome 与 Prettier 的兼容性。我们非常欢迎你在这方面做出任何贡献。

¥Although the challenge is over, we are committed to improve even more the compatibility score with prettier. Any contribution in this regard is very welcome.

这项挑战还揭示了 Prettier 输出的一些情况,我们决定不采用这些情况。我们在网站上创建了一个 新的版块 文件来解释它们。我们希望随着时间的推移,能够精简这部分内容。

¥The challenge has also uncovered some cases in Prettier’s emitted output that we decided to not follow. We have created a new section in our website that explains them. Our hope is to make this section smaller with the time.

如果存在我们网站上未记录的差异,则应将其视为错误并提交问题。

¥If there’s a divergence that isn’t documented in our website, you should consider that a bug and file an issue.

¥New formatting options

为了应对这一挑战,我们为格式化程序添加了新的选项:

¥With this challenge, we added new options to the formatter:

  • lineEnding

    使用此选项匹配操作系统的换行符。我们支持 lf(换行符 - \n)、cr(回车符)。 - \r)和 crlf(回车换行符) - \r\n).

    ¥Use this option to match the line endings of your OS. We support lf (line feed - \n), cr (carriage return - \r) and crlf (carriage return line feed - \r\n).

  • bracketSameLine

    example.js
    // Existing behavior. Now also the default, meaning `bracketSameLine: false`.
    <Foo
    className={somethingReallyLongThatForcesThisToWrap}
    anotherReallyLongAttribute={withAValueThatsSurelyTooLong}
    soThatEverythingWraps
    >
    Hello
    </Foo>
    <Foo
    selfClosingTags={likeThisOne}
    stillPlaceTheBracket={onItsOwnLine}
    toIndicateThat={itClosesItself}
    />

    使用 "bracketSameLine": true 格式化后:

    ¥After formatting with "bracketSameLine": true:

    example.js
    // New behavior, with `bracketSameLine: true`.
    <Foo
    className={somethingReallyLongThatForcesThisToWrap}
    anotherReallyLongAttribute={withAValueThatsSurelyTooLong}
    soThatEverythingWraps>
    Hello
    </Foo>
    <Foo
    selfClosingTags={likeThisOne}
    stillPlaceTheBracket={onItsOwnLine}
    />
  • bracketSpacing

    example.js
    import { sort } from "sort.js";
    const value = { sort };

    使用 "bracketSpacing": false 格式化后:

    ¥After formatting with "bracketSpacing": false:

    example.js
    import {sort} from "sort.js";
    const value = {sort};

¥VSCode extension goodies

VSCode 已迁移到 新的代码仓库

¥The VSCode has been moved to a new repository.

我们从扩展程序中移除了打包的二进制文件,你可以下载所需的版本。以下是一个演示其工作原理的简短视频:

¥We removed the bundled binary from the extension, and you’ll be able to download the version that you want. Here’s a small video of how it works:

从今天起,我们将发布扩展程序的每日构建版本。此版本面向早期用户,用于在正式发布前进行测试。

¥From today, we release a nightly version of the extension. This is a version meant for early adopters and to test things before they are officially released.

¥Some CLI goodies

依赖 Biome LSP 的用户将会很高兴地得知,他们现在可以使用选项 --config-path 将自定义配置传递给命令 lsp-proxy。命令 start 接受相同的选项:

¥People that rely on Biome LSP will be pleased that they can now pass a custom configuration to the command lsp-proxy, using the option --config-path. The same option is accepted by the command start:

Terminal window
biome --config-path=../path/where/config/is lsp-proxy
biome --config-path=../path/where/config/is start

CLI 现在公开了 --diagnostic-level 选项,允许筛选打印到终端的诊断信息类型。

¥The CLI now exposes the option --diagnostic-level, that allows to filter the kind of diagnostics printed to terminal.

Terminal window
biome check --diagnostic-level=error ./src

¥New lint rules, and promoted rule

Biome 也是一个代码检查器,并且它支持 177 条规则!在此版本中,一些规则得到提升,并新增了一些规则。

¥Biome is a linter too, and it features 177 rules! In this release, some rules are promoted and new ones are available.

¥New rules

nursery/noDefaultExport.js:1:8 lint/nursery/noDefaultExport ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

     Avoid default exports.

    > 1 │ export default function f() {};
            ^^^^^^^
      2 │ 

     Default exports cannot be easily discovered inside an editor and don't encourage the use of consistent names through a code base.

     Use a named export instead.

  
nursery/noAriaHiddenOnFocusable.js:1:1 lint/nursery/noAriaHiddenOnFocusable  FIXABLE  ━━━━━━━━━━━━━━

     Disallow aria-hidden="true" from being set on focusable elements.

    > 1 │ <div aria-hidden="true" tabIndex="0" />
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      2 │ 

     aria-hidden should not be set to true on focusable elements because this can lead to confusing behavior for screen reader users.

     Unsafe fix: Remove the aria-hidden attribute from the element.

      1 │ <div·aria-hidden="true"·tabIndex="0"·/>
         -------------------
  
nursery/noImplicitAnyLet.js:1:5 lint/nursery/noImplicitAnyLet ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

     This variable implicitly has the any type.

    > 1 │ var a;
         ^
      2 │ a = 2;
      3 │ 

     Variable declarations without type annotation and initialization have implicitly the any type. Declare type or initialize the variable with some value.

  
  • useAwait

    async function fetchData() {
    // Missing `await` for the promise returned by `fetch`
    return fetch("/data");
    }
nursery/useAwait.js:1:1 lint/nursery/useAwait ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

     This async function lacks an await expression.

    > 1 │ async function fetchData() {
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    > 2 │ // Missing `await` for the promise returned by `fetch`
    > 3 │   return fetch('/data');
    > 4 │ }
     ^
      5 │ 

     Remove this async modifier, or add an await expression in the function.

    > 1 │ async function fetchData() {
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    > 2 │ // Missing `await` for the promise returned by `fetch`
    > 3 │   return fetch('/data');
    > 4 │ }
     ^
      5 │ 

     Async functions without await expressions may not need to be declared async.

  
nursery/useValidAriaRole.js:1:1 lint/nursery/useValidAriaRole  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━

     Enforce that elements with ARIA roles must use a valid, non-abstract ARIA role.

    > 1 │ <div role="datepicker"></div>
     ^^^^^^^^^^^^^^^^^^^^^^^
      2 │ 

     Check WAI-ARIA for valid roles or provide options accordingly.

     Unsafe fix: Remove the invalid role attribute.
       Check the list of all valid role attributes.

      1 │ <div·role="datepicker"></div>
         -----------------
  
new RegExp("abc", "u");
nursery/useRegexLiterals.js:1:1 lint/nursery/useRegexLiterals  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━

   Use a regular expression literal instead of the RegExp constructor.

  > 1 │ new RegExp("abc", "u");
   ^^^^^^^^^^^^^^^^^^^^^^
    2 │ 

   Regular expression literals avoid some escaping required in a string literal, and are easier to analyze statically.

   Safe fix: Use a literal notation instead.

    1  - new·RegExp("abc",·"u");
      1+ /abc/u;
    2 2

¥Recommended rules

a11y/noAccessKey.js:1:22 lint/a11y/noAccessKey  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

     Avoid the accessKey attribute to reduce inconsistencies between keyboard shortcuts and screen reader keyboard comments.

    > 1 │ <input type="submit" accessKey="s" value="Submit" />
                          ^^^^^^^^^^^^^
      2 │ 

     Assigning keyboard shortcuts using the accessKey attribute leads to inconsistent keyboard actions across applications.

     Unsafe fix: Remove the accessKey attribute.

      1 │ <input·type="submit"·accessKey="s"·value="Submit"·/>
                         --------------
  
a11y/useHeadingContent.js:1:1 lint/a11y/useHeadingContent ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

     Provide screen reader accessible content when using heading  elements.

    > 1 │ <h1 />
     ^^^^^^
      2 │ 

     All headings on a page should have content that is accessible to screen readers.

  
complexity/useSimpleNumberKeys.js:1:4 lint/complexity/useSimpleNumberKeys  FIXABLE  ━━━━━━━━━━━━━━━━

     Hexadecimal number literal is not allowed here.

    > 1 │ ({ 0x1: 1 });
        ^^^
      2 │ 

     Safe fix: Replace 0x1 with 1

  1  - ({·0x1:·1·});
    1+ ({·1:·1·});
  2 2

  

¥Promoted rules

¥Deprecated rules

该规则已被 correctness/noInvalidNewBuiltin 替换。

¥The rule is replaced by correctness/noInvalidNewBuiltin

¥Homage to our maintainers

自 Biome 分支以来,有新成员加入了该项目。它们在很多方面都发挥了作用,超乎你的想象:新功能、附属项目、社区互动、支持、文档等等。开源软件不仅仅是编码。

¥Since Biome was forked, new people joined the project. They have been helping with in so many ways that you can’t even imagine: new features, side projects, engaging with the community, support, documentation, and more. OSS is not just about coding.

感谢:

¥Thank you to:

热烈欢迎新加入的维护人员:

¥And a big welcome to our new joined maintainer:

¥New sponsors

最后,我们荣幸地宣布新增两位赞助商:

¥Last but not least, we are proud to announce that we have two new sponsors:

如果你想为本项目做出经济贡献,帮助其开发更多功能,可以通过 GitHub 赞助页面Open Collective 页面 进行捐赠。

¥If you want to economically contribute to the project and help it to ship more features, you can do so from the GitHub Sponsorship page or the Open Collective page.

¥What’s next

该项目发展势头良好,越来越多的人对它感兴趣,也有许多贡献者希望参与其中。

¥The project is thriving, with more people curious about the project and contributors that want to be involved.

在接下来的几个月中,我们将专注于:

¥In the next months we will focus on:

  • 发布路线图。请密切关注,它将涉及许多有趣的工作。

    ¥Publishing a Roadmap. Keep an eye on it, it will involve a lot of interesting work.

  • 网站已使用新徽标进行品牌重塑。

    ¥Rebranding the website with a new logo.

  • 将网站翻译成日语。

    ¥Translate the website in Japanese.

¥Translations