【问题标题】:ANT script to compile all (css) LESS files in a dir and subdirs with RHINO使用 RHINO 编译目录和子目录中的所有 (css) LESS 文件的 ANT 脚本
【发布时间】:2014-09-18 20:31:35
【问题描述】:

我想在特定文件夹中编译所有 *.less 脚本,并使用 less-rhino-1.1.3.js 子目录。

github上有一个针对特定文件执行此操作的示例,效果很好。但我想对一个完整的文件夹做同样的事情。我尝试了很多,这是我的最后一次尝试。

不行,propertyregex好像不是标准的ANT,我不想用这种东西。我什至不确定这段代码是否有效。

<project name="test" default="main" basedir="../../">
<property name="css.dir" location="public/css"/>
<property name="tool.less" location="bin/less/less-rhino-1.1.3.js"/>
<property name="tool.rhino" location="bin/tools/rhino/js.jar"/>
<macrodef name="lessjs">
    <attribute name="input" />
    <attribute name="output" />
    <sequential>
        <java jar="${tool.rhino}" fork="true" output="@{output}">
            <arg path="${tool.less}"/>
            <arg path="@{input}"/>
        </java>
        <echo>Lessjs: generated @{output}</echo>
    </sequential>
</macrodef>

<target name="main">
     <echo>compiling less css</echo>
     <fileset dir="${css.dir}" id="myfile">
          <filename name="**/*.less" />
     </fileset>
     <property name="lessfilename" refid="myfile"/>
     <propertyregex property="cssfilename"
          input="${lessfile}"
          regexp="^(.*)\.less$"
          replace="^\1\.css$" 
          casesensitive="true" />
     <lessjs input="lessfile" output="cssfilename"/>
</target>
</project>

