原文:biomejs.dev/blog/biome-… 。以下为翻译。
随着 Biome v1.4.0
的发布,我们赢得了 Prettier 挑战 的奖金!
在 v1.4.0
中,你将获得更好的格式化体验,更多的格式化选项,新的 VSCode 功能,新的赞助商等等!
你可以通过运行以下命令来升级 Biome:
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
更好的格式化器
Biome 格式化器现在在与 Prettier 的兼容性上达到了 超过 96%!这个分数是针对 JavaScript、TypeScript 和 JSX 格式化计算的。
这是由 Christopher Chedeau,Prettier 的创造者之一发起的挑战的功劳。
这个挑战吸引了许多人的注意,其中一些人决定为 Biome 做出贡献,以赢得部分奖金。我看到了一些令人惊奇的事情:贡献者们有着惊人的协调能力,他们承担了任务,并在几个小时内提供了解决方案。
我认为使这成为可能的主要因素有三个:
- 金钱。这是一个事实,如果有人决定只为了赚取一小部分津贴而做出贡献,那完全没问题。
- 沟通。我们使用 GitHub 作为唯一的协调媒介。我们提供了信息、指导和帮助,以便交付。
- 基础设施。Biome 依赖于一个坚实的测试基础设施,由 以前的 Rome Tools 员工 和 贡献者 构建。它能够捕获每一个重新格式化的 bug,提供粒度细化的差异,并在发出的输出与 Prettier 发出的输出不同时警告用户。
在挑战之前,Biome 大约有 85% 的兼容性,基于我们的内部指标(JavaScript、TypeScript 和 JSX,在选项平等的情况下)。尽管 85% 看起来可能很高, 但在大型代码库上,低到 15% 的影响是巨大的,人们可能会因为变化太多而感到恐慌,导致早期的采用者在将 Biome 带到他们的团队时遇到阻力。我们社区的一位成员分享了一些见解:
作为一个很好的例子,即使只有最后的 5% 对大型代码库(特别是实现了
bracketSpacing
和现在的bracketSameLine
)的改善有多大,我在我们的单仓库中的一个项目上运行了它[...]。就在上周,这个数字
[diagnostics]
还超过了 6,000。即使忽略了括号选项,它仍然超过了 1000,现在只剩下 200 了!
尽管挑战已经结束,但我们承诺将进一步提高与 prettier 的兼容性分数。在这方面的任何贡献都非常欢迎。
挑战也揭示了一些我们决定不遵循的 Prettier 的输出案例。我们在网站上创建了一个新的部分来解释它们。我们希望随着时间的推移,这个部分会变得更小。
如果有一个分歧没有在我们的网站上记录,你应该认为那是一个 bug 并提交一个问题。
新的格式化选项
在这个挑战中,我们为格式化器添加了新的选项:
-
使用此选项来匹配你的操作系统的行结束符。我们支持
lf
(换行 -\n
)、cr
(回车 -\r
)和crlf
(回车换行 -\r\n
)。 -
// 现有行为。现在也是默认的,意味着 `bracketSameLine: false`。 <Foo className={somethingReallyLongThatForcesThisToWrap} anotherReallyLongAttribute={withAValueThatsSurelyTooLong} soThatEverythingWraps > Hello </Foo> <Foo selfClosingTags={likeThisOne} stillPlaceTheBracket={onItsOwnLine} toIndicateThat={itClosesItself} />
使用
"bracketSameLine": true
格式化后:// 新的行为,`bracketSameLine: true`。 <Foo className={somethingReallyLongThatForcesThisToWrap} anotherReallyLongAttribute={withAValueThatsSurelyTooLong} soThatEverythingWraps> Hello </Foo> <Foo selfClosingTags={likeThisOne} stillPlaceTheBracket={onItsOwnLine} />
-
import { sort } from "sort.js"; const value = { sort };
After formatting with
"bracketSpacing": false
:import {sort} from "sort.js"; const value = {sort};
VSCode 扩展插件的新功能
VSCode 扩展插件已经被移动到一个新的仓库。
我们从扩展插件中移除了捆绑的二进制文件,你将能够下载你想要的版本。这里有一个小视频展示了它是如何工作的:
从今天开始,我们发布了一个每夜版本的扩展插件。这是一个为早期采用者和在正式发布之前测试事物的版本。
一些 CLI 的新功能
依赖 Biome LSP 的人将会很高兴,他们现在可以使用选项 --config-path
将自定义配置传递给命令 lsp-proxy
。同样的选项也被命令 start
接受:
biome --config-path=../path/where/config/is lsp-proxy
biome --config-path=../path/where/config/is start
CLI 现在公开了选项 --diagnostic-level
,允许过滤打印到终端的诊断类型。
biome check --diagnostic-level=error ./src
新的 lint 规则,以及提升的规则
Biome 也是一个 linter,它具有 177 条规则!在这个版本中,一些规则被提升,新的规则也可用。
新规则
-
export default function f() {}
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.
-
<div aria-hidden="true" tabIndex="0" />
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"·/> │ -------------------
-
var a; a = 2;
nursery/noImplicitAnyLet.js:1:5 lint/nursery/noImplicitAnyLet ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✖ This variable has implicitly 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.
-
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.
-
<div role="datepicker"></div>
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 │
推荐的规则
-
<input type="submit" accessKey="s" value="Submit" />
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"·/> │ --------------
-
<h1 />
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
({ 0x1: 1 });
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 │
升级的规则
- a11y/noInteractiveElementToNoninteractiveRole
- complexity/noThisInStatic
- complexity/useArrowFunction
- correctness/noEmptyCharacterClassInRegex
- correctness/noInvalidNewBuiltin
- style/noUselessElse
- style/useAsConstAssertion
- style/useShorthandAssign
- suspicious/noApproximativeNumericConstant
- suspicious/noMisleadingInstantiator
- suspicious/noMisrefactoredShorthandAssign
废弃的规则
这条规则由 correctness/noInvalidNewBuiltin 替换
向我们的维护者致敬
自从 Biome 分叉以来,新的人员加入了项目。他们以你无法想象的多种方式提供了帮助:新功能、辅助项目、与社区的互动、支持、文档等等。开源软件不仅仅是关于编码。
感谢:
以及热烈欢迎我们新加入的维护者:
新的赞助商
最后但并非最不重要的,我们很自豪地宣布我们有两个新的赞助商:
- 金牌:Shiguredō (shiguredo.jp/)
- 铜牌:KANAME (www.kanamekey.com/)
如果你想经济上对项目做出贡献并帮助它发布更多功能,你可以从 GitHub Sponsorship page 或 Open Collective page 进行。
下一步是什么
该项目正在蓬勃发展,越来越多的人对项目感到好奇,并希望参与其中。
在接下来的几个月,我们将专注于:
- 发布路线图。请密切关注,它将涉及许多有趣的工作。
- 用新的标志重新设计网站。
- 将网站翻译成日语。