我拼凑了一个非常轻量级的过程,用于捆绑从 Typescript 构建的 JS 文件。TLDR:我运行tsc
为js/foo.js
每个src/foo.ts
. 然后我使用esbuild
. 这是粗略的依赖关系图:
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
src_stems := a b c
ts_files := $(addsuffix .ts,$(addprefix src/,$(src_stems)))
js_files := $(addsuffix .js,$(addprefix js/,$(src_stems)))
pkg_files := $(addsuffix .js,$(addprefix pkg/,$(src_stems)))
.bundled: $(pkg_files)
touch $@
pkg:
mkdir -p $@
pkg/%.js: js/%.js | pkg
cp $< $@
$(js_files): .compiled
# Simulate running tsc
.compiled: $(ts_files)
mkdir -p js
touch $(js_files)
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
文件都将具有相同的时间戳。
我究竟做错了什么?我还应该考虑其他规则吗?