我拼凑了一个非常轻量级的过程,用于捆绑由 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
文件都将具有相同的时间戳。我做错了什么?我还应该考虑其他规则吗?
js/*.js
还不够。它告诉 make 有一个先决条件,但它没有提供任何秘诀。您希望有一个配方,使其成为完整的规则,而不仅仅是先决条件声明。添加分号就足够了(我相信):
js/a.js js/b.js js/c.js: .compiled
或者,如果更容易理解,您可以添加类似的内容:
js/a.js js/b.js js/c.js: .compiled ;
请注意:如果您将源文件分配给一个变量并使用该变量,那么阅读您的示例会更简单(并意识到它是正确的),而不是每次都重写所有文件,我们必须仔细解析它们确保它们没有输入错误。