使用Maven构建复杂的Flex项目

2023-12-19

我目前正在考虑用 Maven 替换我们专有的构建环境。当前的解决方案是中央构建的内部开发,为了更轻松的本地开发,我在 Eclipse/Flex IDE 内进行编译,并使用 ANT 脚本将所有内容一起复制到我的本地 Apache 目录(即我的 ant 文件不执行完整构建)并且还依赖于所有项目都在本地可用)。

我们使用 Eclipse 3.6.1 (Helios) 和 Flash Builder 插件(即 Flex4),目标是 Flex SDK 3.5 (FlashPlayer 10.0),其中有相当多的项目,包括要在运行时加载的 .swc 库项目和 .swf 模块,包括每个项目的资源。我们还使用外部链接/运行时共享库​​(一个大的sharedlibraries.swf包含所有内容,即部署中不需要.swc文件)。我已经使用 Sonatypes 安装了 Maven 3.0.2flexmojos-maven-插件 3.7.1 https://repository.sonatype.org/content/sites/maven-sites/flexmojos/3.8/plugin-info.html(因为它看起来比 Servebox 的更活跃)。我已经为每个 Eclipse 项目手动创建了 pom 文件,以确保一切正常,而且 Eclipse-Maven 集成似乎缺乏 Flex 支持。我已经定义了适当的编译器和依赖项参数,以便所有单独的项目都能正确编译 - 即生成的 .swf 文件确实会生成我们应用程序的工作版本。我也读过《Maven 示例 http://www.sonatype.com/books/mvnex-book/reference/public-book.html“来自 Sonatype 的书并查看了他们的”Maven:完整参考 http://www.sonatype.com/books/mvnref-book/reference/public-book.html”,同时并行进行大量谷歌搜索。

我正在努力解决的是我的项目的最终组装,以及其他工件(样式表)。我并不完全理解“Maven 方式”,并且还怀疑 Maven 是专门为 Java 量身定制的,因此让我对 Flex 项目感到有些茫然。

我的项目的基本结构:

  • 外部库:我已将那些带有 install:install-file 的库添加到我的存储库中,这里没有问题
  • 自己的库项目:它们每个都会生成一个 .swc 工件,可以在其他项目中使用,并且 Maven 依赖项处理工作正常,这里没有问题
  • 自己的 swf 模块项目:我们的应用程序在运行时加载 swf 文件,而这些文件又需要一些额外的资源(stylesheet.swf 文件、本地化字符串作为单独的 .xlf 文件、配置文件等)。正是那些我正在挣扎的人。

我的 swf 项目的布局:

  • bin-调试/由 IDE 构建使用,由 Maven 构建不使用/忽略
  • src/Flex 源(.as 和 .mxml 文件)
  • target/Maven 目标目录
  • 网页内容/包含补充文件的目录,需要将其与 .swf 工件一起逐字复制到目标工件(目录或 zip 文件)
  • styles/Flex .css 文件需要编译成 .swf 样式表文件,这些文件是主项目 swf 和 WebContent/ 内容的附加工件(每个 .css 一个,用于不同的主题)

我使用平面层次结构在 Eclipse 中工作,即我的主 pom 文件放置在与所有项目文件夹同级的文件夹中。例子:

project_swf/src/...
project_swf/WebContent/assets/labels.xlf
project_swf/WebContent/config/config.xml
project_swf/pom.xml
lib_swc/src/...
lib_swc/pom.xml
master_build/pom.xml
master_build/swf-assembly.xml

