Статьи

Как упаковать приложения Angular 8 в файлы Regular War

Время от времени необходимо распространять SPA-приложения с использованием файлов war в качестве контейнеров. По моему опыту это необходимо, когда:

  • У вас нет контроля над инфраструктурой развертывания.
  • Вы имеете дело с жесткими стандартами развертывания.
  • ИТ-специалисты не хотят публиковать старый веб-сервер.

В любом случае, как описано в документации Oracle, одним из преимуществ использования военных файлов является возможность включать статические (HTML / JS / CSS) файлы в развертывание. Таким образом, можно с уверенностью предположить, что вы можете распространять любой SPA, используя военный файл в качестве оболочки (с особыми соображениями).

Вам также может понравиться: Angular: все, что вам нужно знать [Учебники] .

Создание POC с Angular 8 и Java War

Чтобы продемонстрировать это, я создам проект, который:

  1. Совместим с тремя большими Java IDE (NetBeans, IntelliJ, Eclipse) и VSCode.
  2. Позволяет использовать IDE в качестве IDE для разработки JavaScript.
  3. Позволяет создать современное приложение SPA (со всеми npm, ng, cli).
  4. Позволяет объединять системы сборки Java (Maven) и JavaScript (Webpack) .
  5. Позволяет распространять минимизированный и готовый к производству проект.

Начальная загрузка простого веб-проекта Java

Чтобы загрузить проект Java, вы можете использовать старый добрый maven-archetype-webapp в качестве основы:

mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-webapp -DarchetypeVersion=1.4

Интерактивная оболочка спросит вас о характеристиках проекта, включая groupId, artifactId (имя проекта) и базовый пакет.

Java Bootstrap

Java Bootstrap

В итоге у вас должна получиться следующая структура:

demo-angular-8$ tree
.
├── pom.xml
└── src
    └── main
        └── webapp
            ├── WEB-INF
            │   └── web.xml
            └── index.jsp

4 directories, 3 files

Теперь вы сможете открыть свой проект в любой IDE. По умолчанию pom.xml  будет включать заблокированные версии для плагинов Maven. Вы можете безопасно избавиться от них, так как мы не будем персонализировать весь жизненный цикл Maven, только пару хуков.

<?xml version="1.0" encoding="UTF-8"?>

<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>

  <groupId>com.nabenik</groupId>
  <artifactId>demo-angular-8</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>demo-angular-8 Maven Webapp</name>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>
</project>

Кроме того, в index.jspэтом нет необходимости, поэтому просто удалите его.

Самозагрузка простого углового проекта JS

В качестве самоуверенного подхода я предлагаю изолировать проект Angular в своем собственном каталоге ( src/main/frontend). В прошлом и с помощью простых фреймворков (AngularJS, Knockout, Ember) можно было загружать весь проект с помощью пары включений в файле index.html.

Тем не менее, в настоящее время большинство современных проектов переднего плана используют какой-то пакет / линтер для включения современных (> = ES6) функций, таких как модули, а в случае Angular для этого используется Webpack под капотом.

В этом руководстве я предполагаю, что вы уже установили все инструменты Angular CLI , поэтому мы можем зайти в нашу структуру исходного кода и запустить проект Angular.

demo-angular-8$ cd src/main/
demo-angular-8/src/main$ ng new frontend

Это загрузит проект Vanilla Angular, и фактически вы можете рассматривать src/main/frontendпапку как отдельный корень (а также вы можете открыть ее непосредственно из VSCode). Окончательная структура будет выглядеть так:

Структура JS

Структура JS

В качестве первого POC я запустил приложение напрямую из CLI, используя IntelliJ IDEA и ng serve --open. Все работало как положено.

Мы здесь

Мы здесь

Вызов Webpack от Maven

Одним из полезных плагинов для этой задачи является frontend-maven-plugin, который позволяет:

  1. Загрузить распространенные менеджеры пакетов JS (npm, cnpm, bower, yarn)
  2. Вызывать системы сборки JS и тесты (grunt, gulp, webpack или npm, карма)

По умолчанию проект Angular поставляется с хуками от npmдо, ngно нам нужно добавить хук в package.json, чтобы создать build ( buildProduction) производственного качества , пожалуйста, дважды проверьте параметр base-href, так как я использую корень по умолчанию из соглашений Java (то же самое) как название проекта)

...
"scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "buildProduction": "ng build --prod --base-href /demo-angular-8/",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  }
...

Чтобы проверить эту сборку, мы могли бы выполнить  npm run buildProduction. В корне webproject ( src/main/frontend) вывод должен быть таким:

NPM Hook

NPM Hook

Наконец, необходимо вызвать или новую цель с Maven. Наша конфигурация должна:

  1. Установите NodeJS (и NPM).
  2. Установите JS-зависимости.
  3. Вызвать наш новый крюк.
  4. Скопируйте результат в нашу последнюю распространяемую войну.

Для этого должно быть достаточно следующей конфигурации:

<build>
<finalName>demo-angular-8</finalName>
    <plugins>
    <plugin>
            <groupId>com.github.eirslett</groupId>
            <artifactId>frontend-maven-plugin</artifactId>
            <version>1.6</version>

            <configuration>
                <workingDirectory>src/main/frontend</workingDirectory>
            </configuration>

            <executions>

                <execution>
                    <id>install-node-and-npm</id>
                    <goals>
                        <goal>install-node-and-npm</goal>
                    </goals>
                    <configuration>
                        <nodeVersion>v10.16.1</nodeVersion>
                    </configuration>
                </execution>

                <execution>
                    <id>npm install</id>
                    <goals>
                        <goal>npm</goal>
                    </goals>
                    <configuration>
                        <arguments>install</arguments>
                    </configuration>
                </execution>
                <execution>
                    <id>npm build</id>
                    <goals>
                        <goal>npm</goal>
                    </goals>
                    <configuration>
                        <arguments>run buildProduction</arguments>
                    </configuration>
                    <phase>generate-resources</phase>
                </execution>
            </executions>
    </plugin>
    <plugin>
        <artifactId>maven-war-plugin</artifactId>
        <version>3.2.2</version>
        <configuration>
            <failOnMissingWebXml>false</failOnMissingWebXml>

            <!-- Add frontend folder to war package -->
            <webResources>
                <resource>
                    <directory>src/main/frontend/dist/frontend</directory>
                </resource>
            </webResources>

        </configuration>
    </plugin>
    </plugins>
</build>

Вот и все!. После выполнения mvn clean packageвы получите переносимый файл war, который будет работать во время выполнения любого контейнера сервлета. Например, я протестировал его с Payara Full 5, и он работал как положено.

Конечный результат!

Конечный результат!

Дальнейшее чтение