#task-runner #task #runner #javascript #web #make #front-end

app chompbuild

具有 JS 扩展系统的类似 Make 的并行任务运行器

40 个版本

0.2.23 2024 年 4 月 16 日
0.2.17 2023 年 6 月 19 日
0.2.14 2023 年 3 月 23 日
0.2.11 2022 年 10 月 23 日
0.2.1 2022 年 3 月 30 日

#559 in Web 编程

每月 49 次下载

Apache-2.0

215KB
5K SLoC

CHOMP

Crates.io Discord

Chomp 是一个具有先进功能的前端任务运行器,专注于 易用性不干扰

  1. 一个具有单条命令的高级任务运行器!
  2. 轻松适应现有的项目/任务系统 - 无需重写。
  3. 您可以通过单行更新来启用和管理高级任务运行器功能。

Chomp 是一个很好的选择,对于前端项目,目标是在不增加复杂性和开销的情况下获得高级任务运行器功能(如智能缓存)。

单行迁移 npm 脚本

Chomp 可以导入项目的现有 package.json 脚本而不会破坏它们,因为它支持相同的特性

chomp --init --import-scripts

现在您可以使用 Chomp 运行 npm 脚本了!

npm run <task> 变为 chomp <task>,并且行为相同,您可以根据需要选择进一步的功能。

唯一的区别是,Chomp 更快。并且,经过一些调整,您还可以启用智能缓存、并行化等功能!

Chomp 提供哪些功能?

Chomp 是一个高级任务运行器。它提供了类似于 turbonx 的功能,但专注于易用性,*不是 monorepos。它基于与传统的 make 文件相同的原理。

并行化

Chomp 并行运行任务,基于已执行任务的依赖关系!

监视/服务

Chomp 通过包含 --watch--serve 选项来监控任何任务!关于 --watch 的更多信息,请参阅 这里,以及关于 --serve 的更多信息,请参阅 这里

一个 JS 扩展系统

Chomp 具有基于自己的自定义任务的 JS 扩展系统,允许您扩展 Chomp。

智能缓存

Chomp 根据任务依赖项(如其他任务或更新的文件)缓存任务。您不必担心这一点!

Chomp 适用于单仓库项目,但其设计是为了易于使用,而不是阻碍。

安装

如果您使用 Cargo,请运行

cargo install chompbuild

如果您不使用 Cargo,请运行

npm install -g chomp

注意:npm 脚本会使脚本运行时间增加 100ms 以上。

所有版本都提供了用于 所有版本 的常见平台二进制文件。

要快速在 GitHub Actions CI 工作流程中设置 Chomp,请参阅 Chomp GitHub Action

文档

入门

从 npm 脚本迁移

要将使用 npm "scripts" 的现有项目转换为 Chomp,请运行

$ chomp --init --import-scripts
 chompfile.toml created with 2 package.json script tasks imported.

或者更简短的版本

$ chomp -Ii
 chompfile.toml created with 2 package.json script tasks imported.

然后使用 chomp <name> 替代 npm run <name>,并享受任务依赖、增量构建和并行性等新功能!

你好世界

chomp 会与运行 chomp 命令的同一目录中的 chompfile.toml TOML 配置 进行交互。

Chomp 会将任务构建为依赖其他文件的文件树,然后以最大并行性运行这些任务。

例如,这里有一个名为 hello 的任务,它基于 name.txt 的内容构建 hello.txt,而 name.txt 本身是由另一个命令构建的

chompfile.toml

version = 0.1

[[task]]
target = 'name.txt'
run = '''
  echo "No name.txt, writing one."
  echo "World" > name.txt
'''

[[task]]
name = 'hello'
target = 'hello.txt'
dep = 'name.txt'
run = '''
  echo "Hello $(cat name.txt)" > hello.txt
'''

保存此文件后,hello 命令将运行所有依赖命令,然后再执行其自己的命令

$ chomp hello

🞂 name.txt
No name.txt, writing one.
 name.txt [4.4739ms]
🞂 hello.txt
 hello.txt [5.8352ms]

$ cat hello.txt
Hello World

最后,它将使用合并输出填充 hello.txt 文件。

后续运行将使用目标文件的 mtime 来确定需要重新运行的内容。

重新运行 hello 命令将看到 hello.txt 目标已被定义,并且 name.txt 依赖项没有更改,因此它将跳过再次运行该命令

chomp hello

 name.txt [cached]
 hello.txt [cached]

更改 name.txt 的内容将使 hello.txt 目标无效,而不是重新运行 name.txt 命令

$ echo "Chomp" > name.txt
$ chomp hello

 name.txt [cached]
  hello.txt invalidated by name.txt
🞂 hello.txt
 hello.txt [5.7243ms]

$ cat hello.txt
Hello Chomp

可以为目标定义 deps 数组,然后按照标准的 Makefile 方法,通过基于目标 / 依赖 mtime 的比较进行无效化,先运行这些目标的任务。

