Parcel v2.12.0

Parcel v2.12.0 引入了对宏的支持,使您能够使用普通的 JavaScript 函数在构建时生成代码。它还包括一个新的在线 REPL,改进了我们的 CSS 捆绑支持,添加了配置选项以微调您的应用程序的代码拆分,并提高了性能和内存使用率。

#

Parcel v2.12.0 引入了对 的支持。宏最初是在 Bun 中实现的,是 JavaScript 函数,它们在构建时运行,而不是被捆绑。宏返回的值将内联到捆绑包中,以替换原始函数调用。这使您能够生成常量、代码,甚至额外的资产,而无需任何自定义插件。

宏使用 导入属性 导入,以指示它们应该在构建时运行,而不是被捆绑到输出中。您可以将任何 JavaScript 或 TypeScript 模块作为宏导入,包括内置的 Node 模块和来自 npm 的包。

此示例使用 regexgen 库在构建时从一组字符串生成优化的正则表达式。

import regexgen from 'regexgen' with {type: 'macro'};

const regex = regexgen(['foobar', 'foobaz', 'foozap', 'fooza']);
console.log(regex);

这将编译成以下捆绑包

console.log(/foo(?:zap?|ba[rz])/);

如您所见,regexgen 库已被完全编译掉,我们只剩下一个静态正则表达式!

Parcel 对宏的实现还使您能够在构建时生成函数,甚至发出新的资产。例如,宏可以生成 CSS,这些 CSS 将被静态提取到 CSS 捆绑包中,就好像它是从 JS 文件导入的一样。

此示例接受一个 CSS 字符串并返回一个生成的类名。CSS 被添加为一个资产并捆绑到一个 CSS 文件中,而 JavaScript 捆绑包只包含生成的类名作为静态字符串。

index.ts
import {css} from './css.ts' with {type: 'macro'};

<div className={css('color: red; &:hover { color: green }')}>
Hello!
</div>
css.ts
import type {MacroContext} from '@parcel/macros';

export async function css(this: MacroContext | void, code: string) {
let className = hash(code);
code = `.${className} { ${code} }`;

this?.addAsset({
type: 'css',
content: code
});

return className;
}

上面示例的捆绑输出将如下所示

index.js
<div className="ax63jk4">
Hello!
</div>
index.css
.ax63jk4 {
color: red;
&:hover {
color: green;
}
}

这基本上是一个 CSS-in-JS 库,它在几行代码中就实现了构建时静态提取!由于宏只是普通的 JavaScript 或 TypeScript 函数,因此您可以在此基础上创建任何您想要的 API,例如使用对象 API 或主题值生成 CSS。我们很高兴看到这将解锁哪些创新 - 对于 CSS-in-JS 以及更多。查看 文档 以了解更多信息。

REPL

#

Parcel 现在有一个 REPL,您可以在浏览器中直接试用它!Niklas Mischkulnig 已经开发了 REPL 多年,我们很高兴它终于集成到我们的网站中。REPL 具有完整的代码编辑器、文件浏览器,并支持大多数 Parcel 功能,包括监视模式、开发服务器、热模块替换等等。

在幕后,REPL 由最先进的 Web 技术提供支持,包括 WebAssembly、用于托管开发服务器的服务工作者、用于多核处理的 Web 工作者后端以及用于包管理器缓存的 IndexedDB。它甚至可以通过运行浏览器编译的 Yarn 版本从 npm 安装包。

REPL 非常适合玩转 Parcel 并查看事物是如何编译的。它也非常适合创建可共享的错误重现。查看它

闪电般快速的 CSS 驱动的捆绑

#

Parcel 一直使用 Lightning CSS 默认情况下转换 CSS 文件。现在 Parcel 也使用它来捆绑 CSS 文件。这带来了对现代 CSS 功能的支持,例如带有 级联层@import,改进了对使用媒体和支持查询导入的支持,以及更正确地处理复杂的 CSS 排序问题。

手动共享捆绑包

#

默认情况下,Parcel 会自动将您的代码拆分为代码,以实现最大的缓存效率。在您的应用程序的多个部分之间共享的通用模块将被提取到一个 共享捆绑包 中,以便浏览器可以单独加载和缓存它们。但是,有时您可能比 Parcel 更了解应用程序的某个特定部分应该如何加载,选择提前过度获取以优化以后的操作。在此版本中,我们引入了对手动共享捆绑包的支持来解决这个问题。

手动共享捆绑包使您能够配置 Parcel 以确保某些模块始终捆绑在一起,无论它们在何处使用。例如,您可以创建一个供应商捆绑包,加载一组常用的库,或者将特定路由的资产分组到一个捆绑包中。这使用 glob 来匹配文件路径以及其他选项来按根资产或类型分组、拆分为多个并行 http 请求等等来指定。查看 文档 以了解所有详细信息。

手动共享捆绑包最适合在尝试了 Parcel 的默认捆绑算法并进行了实际性能测试后应用。当您遇到无法通过更改代码结构解决的特定性能问题时,请使用手动共享捆绑包来覆盖 Parcel 的默认行为。手动共享捆绑包在将代码从其他捆绑器(如 webpack)移植时也很有用。

性能改进

#

与大多数 Parcel 版本一样,v2.12.0 还包含一些性能改进。在此版本中,我们改进了我们的核心图数据结构,将内存使用量减少了约 52%,并将写入性能提高了约 5%。对于一个真实的、非常大的应用程序,这相当于内存使用量减少了约 800MB,并且启动、构建或关闭时间没有出现任何回归!如果您有兴趣了解我们如何进行这些优化,请查看 PR。有关我们由 SharedArrayBuffer 支持的自定义图数据结构的更多背景信息,我们现在有一些 文档

在此版本中,我们还改进了 Parcel 将图存储到磁盘的方式,以便在开发过程中的空闲时间以小块的形式工作,而不是在序列化图时阻止进程关闭。我们不再一次序列化整个图,而是跟踪哪些部分已被修改,只重新序列化那些部分。这应该会提高 Parcel 对非常大型项目的感知关闭性能。

感谢!

#

感谢所有为本版本做出贡献的人!查看 完整变更日志 以了解所有其他错误修复和改进。