如何将 Maven 执行仅定位到构建文件夹?

How to target maven executions to the build folder only?

我有一个使用 Maven 和 frontend-maven-plugin (com.github.eirslett) 的项目。

因为我 运行 mvn install 来自插件 运行 的所有执行,它们创建了 node_modulesbower_componentsnode src/main/webapp 根目录中的文件夹,其中是实际的前端代码。

问题是,我想 mvn install 只在 war 目录中生成的包中执行和创建 build 目录中的那些,而不是在版本化的应用程序代码中,就像它一样使用 Java 个库。

有办法实现吗?

这是我pom.xml的相关部分:

<build>
    <directory>build</directory>
    <outputDirectory>build/classes</outputDirectory>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.3</version>
            <configuration>
                <source>${java.version}</source>
                <target>${java.version}</target>
                <encoding>UTF-8</encoding>
                <webResources>
                    <resource>
                        <filtering>true</filtering>
                        <directory>src/main/webapp</directory>
                        <includes>
                            <include>WEB-INF/weblogic.xml</include>
                        </includes>
                    </resource>
                </webResources>
            </configuration>
        </plugin>
        ...
        <plugin>
            <groupId>com.github.eirslett</groupId>
            <artifactId>frontend-maven-plugin</artifactId>
            <version>0.0.20</version>

            <configuration>
                <workingDirectory>src/main/webapp</workingDirectory>
            </configuration>

            <executions>
                <execution>
                    <id>install node and npm</id>
                    <goals>
                        <goal>install-node-and-npm</goal>
                    </goals>
                    <configuration>
                        <nodeVersion>v0.10.34</nodeVersion>
                        <npmVersion>2.1.11</npmVersion>
                    </configuration>
                </execution>

                <execution>
                    <id>npm install</id>
                    <goals>
                        <goal>npm</goal>
                    </goals>
                    <configuration>
                        <arguments>install</arguments>
                    </configuration>
                </execution>

                <execution>
                    <id>bower install</id>
                    <goals>
                        <goal>bower</goal>
                    </goals>
                    <configuration>
                        <arguments>install</arguments>
                    </configuration>
                </execution>

                <execution>
                    <id>grunt build</id>
                    <goals>
                        <goal>grunt</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        ...
    </plugins>
</build>

插件(frontend-maven-plugin)主要支持这个。 "workingDirectory" 参数告诉插件在哪里进行工作(即 npm install)。这要求构建文件(即 package.json、gruntFile.js)位于该工作目录中。为了解决这个问题,我添加了一个 antrun 执行来在构建的其余部分之前复制这些文件(通过过滤)。然后,我的 grunt 文件会在适当的时候引用源文件,任何输出都会进入我的 target-grunt 文件夹。

这是我的配置:

        <plugin>
            <groupId>com.github.eirslett</groupId>
            <artifactId>frontend-maven-plugin</artifactId>
            <version>0.0.20</version>
            <configuration>
                <workingDirectory>target-grunt</workingDirectory>
            </configuration>
            <executions>
               ...
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-antrun-plugin</artifactId>
            <executions>
                <execution>
                    <id>prepare-grunt</id>
                    <phase>generate-resources</phase>
                    <goals>
                        <goal>run</goal>
                    </goals>
                    <configuration>
                        <target>
                            <!-- copy, filter, rename -->
                            <filter token="moduleName" value="${moduleName}" />
                            <filter token="project.version" value="${project.version}" />
                            <filter token="project.artifactId" value="${project.artifactId}" />
                            <copy file="${basedir}/target-grunt/imported-js/main/js/com/verisk/underwriting/config/grunt/npm-package-module/0.0.1/npm-package-module-0.0.1.js" tofile="${basedir}/target-grunt/package.json" filtering="true" failonerror="true" verbose="true" />
                            <copy file="${basedir}/Gruntfile.js" tofile="${basedir}/target-grunt/Gruntfile.js" failonerror="true" verbose="true" />
                        </target>
                    </configuration>
                </execution>
            </executions>
        </plugin>

可以使用 <installDirectory> 配置参数来选择安装 NodeJS 的位置。

frontend-maven-plugin 将在 package.json 所在的位置安装 node_modules。这就是为什么您需要向某些 target/<sub-path>.

提供 package.json 的网络资源副本的原因

