使用 GNU Make 的打字稿工作流程

问题描述 投票:0回答:1

我拼凑了一个非常轻量级的过程,用于捆绑由 Typescript 构建的 JS 文件。 TLDR:我运行

tsc
为每个
js/foo.js
生成
src/foo.ts
。然后我使用
esbuild
捆绑 JS 文件。这是粗略的依赖关系图:

pkg/         js/                             src/
  a.js   ->    a.js   -.               .->     a.ts
  b.js   ->    b.js   --> .compiled   -+->     b.ts
  c.js   ->    c.js   -'               '->     c.ts

因为

tsc
与 Java 一样,会无条件地立即编译整个代码库,而不是单个源文件,所以我使用
.compiled
文件作为中间代理来指示
tsc
编译。

这是经过淡化但独立、功能齐全的 Makefile:


.PHONY: bundle
bundle: .bundled

.bundled: pkg/a.js pkg/b.js pkg/c.js
    touch $@

pkg:
    mkdir -p $@

# Simulate esbuild
pkg/%.js: js/%.js | pkg
    cp $< $@

js/a.js js/b.js js/c.js: .compiled

# Simulate running tsc
.compiled: src/a.ts src/b.ts src/c.ts
    mkdir -p js
    touch js/a.js js/b.js js/c.js
    touch $@

.PHONY:
clean:
    rm -rf pkg js .compiled .bundled

一切都按预期进行

make clean bundle

$ mkdir -p src
$ touch src/{a,b,c}.ts
$ make

但是,我对单个文件更新后捆绑时的行为感到惊讶。例如,在干净的构建后运行:

$ touch src/b.ts # I modify a single source
$ make
mkdir -p js
touch js/a.js js/b.js js/c.js
touch .compiled
cp js/b.js pkg/b.js    <- Note a.js isn't being bundled!
cp js/c.js pkg/c.js
touch .bundled

而且,如果我再次运行

make
,丢失的文件就会被捕获:

$ make
cp js/a.js pkg/a.js
touch .bundled

我尝试使用

make -d
进行调试,但无法弄清楚为什么当我有部分更新时,需要运行两次才能捆绑
a.js
。另请注意,它总是被错过,我想这是因为它是第一个列出的来源。
来自

a.js

的一些调试行:

make -d

     Prerequisite 'js/a.js' is older than target 'pkg/a.js'.
...
     Prerequisite 'js/b.js' is newer than target 'pkg/b.js'.
...
     Prerequisite 'js/c.js' is newer than target 'pkg/c.js'.

线的诊断与其他线不一致。事实上,所有

pkg/a.js
文件都将具有相同的时间戳。
我做错了什么?我还应该考虑其他规则吗?

gnu-make
1个回答
0
投票

js/*.js

还不够。它告诉 make 有一个先决条件,但它没有提供任何秘诀。您希望有一个配方,使其成为完整的规则,而不仅仅是先决条件声明。添加分号就足够了(我相信):

js/a.js js/b.js js/c.js: .compiled

或者,如果更容易理解,您可以添加类似的内容:

js/a.js js/b.js js/c.js: .compiled ;

请注意:如果您将源文件分配给一个变量并使用该变量,那么阅读您的示例会更简单(并意识到它是正确的),而不是每次都重写所有文件,我们必须仔细解析它们确保它们没有输入错误。

© www.soinside.com 2019 - 2024. All rights reserved.