From ceef05bddbef05cc3105ab348209742a80dc708f Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Fri, 2 Feb 2024 14:04:24 -0600 Subject: [PATCH 1/2] CLDR-17270 st: don't use late cache busting for bundle.js - instead, let webpack create a bundle name based on the content's hash, which will truly change when and only when the content changes. - webpack hook to write the file - read a manifest.json on the server side to serve that --- tools/cldr-apps/js/webpack.config.js | 32 ++++++++++++++++--- .../java/org/unicode/cldr/web/SurveyTool.java | 32 ++++++++++++++++--- 2 files changed, 54 insertions(+), 10 deletions(-) diff --git a/tools/cldr-apps/js/webpack.config.js b/tools/cldr-apps/js/webpack.config.js index 7906a5892a7..4965e5d295e 100644 --- a/tools/cldr-apps/js/webpack.config.js +++ b/tools/cldr-apps/js/webpack.config.js @@ -1,6 +1,26 @@ const path = require("path"); +const fs = require('fs'); const { VueLoaderPlugin } = require("vue-loader"); -const { DefinePlugin } = require("webpack"); +const { DefinePlugin, Compiler } = require("webpack"); + +class SurveyToolPlugin { + constructor() { + + } + /** + * + * @param {Compiler} compiler + */ + apply(compiler) { + compiler.hooks.afterEmit.tap('SurveyToolPlugin', (compilation) => { + const { assets } = compilation; + const jsfiles = Object.keys(assets).filter(s => /\.js$/.test(s)); + const manifestFile = path.resolve(compiler.outputPath, 'manifest.json'); + fs.writeFileSync(manifestFile, JSON.stringify({ jsfiles }), 'utf-8'); + console.log('# SurveyToolPlugin Wrote: ', manifestFile); + }); + } +}; module.exports = (env, argv) => { const {mode} = argv; @@ -12,7 +32,7 @@ module.exports = (env, argv) => { cacheDirectory: path.resolve(__dirname, '../target/webpack_cache'), }, output: { - filename: "bundle.js", + filename: "[name].[contenthash].js", path: path.resolve(__dirname, "..", "src", "main", "webapp", "dist"), library: "cldrBundle", libraryTarget: "var", @@ -43,7 +63,9 @@ module.exports = (env, argv) => { // esm bundler flags, // see __VUE_PROD_DEVTOOLS__: JSON.stringify(DEV), // TODO: support dev mode - __VUE_OPTIONS_API__: JSON.stringify(true), - })], - }; + __VUE_OPTIONS_API__: JSON.stringify(true), + }), + new SurveyToolPlugin(), + ] + }; }; diff --git a/tools/cldr-apps/src/main/java/org/unicode/cldr/web/SurveyTool.java b/tools/cldr-apps/src/main/java/org/unicode/cldr/web/SurveyTool.java index e520ffd7c33..2bd1348c6d0 100644 --- a/tools/cldr-apps/src/main/java/org/unicode/cldr/web/SurveyTool.java +++ b/tools/cldr-apps/src/main/java/org/unicode/cldr/web/SurveyTool.java @@ -1,8 +1,13 @@ package org.unicode.cldr.web; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.io.PrintWriter; +import java.io.Reader; import java.io.Writer; +import java.nio.charset.StandardCharsets; +import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.ServletConfig; @@ -14,6 +19,9 @@ import org.unicode.cldr.util.CLDRURLS; import org.unicode.cldr.util.CldrUtility; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + public class SurveyTool extends HttpServlet { static final Logger logger = SurveyLog.forClass(SurveyTool.class); @@ -242,6 +250,12 @@ public static void includeMonitoring(Writer out) throws IOException { } } + static private final Gson gson = new GsonBuilder().setPrettyPrinting().create(); + + private final class STManifest { + public String jsfiles[]; + } + /** * Write the script tags for Survey Tool JavaScript files * @@ -253,15 +267,23 @@ public static void includeMonitoring(Writer out) throws IOException { public static void includeJavaScript(HttpServletRequest request, Writer out) throws IOException, JSONException { includeMonitoring(out); - // Load the big bundle - out.write( - "\n"); + + // use WebPack-built manifest.json to include all chunks. + // ideally this would all come from a static .html file built by WebPack. + // TODO https://unicode-org.atlassian.net/browse/CLDR-17353 + try (final InputStream is = request.getServletContext().getResourceAsStream("dist/manifest.json"); + final Reader r = new InputStreamReader(is, StandardCharsets.UTF_8);) { + for(final String f : gson.fromJson(r, STManifest.class).jsfiles) { + out.write("\n"); + } + } + includeJqueryJavaScript(request, out); includeCldrJavaScript(request, out); } + + private static void includeJqueryJavaScript(HttpServletRequest request, Writer out) throws IOException { // Per https://en.wikipedia.org/wiki/JQuery#Release_history -- From 261ff29004dd0eb93b371d97f2c68b9af799fb4c Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Fri, 2 Feb 2024 14:10:46 -0600 Subject: [PATCH 2/2] CLDR-17270 st: don't use late cache busting for bundle.js - spotless --- .../java/org/unicode/cldr/web/SurveyTool.java | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/tools/cldr-apps/src/main/java/org/unicode/cldr/web/SurveyTool.java b/tools/cldr-apps/src/main/java/org/unicode/cldr/web/SurveyTool.java index 2bd1348c6d0..ffe052fa03d 100644 --- a/tools/cldr-apps/src/main/java/org/unicode/cldr/web/SurveyTool.java +++ b/tools/cldr-apps/src/main/java/org/unicode/cldr/web/SurveyTool.java @@ -1,5 +1,7 @@ package org.unicode.cldr.web; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -7,7 +9,6 @@ import java.io.Reader; import java.io.Writer; import java.nio.charset.StandardCharsets; -import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.ServletConfig; @@ -19,9 +20,6 @@ import org.unicode.cldr.util.CLDRURLS; import org.unicode.cldr.util.CldrUtility; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; - public class SurveyTool extends HttpServlet { static final Logger logger = SurveyLog.forClass(SurveyTool.class); @@ -250,7 +248,7 @@ public static void includeMonitoring(Writer out) throws IOException { } } - static private final Gson gson = new GsonBuilder().setPrettyPrinting().create(); + private static final Gson gson = new GsonBuilder().setPrettyPrinting().create(); private final class STManifest { public String jsfiles[]; @@ -271,19 +269,23 @@ public static void includeJavaScript(HttpServletRequest request, Writer out) // use WebPack-built manifest.json to include all chunks. // ideally this would all come from a static .html file built by WebPack. // TODO https://unicode-org.atlassian.net/browse/CLDR-17353 - try (final InputStream is = request.getServletContext().getResourceAsStream("dist/manifest.json"); - final Reader r = new InputStreamReader(is, StandardCharsets.UTF_8);) { - for(final String f : gson.fromJson(r, STManifest.class).jsfiles) { - out.write("\n"); - } + try (final InputStream is = + request.getServletContext().getResourceAsStream("dist/manifest.json"); + final Reader r = new InputStreamReader(is, StandardCharsets.UTF_8); ) { + for (final String f : gson.fromJson(r, STManifest.class).jsfiles) { + out.write( + "\n"); + } } includeJqueryJavaScript(request, out); includeCldrJavaScript(request, out); } - - private static void includeJqueryJavaScript(HttpServletRequest request, Writer out) throws IOException { // Per https://en.wikipedia.org/wiki/JQuery#Release_history --