我已经成功创建了一个“主构建”,使用它来构建我的所有 SWC 和 SWF 项目大师 pom:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <name>Dragon Master Build</name>
    <description>This project can be used to build and package the client application</description>

    <properties>
        <!-- this needs to be the same as the groupId tag, which unfortunately cannot be accessed directly using ${} notation -->
        <group-id>de.zefiro.maven.example</group-id>

        <!-- parameter to plugin swf files, shown as plugin 'Build Number' in client -->
        <!-- TODO should be a build number on central system -->
        <zefiro.plugin.buildno>local_dev_mvn</zefiro.plugin.buildno>

        <!-- build all SWF files (except sharedlibraries.swf) with external references (Note: Flexmojo abuses the 'scope' concept here, but there is currently no better way) -->
        <zefiro.swf.scope>external</zefiro.swf.scope>
    </properties>

    <groupId>de.zefiro.maven.example</groupId>
    <artifactId>full_build</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <build>
        <sourceDirectory>src/</sourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.sonatype.flexmojos</groupId>
                <artifactId>flexmojos-maven-plugin</artifactId>
                <version>3.7.1</version>
                <extensions>true</extensions>
                <!-- We need to compile with Flex SDK 3.5 -->
                <dependencies><dependency>
                    <groupId>com.adobe.flex</groupId>
                    <artifactId>compiler</artifactId>
                    <version>3.5.0.12683</version>
                    <type>pom</type>
                </dependency></dependencies>
                <!-- configuration for the Flex compilation -->
                <configuration>
                    <targetPlayer>10.0.0</targetPlayer>
                    <incremental>false</incremental>
                    <debug>false</debug>
                    <runtimeLocales></runtimeLocales>
                    <locale>en_US</locale>
                    <optimize>true</optimize>
                    <showWarnings>true</showWarnings>
                    <strict>true</strict>
                    <useNetwork>true</useNetwork>
                    <allowSourcePathOverlap>true</allowSourcePathOverlap>
                    <definesDeclaration>
                        <property>
                            <name>ZEFIRO::META_INFO</name>
                            <value>"buildno=${zefiro.plugin.buildno}"</value>
                        </property>
                    </definesDeclaration>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>com.adobe.flex.framework</groupId>
            <artifactId>flex-framework</artifactId>
            <version>3.5.0.12683</version>
            <type>pom</type>
            <exclusions>
                <!-- make sure to exclude the default 'playerglobal' transitive dependency (which would be version 9 for SDK 3.5, however, we want version 10) -->
                <exclusion>
                    <groupId>com.adobe.flex.framework</groupId>
                    <artifactId>playerglobal</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>com.adobe.flex.framework</groupId>
            <artifactId>playerglobal</artifactId>
            <!-- this artifact version must match the flex SDK version used in this project -->
            <version>3.5.0.12683</version>
            <!-- the classifier specifies the target flash player major version (default is 9 for SDK 3.5) -->
            <classifier>10</classifier>
            <type>swc</type>
        </dependency>

        [... some more dependencies needed by all projects ...]
    </dependencies>

    <modules>
        <module>../lib_swc</module>
        <module>../project_swf</module>
        [... calls all my projects ...]
    </modules>

</project>

然后我可以编译我的SWC 图书馆项目使用这个简单的 POM:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>de.zefiro.maven.example</groupId>
        <artifactId>full_build</artifactId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../master_build</relativePath>
    </parent>

    <name>Sample library project</name>
    <artifactId>lib_swc</artifactId>
    <packaging>swc</packaging>

    <dependencies>
        <dependency>
            <groupId>${group-id}</groupId>
            <artifactId>some_other_library</artifactId>
            <version>${project.version}</version> <!-- I should probably look into dependency/versioning as well, but for now this works -->
            <!-- Note: no 'Scope' here, swc files will be build "merged into code"-style. Needed as transitive dependencies don't work with Maven/Flex - we use 'external' scope for the final swf projects dependencies -->
            <type>swc</type>
        </dependency>
    </dependencies>

</project>

And my SWF项目有了这个 POM:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>de.zefiro.maven.example</groupId>
        <artifactId>full_build</artifactId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../master_build</relativePath>
        </parent>

    <name>Sample SWF module</name>
    <artifactId>project_swf</artifactId>
    <packaging>swf</packaging>

    <build>
    <!-- This name needs to be exactly specified, as the runtime will load it as it's specified in the configuration xml -->
        <finalName>SampleProjectModule1</finalName>

        <!-- define the master source file, it's picked up for some projects automatically and must be specified for others. Inherits compiler parameters from parent. -->
        <plugin>
            <groupId>org.sonatype.flexmojos</groupId>
            <artifactId>flexmojos-maven-plugin</artifactId>
            <version>3.7.1</version>
            <configuration>
                <sourceFile>project_swf_master_file.as</sourceFile>
            </configuration>
        </plugin>

        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <descriptors>
                        <descriptor>../master_build/swf-assembly.xml</descriptor>
                    </descriptors>
                </configuration>
                <executions>
                    <execution>
                        <id>WebContent-packaging</id>
                        <phase>package</phase>
                        <goals><goal>single</goal></goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>${group-id}</groupId>
            <artifactId>project_swc</artifactId>
            <version>${project.version}</version>
            <scope>${zefiro.swf.scope}</scope> <!-- tell Flex Mojo that we want to compile using runtime shared libraries (rsl) -->
            <type>swc</type>
        </dependency>
        [...]
    </dependencies>

