使用make build /最小化已更改的JS文件

时间:2012-04-02 23:54:56

标签: build makefile

我正在使用Makefile来帮助我在我的应用程序中执行JS的构建步骤。目标是使用Make的能力仅处理修改过的文件以防止无关的复制等。

构建你需要的JS

  1. 将原始.js文件从主dev目录复制到构建目录
  2. 最小化复制的文件并创建文件的-min.js版本
  3. 生成一个meta.js,其中包含用于组合加载器的内置JS文件中YUI模块的信息。
  4. 所以我一直在努力使Makefile向后工作。 meta.js取决于-min.js,它取决于从$builddir/b/*.js复制的%origdir/*.js

    在查看事物时,似乎我应该能够使用%.js来捕获任何匹配的文件,但是当我尝试这个时,我得到:

      make: *** No rule to make target `bookie/static/js/build/b/%-min.js', needed by `bookie/static/js/build/b/meta.js'.  Stop.
    

    我正在与之合作,任何人都知道我做错了什么?我希望当我make js复制已更改的.js文件时,缩小它们,然后重新生成meta.js。

    # Makefile to help automate tasks in bookie
    WD := $(shell pwd)
    PY := bin/python
    BOOKIE_JS = bookie/static/js/bookie
    JS_BUILD_PATH = bookie/static/js/build
    JS_META_SCRIPT = $(PY) scripts/js/generate_meta.py
    
    EXTENSION = $(WD)/extensions
    CHROME_BUILD = $(EXTENSION)/chrome_ext/lib
    
    
    # JAVASCRIPT
    #
    # Javascript tools for building out combo loader build directory, out meta.js,
    # and syncing things over to the chrome extension directory.
    
    .PHONY: js
    js: $(JS_BUILD_PATH)/b/meta.js
    
    $(JS_BUILD_PATH)/b/meta.js: $(JS_BUILD_PATH)/b/%-min.js
        echo "META"
        $(JS_META_SCRIPT) -n YUI_MODULES -s $(JS_BUILD_PATH)/b/ \
            -o $(JS_BUILD_PATH)/b/meta.js \
            -x -min.js$
    
    $(JS_BUILD_PATH)/b/%-min.js: $(JS_BUILD_PATH)/b/$*.js
        echo "MIN"
        rm $(JS_BUILD_PATH)/b/meta.js || true
        scripts/js/jsmin_all.py $(JS_BUILD_PATH)/b
    
    $(JS_BUILD_PATH)/b/%.js: $(BOOKIE_JS)/$*.js
        echo "Initial"
        cp $? $(JS_BUILD_PATH)/b/
        cp $? $(CHROME_BUILD)/
    
    .PHONY: clean_js
    clean_js:
        rm -rf $(JS_BUILD_PATH)/* || true
    

2 个答案:

答案 0 :(得分:0)

您的配方有点难以理解,因为您的实用程序不是标准Unix风格的过滤器:它们似乎不将输入文件名作为参数或从stdin读取输入,并且似乎不会将输出写入stdout

我的猜测是(基于文件名中的all)您的实用程序转换特定目录中的所有文件。这不是make可以优雅处理的事情:它实际上是为了支持从单个输入文件(依赖项)生成单个输出文件(目标)的规则。

模式规则只允许您同时为整个文件类别指定此类规则,但它们不指定在单个规则中处理文件集合。你似乎试图这样做。

我一直遇到这个make限制。作为一种变通方法,您可以使用文件所在的目录作为规则的目标和依赖项(如果确保不会在其中创建其他文件),或者使用没有用于标记完成的内容的特殊标记文件一条规则。正确的解决方案需要对make规则的语法和语义进行基本扩展。

答案 1 :(得分:0)

使通配符不按照您的想法运行。让我们从这条规则开始:

$(JS_BUILD_PATH)/b/%.js: $(BOOKIE_JS)/$*.js
    echo "Initial"
    cp $? $(JS_BUILD_PATH)/b/
    cp $? $(CHROME_BUILD)/

%意味着它是一个模式规则,因此Make期望在先决条件列表中有相应的%。相反,它看起来好像你正在尝试使用自动变量$*(不能在先决条件列表中使用)或通配符*(如果不使用{ {1}}命令)。试试这种方式:

wildcard

这样可行,但前提是您准确指定了所需的文件;它不会复制dev目录中的每个$(JS_BUILD_PATH)/b/%.js: $(BOOKIE_JS)/%.js echo "Initial" cp $? $(JS_BUILD_PATH)/b/ cp $? $(CHROME_BUILD)/ 文件(稍后会详细介绍)。

现在为.js。我无法确切地知道这个规则是如何工作的,但它看起来好像你运行了一个python脚本,它立即对目录中的所有* .js文件起作用。如果这是正确的,那么从-min.js获得foo-min.js的规则是没有意义的;应该有一个规则来运行脚本,我们需要一个列出它需要的所有foo.js文件:

.js

最后,DEV_JS_FILES := $(wildcard $(BOOKIE_JS)/*.js) BUILD_JS_FILES := $(patsubst $(BOOKIE_JS)/%.js,$(JS_BUILD_PATH)/b/%.js,$(DEV_JS_FILES)) .PHONY: min min: $(BUILD_JS_FILES) echo "MIN" rm $(JS_BUILD_PATH)/b/meta.js || true scripts/js/jsmin_all.py $(JS_BUILD_PATH)/b

meta.js

修改:
我想我明白你在做什么。有几种方法可以做到这一点;最简单的只是将三个规则合并为一个:

$(JS_BUILD_PATH)/b/meta.js: min
        echo "META"
        $(JS_META_SCRIPT) -n YUI_MODULES -s $(JS_BUILD_PATH)/b/ \
        -o $(JS_BUILD_PATH)/b/meta.js \
        -x -min.js$

此操作仅适用于开发中DEV_JS_FILES := $(wildcard $(BOOKIE_JS)/*.js) $(JS_BUILD_PATH)/b/meta.js: $(DEV_JS_FILES) echo "Initial" cp $? $(JS_BUILD_PATH)/b/ cp $? $(CHROME_BUILD)/ echo "MIN" rm $(JS_BUILD_PATH)/b/meta.js || true scripts/js/jsmin_all.py $(JS_BUILD_PATH)/b rm $(addprefix $(JS_BUILD_PATH)/b/,$?) echo "META" $(JS_META_SCRIPT) -n YUI_MODULES -s $(JS_BUILD_PATH)/b/ \ -o $(JS_BUILD_PATH)/b/meta.js \ -x -min.js rm $(JS_BUILD_PATH)/b/*-min.js 以上.js的{​​{1}}文件(如果meta.js尚不存在,则仅适用于所有文件。)