Skip to content

Instantly share code, notes, and snippets.

@bseib
Last active November 24, 2023 17:08
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bseib/a3509267931b3f0a80c77323e9fd6956 to your computer and use it in GitHub Desktop.
Save bseib/a3509267931b3f0a80c77323e9fd6956 to your computer and use it in GitHub Desktop.
Webpack + JSP

Webpack + JSP

These snippets were created after reading the following article on how to use webpack to build code bundles for individual JSP pages, and specifically how to get those JSP pages to refer to the correct filename + hash.

https://medium.com/@jsilvax/introducing-webpack-into-an-existing-java-based-web-app-ff53f14d37ec

There was no actual code, but the description of the approach was enough to put something together. jsilvax just posted some code here: https://medium.com/p/510d859b9f36/responses/show

When you write a TLD lib that has functions, those function calls are static, meaning there's no way that class is going to know your Serlvet context. So, you just have to pass that in as an argument so that the function can open the manifest file.

<%@ page pageEncoding="UTF-8" %>
<%@ taglib prefix="webpack" uri="/WEB-INF/tlds/webpack.tld" %>
<c:set var="servletContext" value="${pageContext.servletContext}" />
<head>
<script src="${webpack:getManifestResource(servletContext, 'page-one.js')}"></script>
</head>
<%-- etc --%>
const path = require('path');
const WebpackAssetsManifest = require('webpack-assets-manifest');
module.exports = {
entry: {
pricing2: './src-web/path/to/page-one.js',
},
output: {
filename: '[name]-[chunkhash].js',
path: __dirname + '/war/bundle',
},
module: {},
plugins: [
new WebpackAssetsManifest({
writeToDisk: true,
}),
],
}
// Running `webpack --config webpack.config.js` will put `page-one-xxxxxxxxx.js` and
// the `manifest.json` into the `/war/bundle` directory.
<!-- located at war/WEB-INF/tlds/webpack.tld -->
<taglib version="2.0" xmlns="http://java.sun.com/xml/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd">
<tlib-version>2.0</tlib-version>
<jsp-version>2.0</jsp-version>
<short-name>webpack</short-name>
<description>
functions to deal with webpack files
</description>
<function>
<name>getManifestResource</name>
<function-class>your.namespace.tag.WebpackTagLib</function-class>
<function-signature>java.lang.String getManifestResource(javax.servlet.ServletContext, java.lang.String)</function-signature>
</function>
</taglib>
package your.namespace.tag;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.ServletContext;
import org.json.JSONException;
import org.json.JSONObject;
public class WebpackTagLib {
static public String getManifestResource(ServletContext ctx, String filename) {
try {
InputStream inputStream = ctx.getResourceAsStream("/bundle/manifest.json");
ByteArrayOutputStream result = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) != -1) {
result.write(buffer, 0, length);
}
JSONObject json = new JSONObject(result.toString("UTF-8"));
String fullFilename = json.getString(filename);
if ( null == fullFilename ) {
return "/no/manifest/entry/for/" + filename;
}
return "/bundle/" + fullFilename;
}
catch ( JSONException | IOException e ) {
return "/no/manifest/entry/for/" + filename;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment