我开始使用GNU Make作为我的前端构建工具,而且大多数工作都很棒。唯一令人烦恼的是,当其中一个步骤出现错误时,编译似乎没有停止。 Makefile的相关部分:
js_files=$(filter-out $(ignore_js),$(wildcard \
js/ll/*.js js/ll/**/*.js))
ignore_js=js/ll/dist% js/ll/%.min.js
%.min.js: %.js
@echo ">>> Uglifying $?"
@$(BABELJS) $(BABELJSFLAGS) $? | $(UGLIFYJS) --source-map $(UGLIFYJSFLAGS) > $@
min_js_files=$(js_files:%.js=%.min.js)
main.js: $(min_js_files)
@echo ">>> Concatenating JavaScript"
mkdir -p $(DIST_DIR)
cat $^ > $(DIST_DIR)$@
prod: main.js clean
我从运行make prod
得到的输出看起来像这样:
>>> Uglifying js/ll/DateEx.js
SyntaxError: js/ll/DateEx.js: Invalid number (22:36)
20 | day = today.getDate();
21 | }
> 22 | return new Date(year, month, day, 01, 0, 0);
| ^
23 | }
24 |
25 | function newDateS(s)
>>> Uglifying js/ll/Anonymization.js
>>> Uglifying js/ll/DummyStorage.js
(...)
我的印象是,这种情况发生是因为这些步骤并行运行,但我对Make的支持一无所知。当其中一个步骤返回非零时,如何编译停止?
答案 0 :(得分:2)
你要求的是Make的完善的默认行为。构建链中的某些内容在失败时未正确设置非零退出代码,或者您正在屏蔽它。
特别是,shell管道的退出代码始终是管道中最终命令的退出代码。换句话说,配方中BABELJS
的任何错误都将丢失。
也许重构不使用管道,也许是这样的:
%.min.js: %.js.tmp
$(UGLIFYJS) --source-map $(UGLIFYJSFLAGS) <$< >$@
%.js.tmp: %.js
$(BABELJS) $(BABELJSFLAGS) $< >$@
.PHONY: clean
clean:
rm *.js.tmp
使用临时文件有点尴尬,选择是否在第一步使用单独的配方是任意的。我更喜欢这种风格,因为它更符合Make的精神(明确声明依赖关系,让Make keep track)但是如果你想要对流程进行细粒度的控制,你可以采取另一种方式。
我还从@
规则中删除了BABELJS
前缀。这是我的一个私人运动 - 乱扔你的Makefile,这些使调试变得困难,如果你想要平静和安静,正确的解决方案是使用make -s
。