【问题标题】:Is it possible to compile grunt project from maven?是否可以从 maven 编译 grunt 项目?
【发布时间】:2013-02-18 18:13:49
【问题描述】:

我正在尝试从 maven 中执行 grunt 任务,而无需安装 Node.js 或任何东西。这是因为我不想让 Jenkins 打包我的工件,并且我无法在该机器上安装 Node.js。

我知道使用 npm 和一些命令很容易让它工作,但我也认为它应该很容易与 maven 集成,问题是我不知道从哪里开始,因为我是新手到 npm。

【问题讨论】:

    标签: java node.js maven gruntjs


    【解决方案1】:

    是的,使用 frontend-maven-plugin,您可以通过 Maven 编译 Grunt 项目(通过 NodeJS mailing list 找到)。

    正如文档所指出的,该插件具有以下功能:

    • 让您的前端和后端构建尽可能分开,将它们之间的交互量减少到最低限度;仅使用 1 个插件。
    • 让您在构建过程中使用 Node.js 及其库,而无需为构建系统全局安装 Node/NPM
    • 让您确保在每个构建环境中运行的 Node 和 NPM 的版本都相同

    我已经浏览了代码,它相当简单。谢天谢地,终于有人把它放在一起了;这是一个优雅的解决方案。存储库包含使用常规 Gruntfile.js 调用 jshint 分析的 an example

    【讨论】:

    • 这个插件很棒!引用自述文件:并不是要替换 Node 的开发者版本 - 前端开发者仍然会在他们的笔记本电脑上安装 Node,但后端开发者可以运行干净的构建,甚至无需在他们的计算机上安装 Node
    • 我在多个项目中使用它,它很棒。需要注意的一件事是将为正在运行的系统下载节点,因此如果您的构建服务器上有不同的操作系统,您需要确保这是您已签入版本控制的版本,您的本地版本(对我来说是 OSX)必须在您的项目本地维护。
    • 另一种选择是 .gitignore 的“节点”文件夹(可执行文件的最终位置),这样每个架构都有自己的。
    【解决方案2】:

    2014-09-19 更新:这不再是最准确的答案 - 请查看下面的其他一些答案。在我回答这个问题时,它是准确的,但从那时起,这方面似乎取得了很大进展。

    恐怕你运气不好。 Grunt 是使用 node 构建的,需要使用 npm 安装。如果您不想使用 npm,您也许可以从另一台机器复制现有的 Grunt 安装,但仍将使用 grunt 可执行文件及其在构建服务器上的所有依赖项。

    除此之外,许多 Grunt 任务都是作为 Node.js 模块实现的,您还必须安装它们。同样,您可能可以从另一台服务器复制它们,在该服务器上您已经完成了 Node.js/Grunt 的安装,但在某一时刻,您必须这样做。

    要从 Maven 运行 Grunt,最好的办法是使用 Maven exec 插件,然后从那里执行 grunt 可执行文件。

    作为替代方案,有几个 Maven 插件允许您以基于 Java 的方式执行类似于 Grunt 的操作。它们需要与 Grunt 不兼容的额外配置,因此需要使用 YMMV。我过去使用的一个是http://code.google.com/p/wro4j/,它也带有一个 Maven 插件:http://code.google.com/p/wro4j/wiki/MavenPlugin

    您无法在构建服务器上安装 Node.js 的任何特殊原因?

    【讨论】:

    • 谢谢@nwinkler!非常完整的答案。没有什么特别的原因,当我已经有一个可以处理我的项目要求的构建系统时,我发现安装额外的构建系统有点尴尬。在尝试使用 grunt 之前,我使用 compass 和 maven 来构建 sass:gist.github.com/mkristian/1671207。然后我看到 Grunt 可以处理这些以及更多。由于使用 JRuby,我能够在目标目录中安装 ruby​​ gem 并从那里运行它,我认为使用 Node.js 和 Grunt 也可以实现类似的功能。好像可以,但是还没有复制粘贴的方式
    • 要从 Maven 运行 Grunt,您可以使用 grunt-maven-plugin。请参阅下面的答案。
    • 我推荐frontend-maven-plugin,请参阅下面的答案。
    【解决方案3】:

    您可以使用grunt-maven-plugin。它允许您轻松地将 Grunt 任务集成到 Maven 构建过程中。没有肮脏的黑客攻击。

    这是我在当前项目中使用的,效果非常好。

    【讨论】:

    • 您是否尝试过集成 nodejs-maven-plugin 之类的东西来抽象 NodeJS 运行时安装?
    • @b.long 不,我们不喜欢有一个来自 maven Central 的由某人管理的 nodejs 工件的想法。这样我们就无法控制 nodejs 的版本,就像我们喜欢的时候拥有最新版本一样。
    • 这是可以理解的,当然是一个合理的担忧。感谢您的更新:)
    • @pbetkier 你有什么配置示例可以分享吗?我正在为 grunt 找不到我的 js 文件而苦苦挣扎。
    【解决方案4】:

    最后我得到了这个(足够接近但没有解决问题):

    <plugin>
    <groupId>org.mule.tools.javascript</groupId>
    <artifactId>npm-maven-plugin</artifactId>
    <version>1.0</version>
    <executions>
        <execution>
            <phase>generate-resources</phase>
                <goals>
                    <goal>fetch-modules</goal>
                </goals>
                <configuration>
                    <packages>
                        <package>grunt-cli:0.1.6</package>
                    </packages>
                </configuration>
            </execution>
        </executions>
    </plugin>
    

    在本地安装 grunt-cli,但如果我没有安装 node.js,它就毫无价值。虽然我尝试在本地安装 node.js,但需要安装 python、g++ 和 make。所以我将使用 KISS 解决方案:在构建服务器中安装 grunt。

    参考:
    https://github.com/mulesoft/npm-maven-plugin
    https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager
    https://github.com/mcheely/requirejs-maven-plugin

    【讨论】:

    【解决方案5】:

    您可能想查看http://jhipster.github.io/:它是一个 Yeoman 生成器,它生成的应用程序包含 Maven、Grunt 和 Bower 一起工作。

    这有点像您的第三个选项,但一切都是为您配置的,这并不容易。它还为您生成基本的 AngularJS 和 Java REST 服务

    【讨论】:

      【解决方案6】:

      这是一个完整的复制/粘贴解决方案,在 2017 年使用 frontend-maven-plugin 进行前端构建,使用 maven-war-plugin 构建战争。

      它有什么作用?安装 npm、bower grunt 和你需要的一切,然后运行 ​​npm install、bower install,最后运行 grunt build。

      您可以删除/添加替换您想要的步骤,对我来说,这是一个完整的 30 秒安装/构建库和项目。

      <dependencies>
        ...
      </dependencies>
      
      <dependencyManagement>
          <dependencies>
              <!-- https://mvnrepository.com/artifact/com.github.eirslett/frontend-maven-plugin -->
              <dependency>
                  <groupId>com.github.eirslett</groupId>
                  <artifactId>frontend-maven-plugin</artifactId>
              </dependency>
          </dependencies>
      </dependencyManagement>
      
      <build>
          <pluginManagement>
              <plugins>
                  <plugin>
                      <groupId>org.apache.maven.plugins</groupId>
                      <artifactId>maven-war-plugin</artifactId>
                      <version>2.4</version>
                      <configuration>
                          <warSourceDirectory>src/main/webapp/YourFrontJsFolder/dist</warSourceDirectory>
                          <warName>YouWarName</warName>
                          <failOnMissingWebXml>false</failOnMissingWebXml>
                          <warSourceExcludes>node_modules/**</warSourceExcludes>
                          <includeScope>system</includeScope>
                          <webResources>
                              <resource>
                                  <directory>WebContent/WEB-INF</directory>
                                  <targetPath>WEB-INF</targetPath>
                                  <includes>
                                      <include>**/*.jar</include>
                                      <include>**/*.jsp</include>
                                  </includes>
                              </resource>
                          </webResources>
                      </configuration>
                  </plugin>
      
                  <plugin>
                      <groupId>org.apache.maven.plugins</groupId>
                      <artifactId>maven-compiler-plugin</artifactId>
                      <version>3.3</version>
                      <configuration>
                          <source>1.7</source>
                          <target>1.7</target>
                          <encoding>Cp1252</encoding>
                      </configuration>
                  </plugin>
              </plugins>
          </pluginManagement>
      
          <finalName>YourAppName</finalName>
      </build>
      
      <profiles>
          <profile>
              <id>release</id>
              <build>
                  <plugins>
                      <plugin>
                          <groupId>com.github.eirslett</groupId>
                          <artifactId>frontend-maven-plugin</artifactId>
                          <executions>
                              <execution>
                                  <!-- optional: you don't really need execution ids, but it looks 
                                      nice in your build log. -->
                                  <id>install node and npm</id>
                                  <goals>
                                      <goal>install-node-and-npm</goal>
                                  </goals>
                                  <!-- optional: default phase is "generate-resources" -->
                                  <phase>generate-resources</phase>
      
                                  <configuration>
                                      <nodeVersion>v7.6.0</nodeVersion>
                                  </configuration>
                              </execution>
      
                              <execution>
                                  <id>npm install</id>
                                  <goals>
                                      <goal>npm</goal>
                                  </goals>
      
                                  <!-- optional: default phase is "generate-resources" -->
                                  <phase>generate-resources</phase>
      
                                  <configuration>
                                      <arguments>install</arguments>
                                  </configuration>
                              </execution>
      
                              <execution>
                                  <id>bower install</id>
                                  <goals>
                                      <goal>bower</goal>
                                  </goals>
      
                                  <configuration>
                                      <!-- optional: The default argument is actually "install", so unless 
                                          you need to run some other bower command, you can remove this whole <configuration> 
                                          section. -->
                                      <arguments>install</arguments>
                                  </configuration>
                              </execution>
      
                              <execution>
                                  <id>grunt build</id>
                                  <goals>
                                      <goal>grunt</goal>
                                  </goals>
      
                                  <!-- optional: the default phase is "generate-resources" -->
                                  <phase>generate-resources</phase>
      
                                  <configuration>
                                      <!-- optional: if not specified, it will run Grunt's default task 
                                          (and you can remove this whole <configuration> section.) -->
                                      <arguments>build</arguments>
                                  </configuration>
                              </execution>
                          </executions>
      
                          <configuration>
                              <installDirectory>target</installDirectory>
                              <workingDirectory>src/main/webapp/YourFrontJsFolder</workingDirectory>
                          </configuration>
                      </plugin>
                  </plugins>
              </build>
          </profile>
          <profile>
              <id>debug</id>
              <activation>
                  <activeByDefault>true</activeByDefault>
              </activation>
          </profile>
          <profile>
              <id>IDE</id>
              <activation>
                  <property>
                      <name>m2e.version</name>
                  </property>
              </activation>
              <build>
                  <!-- Put the IDE's build output in a folder other than target, so that 
                      IDE builds don't interact with Maven builds -->
                  <directory>target-ide</directory>
              </build>
          </profile>
      </profiles>
      

      然后你可以Run as -> Maven build ...,目标clean install和个人资料release

      【讨论】:

      • 谢谢!我现在正在使用这个解决方案!
      【解决方案7】:

      第一个问题是 Maven 是 Java,但是 Grunt.js 在 Node.js 运行时上运行。我在两者之间实现的最简单的集成涉及 maven-exec-plugin。 maven-exec-plugin 能够执行 .sh/.bat/.cmd 脚本,无论您使用的操作系统是本机的。因此,在 Maven 构建期间,我会让 maven-exec-plugin 执行一个名为 optimize-js.sh 的脚本,例如,它会简单地执行类似“grunt release –force”之类的操作。脚本可以做任何事情。重要的是配置 maven-exec-plugin 以在正确的工作目录中执行它们。当然,“grunt”和“node”需要在命令行中执行。

      【讨论】:

        【解决方案8】:

        如果问题是在 Jenkins 机器上安装 NodeJS,那么您可以使用 NodeJS Jenkins 插件。

        https://wiki.jenkins-ci.org/display/JENKINS/NodeJS+Plugin

        我们还没有将它与 Maven 一起使用(还),但我们正在运行 grunt。

        【讨论】:

          【解决方案9】:

          可以使用 exec-maven-plugin 来完成。

          在你的 package.json 中定义一个 script 和对 grunt-cli 的依赖:

          ...
            "scripts": {
              "build": "./node_modules/.bin/grunt install"
            },
            "devDependencies": {
            "grunt-cli": "^1.2.0",
          ...
          

          在你的 pom 中,添加要运行的命令:

                  <plugin>
                      <groupId>org.codehaus.mojo</groupId>
                      <artifactId>exec-maven-plugin</artifactId>
                      <version>X.Y.Z</version>
                      <executions>
                          <execution>
                              <id>exec-npm-install</id>
                              <phase>generate-sources</phase>
                              <configuration>
                                  <workingDirectory>${project.basedir}</workingDirectory>
                                  <executable>npm</executable>
                                  <arguments>
                                      <argument>install</argument>
                                  </arguments>
                              </configuration>
                              <goals>
                                  <goal>exec</goal>
                              </goals>
                          </execution>
                          <execution>
                              <id>exec-grunt-install</id>
                              <phase>generate-sources</phase>
                              <configuration>
                                  <workingDirectory>${project.basedir}</workingDirectory>
                                  <executable>npm</executable>
                                  <arguments>
                                      <argument>run</argument>
                                      <argument>build</argument>
                                  </arguments>
                              </configuration>
                              <goals>
                                  <goal>exec</goal>
                              </goals>
                          </execution>
                      </executions>
                  </plugin>
          

          它现在将在 mvn 包

          上运行

          【讨论】:

            猜你喜欢
            • 2021-06-25
            • 2016-10-27
            • 2016-12-13
            • 1970-01-01
            • 1970-01-01
            • 2014-03-09
            • 1970-01-01
            • 2011-04-18
            • 1970-01-01
            相关资源
            最近更新 更多