在 Windows 上使用 PowerShell,而在 POSIX 系统上使用 Bash。由于两个系统上都定义了 echo>,因此上面的例子可以在跨平台环境下工作(PowerShell 会自动将 > 放入 UTF-8 模式以使其类似地工作)。

注意,Powershell 中不支持 &&||,因此首选多行脚本和 ;

JS 任务

或者,我们可以使用 engine = 'node'engine = 'deno'run 函数中编写 JavaScript。

chompfile.toml

version = 0.1

[[task]]
target = 'name.txt'
engine = 'node'
run = '''
  import { writeFile } from 'fs/promises';
  console.log("No name.txt, writing one.");
  await writeFile(process.env.TARGET, 'World');
'''

[[task]]
name = 'hello'
target = 'hello.txt'
deps = ['name.txt']
engine = 'node'
run = '''
  import { readFile, writeFile } from 'fs/promises';
  const name = (await readFile(process.env.DEP, 'utf8')).trim();
  await writeFile(process.env.TARGET, `Hello ${name}`);
'''

任务将以任务图允许的最大并行度运行,这可以通过 -j 标志 来控制,以限制同时执行的次数。

使用 --watch 标志 监视所有依赖项,并在无效化时仅应用增量重建。

或者,使用 chomp hello --serve 运行一个具有监视重建的静态文件服务器。

有关详细信息,请参阅 任务文档

单一代码仓库

Chomp 中没有一等单一代码仓库支持,但一些简单的技术可以实现相同的结果。

例如,考虑一个单一代码仓库,其中 packages/[pkgname]/chompfile.toml 定义了每个包的任务。

基本级别的 chompfile.toml 可以使用以下 chompfile.toml 运行所有子包的 test 任务:

[[task]]
name = 'test'
dep = 'packages/#/chompfile.toml'
run = 'chomp -c $DEP test'

chomp test 将使用 任务插值 并行运行多个子包测试任务。类似的方法也可以用于 基本单元测试

通过添加 serial = 'true',可以使得插值以序列方式运行而不是并行运行。

目前不支持跨项目依赖项。相反,如果 packages/a/chompfile.toml 的构建任务依赖于 packages/b/chompfile.toml 的构建任务先运行,则 packages/a/chompfile.toml 可能看起来像这样:

[[task]]
name = 'build'
run = 'cargo build'
dep = 'build:deps'

[[task]]
name = 'build:deps'
run = 'chomp -c ../a build'

只要 packages/a/chompfile.tomlbuild 任务正确配置了其目标和依赖项,以便在所有目标 mtime 都大于其依赖项时执行零工作,那么这将仍然很快。

扩展

扩展可以注册用于 Chompfiles 中的任务模板。

扩展通过使用 extensions 列表加载,可以是任何本地或远程的 JS 文件。

version = 0.1
extensions = [
  "./local.js",
  "https://remote.com/extension.js"
]

提供了一个核心扩展库,其中包含适用于 JS 生态系统的实用模板,使用简短的协议 chomp:ext,这是 @chompbuild/extensions 包内容的缩写。

以下是一个简单示例。

请参阅 @chompbuild/extensions 包 以获取扩展描述和示例。

示例:TypeScript 与 SWC

要使用 SWC 模板编译 TypeScript

version = 0.1
extensions = ['[email protected]:swc']

[[task]]
name = 'build:typescript'
template = 'swc'
target = 'lib/##.js'
deps = ['src/##.ts']

在上面的代码中,所有 src/**/*.ts 文件将被 globbing,SWC 将在它们上运行,并将输出到 lib/[file].js,同时生成它们的源映射。

由于与 glob 依赖(也受支持)不同,# 和 # 插值语法是特殊的,因为必须存在依赖项与其目标之间的 1:1 关系。

只有不存在或 src mtimes 无效的文件将被重新构建。如果 SWC 本身更新,所有依赖于它的文件都将重新构建。

可以通过名称直接构建特定文件或模式,跳过所有其他构建工作

chomp lib/main.js lib/dep.js

🞂 lib/dep.js
🞂 lib/app.js
 lib/dep.js [317.2838ms]
 lib/app.js [310.0831ms]

也支持通过名称或文件名构建任务的模式(以下两个命令是等效的)

$ chomp lib/*.js
$ chomp :build:*

要去除模板魔法,请运行 chomp --eject 以将 chompfile.toml 转换为其无模板形式

$ chomp --eject

 chompfile.toml template tasks ejected

生成更新的 chompfile.toml

version = 0.1

[[task]]
name = 'build:typescript'
target = 'lib/##.js'
dep = 'src/##.ts'
stdio = 'stderr-only'
run = 'node ./node_modules/@swc/cli/bin/swc.js $DEP -o $TARGET --no-swcrc --source-maps -C jsc.parser.syntax=typescript -C jsc.parser.importAssertions=true -C jsc.parser.topLevelAwait=true -C jsc.parser.importMeta=true -C jsc.parser.privateMethod=true -C jsc.parser.dynamicImport=true -C jsc.target=es2016 -C jsc.experimental.keepImportAssertions=true'

许可

Apache-2.0

依赖项

~95MB
~2M SLoC