Building Angular WebBundle for Apache Karaf
Apache Karaf is a complete applications container, supporting several programming models: OSGi, DS, Blueprint, Spring, …
It’s also a complete web application container like Apache Tomcat, but providing some unique feature. If Apache Karaf supports WAR, it also supports Web Bundle. A Web Bundle is basically a bundle with a specific header.
For web application frontend, Angular is popular framework (used in combination with Bootstrap). It’s possible to write Angular directly by hand, but, most of the time, web developers prefer to use IDE like WebStorm.
In any case, Angular CLI (https://github.com/angular/angular-cli) is a “classic” tool to test and build your Angular application.
Project with Angular CLI
Angular CLI allows you to quickly start your Angular project.
You can bootstrap using the following command:
$ ng new test-frontend
Then, Angular CLI (ng
) creates all required resources:
create test-frontend/README.md (1028 bytes) create test-frontend/.angular-cli.json (1248 bytes) create test-frontend/.editorconfig (245 bytes) create test-frontend/.gitignore (544 bytes) create test-frontend/src/assets/.gitkeep (0 bytes) create test-frontend/src/environments/environment.prod.ts (51 bytes) create test-frontend/src/environments/environment.ts (387 bytes) create test-frontend/src/favicon.ico (5430 bytes) create test-frontend/src/index.html (299 bytes) create test-frontend/src/main.ts (370 bytes) create test-frontend/src/polyfills.ts (3114 bytes) create test-frontend/src/styles.css (80 bytes) create test-frontend/src/test.ts (642 bytes) create test-frontend/src/tsconfig.app.json (211 bytes) create test-frontend/src/tsconfig.spec.json (283 bytes) create test-frontend/src/typings.d.ts (104 bytes) create test-frontend/e2e/app.e2e-spec.ts (295 bytes) create test-frontend/e2e/app.po.ts (208 bytes) create test-frontend/e2e/tsconfig.e2e.json (235 bytes) create test-frontend/karma.conf.js (923 bytes) create test-frontend/package.json (1298 bytes) create test-frontend/protractor.conf.js (722 bytes) create test-frontend/tsconfig.json (363 bytes) create test-frontend/tslint.json (3012 bytes) create test-frontend/src/app/app.module.ts (316 bytes) create test-frontend/src/app/app.component.css (0 bytes) create test-frontend/src/app/app.component.html (1141 bytes) create test-frontend/src/app/app.component.spec.ts (986 bytes) create test-frontend/src/app/app.component.ts (207 bytes)> uws@9.14.0 install /home/jbonofre/Workspace/test-frontend/node_modules/uws> node-gyp rebuild > build_log.txt 2>&1 || exit 0> node-sass@4.7.2 install /home/jbonofre/Workspace/test-frontend/node_modules/node-sass> node scripts/install.jsCached binary found at /home/jbonofre/.npm/node-sass/4.7.2/linux-x64-59_binding.node> uglifyjs-webpack-plugin@0.4.6 postinstall /home/jbonofre/Workspace/test-frontend/node_modules/webpack/node_modules/uglifyjs-webpack-plugin> node lib/post_install.js> node-sass@4.7.2 postinstall /home/jbonofre/Workspace/test-frontend/node_modules/node-sass> node scripts/build.jsBinary found at /home/jbonofre/Workspace/test-frontend/node_modules/node-sass/vendor/linux-x64-59/binding.nodeTesting binaryBinary is fineadded 1272 packages in 65.41sProject 'test-frontend' successfully created.
You can test your project using:
$ ng serve** NG Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ **Date: 2018-03-02T10:01:07.769Z Hash: a130567e5011eb653504Time: 8240mschunk {inline} inline.bundle.js (inline) 3.85 kB [entry] [rendered]chunk {main} main.bundle.js (main) 17.9 kB [initial] [rendered]chunk {polyfills} polyfills.bundle.js (polyfills) 549 kB [initial] [rendered]chunk {styles} styles.bundle.js (styles) 41.5 kB [initial] [rendered]chunk {vendor} vendor.bundle.js (vendor) 7.42 MB [initial] [rendered]webpack: Compiled successfully.
You can access your web application directly in your browser and all change is taken on the fly.
If you want to generate “static” web application (converting your Angular project as a set of html and js files), you can use:
$ ng buildDate: 2018-03-02T10:03:36.703Z Hash: 9de4cb2f98111fe59f9eTime: 9459mschunk {inline} inline.bundle.js, inline.bundle.js.map (inline) 3.89 kB [entry] [rendered]chunk {main} main.bundle.js, main.bundle.js.map (main) 7.39 kB [initial] [rendered]chunk {polyfills} polyfills.bundle.js, polyfills.bundle.js.map (polyfills) 202 kB [initial] [rendered]chunk {styles} styles.bundle.js, styles.bundle.js.map (styles) 14.5 kB [initial] [rendered]chunk {vendor} vendor.bundle.js, vendor.bundle.js.map (vendor) 2.44 MB [initial] [rendered]
ng build
generates all static content in a dist
folder. You will find here a index.html
file with all other resources (js
files, …).
Building Angular application ready to be deployed in Apache Karaf
Now, we want to “automatize” this build using Apache Maven. The purpose is to:
- perform
ng build
to create the resources in thedist
folder - package this resource as a Web Bundle
Our Maven pom.xml
will contain basically three plugin executions:
maven-antrun-plugin
to perform theng build
maven-bundle-plugin
to package as a WebBundlemaven-clean-plugin
to clean all created folder
Here’s the pom.xml
doing so:
<?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>net.nanthrax</groupId> <artifactId>test-frontend</artifactId> <version>1.0-SNAPSHOT</version> <packaging>bundle</packaging> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.8</version> <executions> <execution> <id>ng-build</id> <phase>generate-resources</phase> <goals> <goal>run</goal> </goals> <configuration> <target> <mkdir dir="target"/> <echo message="Generating frontend resource"/> <exec executable="ng"> <arg value="build"/> </exec> </target> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <version>3.3.0</version> <inherited>true</inherited> <extensions>true</extensions> <configuration> <instructions> <Web-ContextPath>/angular-test</Web-ContextPath> <Private-Package>*</Private-Package> <Include-Resource>dist</Include-Resource> </instructions> </configuration> </plugin> </plugins> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-clean-plugin</artifactId> <configuration> <directory>dist</directory> <directory>target</directory> </configuration> </plugin> </plugins> </pluginManagement> </build></project>
The most important parts are:
- Web-ContextPath is the context path of our web application.
- Include-Resource uses the resources content generated by
ng build
.
We can now build our bundle, simply using:
$ mvn clean install
Deployment in Apache Karaf
Now, the deployment is pretty simple in Apache Karaf.
On a running Karaf instance, you just have to install the war
feature:
karaf@root()> feature:install war
Now, we directly install our WebBundle:
karaf@root()> bundle:install -s mvn:net.nanthrax/test-frontend/1.0-SNAPSHOTBundle ID: 87
We can see the web application available:
karaf@root()> web:listID │ State │ Web-State │ Level │ Web-ContextPath │ Name───┼─────────────┼─────────────┼───────┼─────────────────┼───────────────────────────────87 │ Active │ Deployed │ 80 │ /angular-test │ test-frontend (1.0.0.SNAPSHOT)
And we can access the application directly using a browser on the Karaf HTTP service (listening on 8181 by default): http://localhost:8181/angular-test
Conclusion
Thanks to the Maven build, we can now setup continuous integration (using Jenkins for instance).
A good improvement could be to wrap this Angular web application in a Karaf feature, automatically installing the war
feature and our webbundle.
Comments
Post a Comment