dot*_*ter 2 makefile build npm
我是新手,来自 npm。我正在尝试将它们一起使用,效果很好。只是make似乎认为每次都需要运行某个npm命令,但是目标文件在那里并且没有变化。
我有一个 git 项目的网站。该网站有一个该项目的 git 子模块,称为 npm。唯一重要的是,我需要在该目录中构建一些文件并将它们压缩到网站的根目录。该网站没有 package.json,因此 npm 将无法在该目录中运行。
下面是 MakeFile,最后是我的问题。
REPO_FOLDER = npm
MINI_FILES = stream.min.js stream.min.js.map
#STREAM_MINI_FILES := $(REPO_FOLDER)/stream.min.js $(REPO_FOLDER)/stream.min.js.map
STREAM_MINI_FILES := $(MINI_FILES:%=REPO_FOLDER/%) #6.3.1 Substitution References
stream.js.zip: $(STREAM_MINI_FILES)
cd $(REPO_FOLDER); \
npm run zip ../stream.js.zip $(MINI_FILES)
$(STREAM_MINI_FILES): minify
minify:
@cd $(REPO_FOLDER); \
test -d "node_modules" || npm install; \
npm run minify;
update:
@git submodule update --remote
all: update stream.js.zip
.PHONY: minify, update, all
Run Code Online (Sandbox Code Playgroud)
1) 即使 npm/stream.min.js npm/stream.min.js.map 存在, minify 目标也始终运行。为什么会这样,我如何才能识别这两个文件?
2)有什么区别@cd和cd?在minify 目标中,我可以@cd到 npm 文件夹并运行npm install,但在 stream.js.zip 目标中,我收到来自 npm 的错误,因为它仍在网站目录中(没有 package.json)。在这种情况下,当我执行 @cd 时,为什么我不在 npm 目录中?
3)我使用 npm 压缩两个编译文件。我已经看到armake中有一个命令,但是它可以制作一个 zip 文件吗?如果是,如何制作?
更新
事实证明我的变量替换是错误的,因此第二个目标也是错误的。$(STREAM_MINI_FILES) 将解析为REPO_FOLDER/stream.min.js REPO_FOLDER/stream.min.js.map而不是stream/stream.min.js stream/stream.min.js.map. 由于第一条规则中的先决条件REPO_FOLDER从未存在,因此每次都会运行第二条规则的配方。
这是最终的工作 MakeFile:
REPO_FOLDER = stream
MINI_FILES = stream.min.js stream.min.js.map
ZIP_FILE = stream.js.zip
#STREAM_MINI_FILES := $(REPO_FOLDER)/stream.min.js $(REPO_FOLDER)/stream.min.js.map
STREAM_MINI_FILES := $(MINI_FILES:%=$(REPO_FOLDER)/%) #6.3.1 Substitution References
$(ZIP_FILE): $(STREAM_MINI_FILES)
@cd $(REPO_FOLDER); \
npm run zip ../$@ $(MINI_FILES)
$(STREAM_MINI_FILES):
@cd $(REPO_FOLDER); \
test -d "node_modules" || npm install; \
npm run minify;
update:
@git submodule update --remote
clean:
@rm --verbose $(ZIP_FILE) $(STREAM_MINI_FILES)
all: update $(ZIP_FILE)
.PHONY: update, clean, all
Run Code Online (Sandbox Code Playgroud)
1)minify被声明为.PHONY特殊目标的先决条件。每次必须构建依赖于它的另一个目标或使用此目标调用 make 时,make 都会重建它。如果您使用make(即,不指定目标)调用 make ,它将尝试构建 makefile 中的第一个目标stream.js.zip,在您的情况下。由于这取决于$(STREAM_MINI_FILES),make 将首先检查这些是否是最新的,如果不是,则重建它们。$(STREAM_MINI_FILES)本身取决于minify,这是 的先决条件,.PHONY因此必须在每种情况下重新制作,即使名为的文件minify存在并且是最新的。
此外,我怀疑minify是一个符号目标,并且没有具有此名称的真实文件(我错了吗?)。这是 make 重建它的另一个原因:它不存在,但$(STREAM_MINI_FILES).
一种选择是minify完全删除(包括从.PHONY先决条件中删除)并合并规则:
$(STREAM_MINI_FILES):
@cd $(REPO_FOLDER); \
test -d "node_modules" || npm install; \
npm run minify
Run Code Online (Sandbox Code Playgroud)
仅当 中列出的文件之一$(STREAM_MINI_FILES)丢失时,才应运行该配方。一个缺点是配方将根据丢失的文件运行多少次,这是一种浪费。为避免这种情况,您可以保留minify目标,但将其设置为一个真正的空文件,以跟踪已完成的操作:
$(STREAM_MINI_FILES): minify
minify:
@cd $(REPO_FOLDER); \
test -d "node_modules" || npm install; \
npm run minify
touch $@
Run Code Online (Sandbox Code Playgroud)
这是一个非常常见的技巧,每次您的构建过程并不完全像“获取一个源文件并构建一个结果文件”时证明非常有用。
2)command在配方中,make 在执行时回显该命令。@command抑制回声。我想这与您的问题无关。
make 配方中的命令列表由 make 执行,每行一个单独的进程。所以,如果你:
cd there
pwd
Run Code Online (Sandbox Code Playgroud)
这两行在两个不同的进程中执行,第一行对第二行没有影响。将您的命令放在同一个 bash 列表中,即通过;force make分隔命令以在单个进程中执行它们(行\中的最后一个字符转义行尾字符):
cd there; pwd
Run Code Online (Sandbox Code Playgroud)
或者:
cd there; \
pwd
Run Code Online (Sandbox Code Playgroud)
是等效的,将pwd在there目录中执行命令。在您的stream.js.zip配方中,您只有一个 bash 列表。因此,它应该按预期工作,并且应该从$(REPO_FOLDER)目录中执行列表的第二个成员。你的问题来自其他方面。您是否尝试手动运行该命令?您是否检查过\确实是该行的最后一个字符(否则它不会转义行尾)。
3)ar不是 make 命令。它是一个 GNU 存档实用程序。不,它不能制作不同格式的 zip 存档。请注意,make 可以ar像解包一样对档案的内部进行操作,这很有用。键入man ar以了解更多信息ar。
| 归档时间: |
|
| 查看次数: |
1207 次 |
| 最近记录: |