Simplified delivery of react.js from apache karaf

This article is about a new servlet base class I have created to simplify serving up javascript frontends from the OSGi web whiteboard.

This article won’t go into the structure of the files that must be served. See Deliver react.js from apache karaf and A Java programmers guide to delivering webapp frontends to get an overview of files.

The short story is that the servlet needs to deliver two files:

  1. An index.html containing the initial DOM tree of the web application (if loaded in a web browser that will be all that’s shown), e.g. like this
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>Frontend Karaf Test</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"></meta>
    </head>
    <body>
    <div id="root"></div>
    <script src="bundle.js" type="application/javascript"></script>
    <noscript>This webpage requires javascript in the browser!</noscript>
    </body>
    </html>
    view raw index.html hosted with ❤ by GitHub
  2. A bundle.js file containing the javascript of the application as well as all dependencies, all packed together to be as compact as possible

The index.html file and the bundle.js files are added as classpath resources in the OSGi bundle containing the servlet.

The index.html file is added by putting it into src/main/resources of the maven project for the OSGi bundle.

The bundle.js file is added to the classpath by letting the frontend-maven-plugin drop the created bundle.js into target/classes/

<project>
<build>
<plugins>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.6</version>
<configuration>
<nodeVersion>v10.4.0</nodeVersion>
<workingDirectory>src/main/frontend</workingDirectory>
<installDirectory>target</installDirectory>
</configuration>
<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
</execution>
<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
</execution>
<execution>
<id>webpack build</id>
<goals>
<goal>webpack</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
view raw pom.xml hosted with ❤ by GitHub

Everything covered so far is identical to what’s described in the first blog post.

The difference is how much simpler creating the servlet component is.

A web whiteboard DS component for serving a frontend without any routing could look like this:

@Component(service={Servlet.class}, property={"alias=/frontend-karaf-demo"})
public class ReactServlet extends FrontendServlet {
@Reference
public void setLogservice(LogService logservice) {
super.setLogService(logservice);
}
}

The LogService service injection is passed to the FrontendServlet base class, where it is used to report problems when serving files.

If the web application has a router that can be used to edit the local part, like e.g. so

<Provider store={store}>
<Router>
<div className="App">
<Switch>
<Route exact path="/frontend-karaf-demo/" component={Home} />
<Route path="/frontend-karaf-demo/counter" component={Counter} />
<Route path="/frontend-karaf-demo/about" component={About} />
</Switch>
</div>
</Router>
</Provider>
view raw routes.jsx hosted with ❤ by GitHub

then the servlet needs to have matching routes (that’s the setRoutes() call in the constructor):
@Component(service={Servlet.class}, property={"alias=/frontend-karaf-demo"})
public class ReactServlet extends FrontendServlet {
public ReactServlet() {
super();
setRoutes("/", "/counter", "/about");
}
...
}

The paths are used when reloading a subpage, e.g. by pressing F5 in the web browser. All paths will return the index.html file which in turn will load the bundle.js which will navigate to the correct sub-page based on the path.

Note that the react paths have the application web context, while the paths on the java side are without the application web part:

React routes Java routes
/frontend-karaf-demo/ /
/frontend-karaf-demo/counter /counter
/frontend-karaf-demo/about /about

4 thoughts on “Simplified delivery of react.js from apache karaf”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.