【问题讨论】:

    标签: ant rhino less


    【解决方案1】:

    您可以使用&lt;fileset&gt; 来包含所有需要编译的less 文件。稍后,您可以使用&lt;mapper&gt; 标记相应的目的地css 文件。

    <project name="test" default="main" basedir="../../">
    <property name="css.dir" location="public/css"/>
    <property name="tool.less" location="bin/less/less-rhino-1.1.3.js"/>
    <property name="tool.rhino" location="bin/tools/rhino/js.jar"/>
    
      <target name="less" description="Convert LESS to CSS then concatenate and Minify any stylesheets">
    
      <echo message="Converting LESS to CSS..."/>
      <!-- Clear the former compiled css files -->
          <delete includeemptydirs="true">
                <fileset dir="${css.dir}" includes="*.css, **/*.css" defaultexcludes="false"/>
          </delete>
    
          <apply dir="${css.dir}" executable="java" parallel="false" failonerror="true">
      <!-- Give the input bundle of less files-->
              <fileset dir="${css.dir}">
                  <include name="*.less"/>
              </fileset>
              <arg value="-jar" />
              <arg path="${tool.rhino}" />
              <arg path="${tool.less}" />
              <srcfile/>
      <!-- Output the compiled css file with corresponding name -->
              <mapper type="glob" from="*.less" to="${css.dir}/*.css"/>
              <targetfile/>
          </apply>
    
      </target>
    
    </project>
    

    【讨论】:

    • 嗨史蒂文。这很棒!你知道我是否/如何打开压缩吗?
    • 尝试在&lt;srcfile/&gt; 之前添加&lt;arg value="-x" /&gt; 以将压缩选项传递给更少的编译器。
    • Steven,你这里用的是什么版本的 Rhino js.jar?
    • 那是两年前的事了,所以这里可能不适用。
    【解决方案2】:

    在几个 SO 答案的帮助下,我能够拼凑出一个可行的解决方案:

    ANT script to compile all (css) LESS files in a dir and subdirs with RHINO

    How to correctly execute lessc-rhino-1.6.3.js from command line

    我必须从 GitHub 下载 LESS 1.7.5 并将 Ant 目标修改为如下所示。 -f 参数和 LESS JavaScript 是关键:

    <property name="css.dir" value="WebContent/css"/>
    <property name="less.dir" value="less"/>
    <property name="tool.rhino.jar" value="test-lib/rhino-1.7R4.jar"/>
    <property name="tool.rhino.lessc" value="test-lib/lessc-rhino-1.7.5.js"/>
    <property name="tool.rhino.less" value="test-lib/less-rhino-1.7.5.js"/>
    <target name="compile-less" description="compile css using LESS">
        <apply dir="${css.dir}" executable="java" parallel="false" failonerror="true">
            <fileset dir="${less.dir}">
                <include name="styles.less"/>
            </fileset>
            <arg value="-jar"/>
            <arg path="${tool.rhino.jar}"/>
            <arg value="-f"/>
            <arg path="${tool.rhino.less}"/>
            <arg path="${tool.rhino.lessc}"/>
            <srcfile/>
            <mapper type="glob" from="*.less" to="${css.dir}/*.css"/>
            <targetfile/>
        </apply>
    </target>
    

    【讨论】:

      【解决方案3】:

      如果最近有其他人像我一样提出这个问题,他们可能会发现其他答案中给出的less-rhino-1.1.3.js 文件不适用于最新版本的 Rhino(对我而言,到目前为止,它是1.7R4 来自 MDN)。但是1.4.0 版本可以,可以从Github here 获得。因此,显示了来自我的build.xml 的相关 sn-p,使用这些更高版本。请注意,我只是将单个 .less 文件编译为单个 .css 文件,因此不使用迭代或映射器(但显然您可以从其他答案中获得这些)。我所做的其他调整是将输出文件作为最终 arg 提供给 less,而不是从 Ant 分叉进程中捕获输出,并删除对 ant-contrib 东西的依赖(对于简单的单文件情况不需要)。

      <property name="tool.rhino" value="build/lesscss/rhino1_7R4/js.jar" />
      <property name="tool.less" value="build/lesscss/less-rhino-1.4.0.js" />
      <property name="single-input-lesscss-file" value="/path/to/my/style.less" />
      <property name="single-output-css-file" value="/output/my/style.css" />
      
      <target name="compileLessCss" description="Compile the single less file to css">
          <sequential>
              <java jar="${tool.rhino}" fork="true">
                  <arg path="${tool.less}" />
                  <arg path="${single-input-lesscss-file}" />
                  <arg path="${single-output-css-file}" />
              </java>
          </sequential>
      </target>
      

      【讨论】:

        【解决方案4】:

        如果 maven 适合您,您可以尝试 wro4j-maven-pluginwro4j-runner(这是一个命令行实用程序)。

        使用其中之一,您所要做的就是创建一个资源模型描述符(wro.xml):

        <groups xmlns="http://www.isdc.ro/wro">
          <group name="g1">
            <css>/path/to/*.less</css>
          </group>
        </groups>
        

        其余的将由 wro4j 库处理。犀牛的工作原理或其他细节无需赘述。

        免责声明:我正在从事 wro4j 项目

        【讨论】:

        • 我没用过maven,听了很多,也许我应该看看。目前我编译每个 .less 文件显式。
        • wro4j-runner是一个命令行工具,可以和Ant集成。
        【解决方案5】:

        我有同样的问题。我使用ant-contrib 开发了一个解决方案。它希望您的所有 .less 文件都在一个平面目录中,并被移动到另一个平面目录。它将在此过程中将文件扩展名更改为 .css。

        <property name="tool.rhino" value="/rhino/js.jar" />
        <property name="tool.less" value="src/js/less-rhino-1.1.3.js" />
        <property name="tool.ant-contrib" value="/ant-contrib/ant-contrib-1.0b3-1.0b3.jar" />
        <property name="less-files-dir" value="src/css/" />
        <property name="css-files-dir" value="build/css/" />
        
        <target name="compilecss" depends="setup-ant-contrib-taskdef, get-less-files-in-dir" description="DO THIS THING">
            <for list="${less-files-to-convert}" param="file-name" trim="true" delimiter=",">
                <sequential>
                    <propertyregex property="file-name-without-extension"
                                input="@{file-name}"
                                regexp="(.*)\..*"
                                select="\1"
                                override="yes" />
                    <java jar="${tool.rhino}" fork="true" output="${css-files-dir}${file-name-without-extension}.css">
                        <arg path="${tool.less}" />
                        <arg path="${less-files-dir}@{file-name}" />
                    </java>
                    <echo>Lessjs: generated ${css-files-dir}${file-name-without-extension}.css</echo>
                </sequential>
            </for>
        </target>
        
        <target name="check-for-ant-contrib">
            <condition property="ant-contrib-available">
                <and>
                    <available file="${tool.ant-contrib}"/>
                </and>
            </condition>
            <fail unless="ant-contrib-available" message="Ant-Contrib is not available."/>
        </target>
        
        <target name="setup-ant-contrib-taskdef" depends="check-for-ant-contrib">
            <taskdef resource="net/sf/antcontrib/antlib.xml">
                <classpath>
                    <path location="${tool.ant-contrib}" />
                </classpath>
            </taskdef>
        </target>
        
        <target name="get-less-files-in-dir">
            <var name="files-list" value="" />
            <for param="file">
                <path>
                    <fileset dir="${less-files-dir}" includes="**/*.less" />
                </path>
                <sequential>
                    <propertyregex property="file-name-and-relative-path"
                            input="@{file}"
                            regexp=".*\\(.*)"
                            select="\1"
                            override="yes" />
                    <echo>file name: ${file-name-and-relative-path}</echo>
                    <if>
                        <equals arg1="${files-list}" arg2="" />
                        <then>
                            <var name="files-list" value="${file-name-and-relative-path}" />
                        </then>
                        <else>
                            <var name="files-list" value="${files-list},${file-name-and-relative-path}" />
                        </else>
                    </if>
                </sequential>
            </for>
            <property name="less-files-to-convert" value="${files-list}" />
            <echo>files to convert: ${less-files-to-convert}</echo>
        </target>
        

        【讨论】:

        • 我没有平面结构,但感谢您展示了 ant-contrib 的解决方案。它可能会被修改为与子目录一起使用。我一直在寻找标准 ANT 的解决方案,但我想,从给定的 awnsers 来看这是不可能的。
        • 您为此使用了哪个版本的 Rhino js.jar?我现在正在尝试同样的事情,但没有找到输出。也就是说,没有写入输出文件。也尝试过启用 Rhino 的详细输出(-v 选项,如 here 所述)无济于事。我用的是最新的Rhino,1_7R4。
        【解决方案6】:

        我无法使用 JDK 1.6 来运行它,因为 javascript 内容已被合并到 JDK 中。 JDK 在发行版中确实有一个 jrunscript 可执行文件,但是当我尝试运行 less-rhino.js 文件时,它无法识别任何 readFile() 函数。有没有人调查过。否则我可能会尝试使用lesscss-engine 并增强它以理解文件集。

        【讨论】:

        • 马特,这方面有什么进展吗?你设法让它与jrunscript一起工作吗?