esbuild v0.18.14 发布,新增 global-css、local-css 加载器及对应伪类选择器

esbuild v0.18.14 已经发布了。esbuild 是一个Go 编写的 JavaScript 打包和压缩工具,支持 TypeScript,性能超强:

此版本引入了两个新的加载器,名为 global-css 和 local-css ,以及两个新的伪类选择器 :local() 和 :global() 。这是流行的CSS模块方法的部分实现,用于避免在CSS中无意间的名称冲突。因为社区中的其他人已经开始使用“CSS模块”来指代完全不同的东西,所以些功能不再这么称呼。

.className 和 #idName 的标识符在 global-css 加载器中是全局的,在 local-css 加载器中是局部的。全局标识符在所有文件中都是相同的(这就是CSS通常的工作方式),但是在不同的文件中,局部标识符是不同的。如果两个单独的CSS文件使用相同的局部标识符 .button ,esbuild会自动重命名其中一个,以防止它们发生冲突。这与esbuild如何自动重命名在不同JS文件中具有相同名称的JS局部变量以避免名称冲突的方式类似。

只有在使用esbuild的打包器来打包导入CSS文件的JS文件时,使用 local CSS 名称与esbuild才有意义。这么做的话,esbuild会为CSS文件中的每个本地名称生成一个export。JS代码可以导入这些名称,并在构建HTML DOM时使用它们。例如:

// app.js

import { outerShell } from './app.css'

const div = document.createElement('div')

div.className = outerShell

document.body.appendChild(div)

/* app.css */

.outerShell {

position: absolute;

inset: 0;

}

当你将此与 esbuild app.js --bundle --loader:.css=local-css --outdir=out 捆绑在一起时,你现在会得到以下的东西(注意本地CSS名称 outerShell 已被重命名):

// out/app.js

(() => {

// app.css

var outerShell = "app_outerShell";

// app.js

var div = document.createElement("div");

div.className = outerShell;

document.body.appendChild(div);

})();

/* out/app.css */

.app_outerShell {

position: absolute;

inset: 0;

}

仅当启用了打包功能时,使用此功能才有意义,原因有两个:一是因为你的代码需要 import 重命名的本地名称以便使用它们,二是因为esbuild需要能够在单次打包操作中处理所有包含本地名称的CSS文件,以便成功地重命名冲突的本地名称以避免冲突。

如果你在全局CSS文件中(使用 global-css 加载器),你可以使用 :local() 创建一个本地名称,如果你在本地CSS文件中(使用 local-css 加载器),你可以使用 :global() 创建一个全局名称。因此,选择 global-css 加载器与 local-css 加载器只是设定了标识符的认行为,但你可以根据需要在每个案例中进行覆盖。例如:

:local(.button) {

color: red;

}

:global(.button) {

color: blue;

}

使用esbuild处理这个CSS文件,无论是使用 global-css 或 local-css 加载器,结果都会类似于这样:

.stdin_button {

color: red;

}

.button {

color: blue;

}

esbuild为本地CSS名称生成名称是实现细节,不打算在任何地方硬编码。应该在JS或HTML中引用本地CSS名称的唯一方式是使用与esbuild捆绑的JS中的 import 语句,如上所示。例如,当 --minify 启用时,esbuild将使用一种不同的名称生成算法,该算法生成尽可能短的名称(类似于esbuild如何压缩JS中的本地标识符)。

如果给它们不同的文件扩展名,可以轻松地同时使用全局CSS文件和本地CSS文件。例如,你可以将 --loader:.css=global-css 和 --loader:.module.css=local-css 传递给esbuild,这样 .css 文件认仍然使用全局名称,但 .module.css 文件认使用本地名称

css 加载器与 global-css 加载器不同。在 css 加载器中, :local 和 :global 注释不会被启用,而会原封不动地传递。这让你有可能使用esbuild处理包含这些注释的CSS,同时保留这些注释。这也意味着,目前本地CSS名称认是被禁用的(因为 css 加载器目前是CSS文件认加载器)。在未来的版本中, :local 和 :global 的语法可能会认启用。

esbuild的实现目前并未与其他类似工具中的模块化CSS的实现对齐功能。这只是一个初步发布,包含了一些基本行为的部分实现,以启动该过程。未来的版本可能会添加更多行为。特别是,这个版本并未实现:

composes 指令

为未使用的本地CSS进行抖动优化

关键帧动画、网格线、 @container 、 @counter-style 等的本地名称

发布公告中表示,这是esbuild最受欢迎的问题!虽然这个版本仍然没有完全解决问题,但这是朝该方向迈出的重要的第一步。

此外,另一项变化是在CSS中解析 :is , :has , :not ,以及 :where。

随着这个版本的发布,esbuild现在将会解析这些伪类选择器的内容作为选择器列表。这意味着你现在会在这些选择器中得到无效选择器语法的语法警告。这也意味着esbuild的CSS嵌套转换的行为与以前略有不同,因为esbuild现在是在一个抽象语法树上操作,而不是一个令牌流。例如:

/* Original code */

div {

:where(.foo&) {

color: red;

}

}

/* Old output (with --target=chrome90) */

:where(.foo:is(div)) {

color: red;

}

/* New output (with --target=chrome90) */

:where(div.foo) {

color: red;

}

发布公告:https://github.com/evanw/esbuild/releases/tag/v0.18.14

相关文章

IT之家 10 月 31 日消息,苹果公司面向数据科学家、3D 艺术家...
鞭牛士 10月30日消息,被戏称为“中国AI教父”的网络红人李一...
IT之家 10 月 31 日消息,Meta 首席执行官马克・扎克伯格在第...
IT之家 10 月 31 日消息,当地时间 30 日,OpenAI 宣布,为了...
据路透社报道,OpenAI 正在与 博通(Broadcom)合作开发其 首...
IT之家 10 月 31 日消息,OpenAI 今日宣布,ChatGPT 的高级语...