那么frontend-maven-plugin可以这样配置:

       <plugin>
            <groupId>com.github.eirslett</groupId>
            <artifactId>frontend-maven-plugin</artifactId>
            <version>0.0.24</version>

            <configuration>
                <nodeVersion>v0.11.14</nodeVersion>
                <npmVersion>2.13.4</npmVersion>
                <installDirectory>target/<sub-path></installDirectory>
                <workingDirectory>target/<sub-path></workingDirectory>
            </configuration>
            ...

为了不弄脏前端资源目录的可能方法,作为示例包含在 src/main/frontendResources 中,来自 GIT(或另一个源代码库)和 node_modules, bower_components, ..., 在 npm、bower 和 grunt 执行过程中生成的目录和文件是:

  1. 使用 maven-resources-plugin,复制源目录 src/main/frontendResources/target/webappStagingDir 子文件夹中 初始化阶段
  2. 设置 workingDirectoryinstallDirectoryfrontend-maven-plugin/target/webappStagingDir
  3. 将 bower 输出目录设置为 /target/webappStagingDir 的子文件夹。
    例如把

    {"directory": "bower_components"}

    在 .bowerrc 文件中

  4. 在构建 Bower 之后,使用 maven-resources-plugin,复制包含在中的输出构建源 bower_components 文件夹到 /target/${artifactId}-${version} 准备包阶段(war 构建之前)

这是 pom 切片:

...
<plugin>
    <groupId>com.github.eirslett</groupId>
    <artifactId>frontend-maven-plugin</artifactId>
    <version>1.6</version>

    <configuration>
        <workingDirectory>${basedir}/target/frontendResourcesStagingDir</workingDirectory>
        <installDirectory>${basedir}/target/frontendResourcesStagingDir</installDirectory>
    </configuration>

    <executions>
        <execution>
            <id>install node and npm</id>
            <phase>generate-resources</phase>
            <goals>
                <goal>install-node-and-npm</goal>
            </goals>
            <configuration>
                <nodeVersion>v8.12.0</nodeVersion>
                <npmVersion>6.4.1</npmVersion>
            </configuration>
        </execution>        
        <execution>
            <id>npm install</id>
            <phase>generate-resources</phase>
            <goals>
                <goal>npm</goal>
            </goals>
            <configuration>
                <arguments>install</arguments>
            </configuration>
        </execution>
        <execution>
            <id>bower install</id>
            <phase>generate-resources</phase>
            <goals>
                <goal>bower</goal>
            </goals>
            <configuration>
                <arguments>install</arguments>
            </configuration>
        </execution>
        <execution>
            <id>grunt build</id>
            <phase>generate-resources</phase>
            <goals>
                <goal>grunt</goal>
            </goals>
            <configuration>
                <arguments>build</arguments>
            </configuration>
        </execution>
    </executions>
</plugin>

<plugin>
    <artifactId>maven-resources-plugin</artifactId>
    <version>3.1.0</version>
    <executions>
        <!-- 
            Copy of the /frontendResources directory, coming from GIT, in /target directory
            executed before the compiling and build of frontend resources
            That dir will be the working directory of npm, bower, grunt
            in order to avoid the creation of the direcotries node, node_modules, bower_components, ...
            (they may be committed in repository)
        -->
        <execution>
            <id>copy-frontendResources-toStagingDir-beforeBuild</id>
            <phase>initialize</phase>
            <goals>
                <goal>copy-resources</goal>
            </goals>
            <configuration>
                <outputDirectory>${basedir}/target/frontendResourcesStagingDir</outputDirectory>
                <resources>          
                    <resource>
                        <directory>${basedir}/src/main/frontendResources</directory>
                        <filtering>true</filtering>
                    </resource>
                </resources>              
            </configuration>            
        </execution>
        <!-- 
            Copy of the /frontendResourcesStagingDir/grunt_output directory in /target/ directory
            executed after build of frontend resources and before the war pachage creation
            it contains the output of grunt install execution
        -->
        <execution>
            <id>copy-frontendResources-afterBuild</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>copy-resources</goal>
            </goals>
            <configuration>
                <outputDirectory>${basedir}/target/${artifactId}-${version}</outputDirectory>
                <resources>          
                    <resource>
                        <directory>${basedir}/target/frontendResourcesStagingDir/grunt_output</directory>
                        <filtering>true</filtering>
                    </resource>
                </resources>              
            </configuration>            
        </execution>
    </executions>
</plugin>
...

此解决方案也适用于前端在 Node.js 和后端在 Java 的混合项目,其中有一个 .war 文件作为输出可交付成果