</project>

据我了解,每个 POM 文件都会生成一个目标文件(用打包标签指定),并且在使用 Flex mojo 时,它需要采用 swf 或 swc 格式。我似乎无法在这里指定多个目标,并且还很难包含我的资源文件(Flex copy-resources 复制我不需要的 html 包装器(对于每个项目),普通资源标签复制资源,但不不打包它们)。现在我当前的工作版本是指定一个自己的程序集描述符,它将我的目标 .swf 文件与 WebContent/ 文件夹一起捆绑到一个 zip 文件中。 Maven 支持 jar/war/bin 文件,但这些文件似乎期望某些条件为真,这不适用于我的 Flex 项目(例如,我没有 web.xml)

swf- assembly.xml:

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
    <id>WebContent</id>
    <formats>
        <format>zip</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <fileSets>
        <!-- Take the base swf artifact (only, not the other stuff which is generated there) -->
        <fileSet>
            <directory>${project.build.directory}</directory>
            <outputDirectory>/</outputDirectory>
            <includes>
                <include>*.swf</include>
            </includes>
        </fileSet>
        <!-- add the WebContent folder -->
        <fileSet>
            <directory>FCPContent</directory>
            <outputDirectory>/</outputDirectory>
        </fileSet>
    </fileSets>
</assembly>

现在,我已经获得了目标目录,其中包含单独的 .swf 文件和包含 .swf 文件以及 WebContent/ 资源的 zip 文件。在调用“mvn install”时它也会被放置在 Nexus 存储库中,因此这看起来是一个很好的进步。虽然如果更好的话我很乐意做完全不同的事情,因为我的最终目标是拥有一个目录(或包含它的 zip/war 文件),其中包含一些静态文件(我们的 html 包装器和加载器 swf + configuration.xml ),对于我们的每个 swf 项目(我们在运行时加载的模块),都有一个包含 .swf 文件和 WebContent/ 资源的目录 - 即我现在可以为每个项目创建的 zip 文件的内容。

index.html
loader.swf
config.xml
project_swf/SampleProjectModule1.swf
project_swf/assets/labels.xlf
project_swf/config/config.xml
project2_swf/module2.swf
project2_swf/cool_colors_stylesheet.swf

所以我的问题是:如何定义这样一个以这种格式创建最终程序集的 Maven 主项目?如果没有其他方法,一个有效的 ANT 文件可能是可以接受的,尽管我读到 Maven 敦促我们远离这些 hack :)

我还需要编译样式表文件,这些文件是 swf 项目的附加工件。我将为此发布一个单独的问题。


我的解决方案有点复杂,感觉“肮脏” - 我认为可能有一种更干净的方法,但至少我现在已经运行它了。

基本上,我使用 Maven-assemble-plugin 创建中间 zip 存档(“war”同样有效),其中包含 swf 可执行文件以及我正在创建的每个插件的任何必要的静态资产(我们使用 OSGi -like动态加载器类似于Eclipse的工作方式,其中一个静态文件是plugin.xml,其他是翻译文件,它们都不能嵌入到.swf中)。 Maven 将 .swf 文件以 Maven 文件名表示法存储为主要工件(我完全忽略了这一点)以及我的 zip 存档(根据 FinalName 标签使用 .swf 名称)。 POM 和程序集文件的工作原理如我原来的问题所示。

我添加了一个空白的装配项目,其唯一目标是依赖并因此包括我的所有其他项目。该项目的输出是我最终的“真实”工件,然后我可以将其用于分发和部署。由于我不想将太多帮助程序项目聚集到我的 Eclipse 工作区中,因此我打破了 Maven 项目和 Eclipse 项目的 1:1 关系:我的 Maven 程序集插件仅位于我的 master_build 项目内的子目录“程序集”中。我在我的主 pom (master_build/pom.xml) 中为其添加了一个模块语句,该语句将作为最后一个项目在反应器中执行。 (由于给定的依赖关系,排序是自动完成的 - 如果您将其指定为第一个模块并且它不是最后执行的,那么您正在构建不需要的项目:)

我还将我的装配项目 POM 设为我的主 POM 的子项目。这不是必需的,但通过这样做我可以继承我定义的 Maven 属性。它还继承了对 Flex 编译器的调用,不过由于这里没有任何可编译的内容,因此这并没有什么坏处。 YMMV。

这是 POM:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>de.zefiro.maven.example</groupId>
        <artifactId>full_build</artifactId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../</relativePath>
    </parent>


    <groupId>${group-id}</groupId>
    <artifactId>full_assembly</artifactId>
    <name>Final Assembly</name>
    <version>${project.parent.version}</version>
    <packaging>pom</packaging> <!-- note that this is POM here, not war or zip -->

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.2.1</version>
                <configuration>
                    <descriptors>
                        <descriptor>final-assembly.xml</descriptor>
                    </descriptors>
                </configuration>
                <executions>
                    <execution>
                        <id>Final-Packaging</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>de.zefiro.maven.example</groupId>
            <artifactId>wrapper</artifactId>
            <version>1.0</version>
            <type>war</type>
        </dependency>
        <dependency>
            <groupId>${group-id}</groupId>
            <artifactId>project_swf</artifactId>
            <version>${project.version}</version>
            <type>zip</type>
            <classifier>WebContent</classifier> <!-- needs to be the ID of the assembler xml which packaged the zip file -->
        </dependency>
[... all other projects which should be packaged ...]
    </dependencies>
</project>

遵循程序集描述符。请参阅程序集描述符文档 http://maven.apache.org/plugins/maven-assembly-plugin/assembly.html了解详情。

<assembly
    xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
    <id>FinalAssembly</id>
    <formats>
        <format>war</format> <!-- can be either zip or war, depending on what you wish -->
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <dependencySets>
        <dependencySet>
            <includes>
                <include>de.zefiro.maven.example:wrapper:war:*</include>
            </includes>
            <unpack>true</unpack>
        </dependencySet>
        <dependencySet>
            <includes>
                <include>${group-id}:project_swf:zip:WebContent:${project.version}</include>
            </includes>
            <useProjectAttachments>true</useProjectAttachments>
            <unpack>true</unpack>
            <outputDirectory>sample_project_1</outputDirectory>
        </dependencySet>
[... list the same projects as in the POM file ...]
    </dependencySets>
</assembly>

我有一份来自不同部门的档案,我正在使用它。它包含 HTML 包装器和运行的主 Flex 应用程序(稍后根据配置文件和各个项目的 plugin.xml 元数据从子目录加载所有插件)。这被放置在输出存档根目录中。所有其他项目都是我自己创建的,并放置在单独的子目录中,因此我在这里不使用通配符。由于我想要一个包含合并的所有文件的单个存档,因此我使用 dependencySet 的 unpack 选项。

请注意,在各个 swf 插件项目的程序集描述符中声明的 ID 现在用作 pom 文件的依赖项部分中的分类器以及程序集描述符中 Maven 位置的一部分。包装类型也是如此,我在这里选择了 zip。由于这仅用于中间存档,因此 zip 就可以了,对于最终组装,可以选择不同的格式。

从同一个父级继承,我可以重用我的 Maven 属性,这些属性也可以在程序集描述符中使用。

可以通过复制现有项目并将其添加到以下位置来添加新项目:

  • master_build/pom.xml 作为模块
  • 依赖项部分中的 master_build/assemble/pom.xml
  • master_build/ assembly/final- assembly.xml 作为 dependencySet

最终的工件是一个 war 文件,其中包含:

sample_project_1/SampleProjectModule1
sample_project_1/assets/labels.xlf
sample_project_1/config/config.xml
other_data/configuration.xml
application.swf
index.html

IE。我的所有 swf 项目在各自子目录中的内容与包含静态文件的wrapper.war 的内容合并。

可以从以下位置的存储库中检索它:

de.zefiro.maven.example:full_assembly:war:FinalAssembly:1.0-SNAPSHOT

为了编译每个插件的样式表,我使用相同的基本思想,并将其向下移动到单个项目级别。我将在中描述它其他问题 https://stackoverflow.com/questions/5356589/using-maven-to-build-flex-project-including-stylesheets

未决问题:我无法生成文件的调试版本和发布版本。我可以将项目加倍并将它们打包在一起(就像我对样式表所做的那样),或者我可以运行整个 Maven 反应器(对于父 POM 和主程序集)两次,例如不同的groupId,从而为所有涉及的项目创建两个完全独立的路径。不过,我还没有对此进行进一步调查。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用Maven构建复杂的Flex项目 的相关文章

随机推荐