From 943ce35738d1110a2e968901c8dc0dc142cb24a4 Mon Sep 17 00:00:00 2001
From: Joel Chen <xchen@walmartlabs.com>
Date: Fri, 5 Mar 2021 19:32:52 -0800
Subject: [PATCH] update to webpack-dev-middleware 4

---
 packages/xarc-app-dev/package.json            |  2 +-
 .../src/lib/dev-admin/middleware.ts           | 47 +++++++++++--------
 packages/xarc-webpack/src/partials/subapp2.ts |  4 +-
 ...n-webpck5.ts => subapp-plugin-webpack5.ts} | 14 +++++-
 4 files changed, 43 insertions(+), 24 deletions(-)
 rename packages/xarc-webpack/src/plugins/{subapp-plugin-webpck5.ts => subapp-plugin-webpack5.ts} (96%)

diff --git a/packages/xarc-app-dev/package.json b/packages/xarc-app-dev/package.json
index 420417a14..5ce528b64 100644
--- a/packages/xarc-app-dev/package.json
+++ b/packages/xarc-app-dev/package.json
@@ -91,7 +91,7 @@
     "sudo-prompt": "^8.2.5",
     "tslib": "^2.1.0",
     "visual-logger": "^1.1.3",
-    "webpack-dev-middleware": "^3.7.2",
+    "webpack-dev-middleware": "^4.1.0",
     "webpack-hot-middleware": "^2.25.0",
     "winston": "^2.4.4",
     "xaa": "^1.7.0",
diff --git a/packages/xarc-app-dev/src/lib/dev-admin/middleware.ts b/packages/xarc-app-dev/src/lib/dev-admin/middleware.ts
index 2820d9fae..34ae5638f 100644
--- a/packages/xarc-app-dev/src/lib/dev-admin/middleware.ts
+++ b/packages/xarc-app-dev/src/lib/dev-admin/middleware.ts
@@ -8,6 +8,7 @@ import hotHelpers from "webpack-hot-middleware/helpers";
 import Url from "url";
 import { devProxy } from "../../config/dev-proxy";
 import { formUrl } from "../utils";
+import getFilenameFromUrl from "webpack-dev-middleware/dist/utils/getFilenameFromUrl";
 
 const { getWebpackStartConfig } = require("@xarc/webpack/lib/util/custom-check"); // eslint-disable-line
 
@@ -161,36 +162,35 @@ export class Middleware {
         },
         // port: archetype.webpack.devPort,
         // host: archetype.webpack.devHostname,
-        quiet: false,
-        lazy: false,
-        watchOptions: {
-          aggregateTimeout: 2000,
-          poll: false
-        },
+        // quiet: false,
+        // lazy: false,
+        // watchOptions: {
+        //   aggregateTimeout: 2000,
+        //   poll: false
+        // },
         stats: {
           colors: true
         },
         publicPath: "/js",
-        serverSideRender: false,
-        clientLogLevel: "info"
+        serverSideRender: false
+        // clientLogLevel: "info"
       },
       options.common,
       options.dev
     );
 
-    let defaultReporter; // eslint-disable-line
-    webpackDevOptions.reporter = (a, b) => defaultReporter(a, b);
-
     this.devMiddleware = webpackDevMiddleware(compiler, webpackDevOptions);
     this.hotMiddleware = webpackHotMiddleware(compiler, webpackHotOptions);
     this.publicPath = webpackDevOptions.publicPath || "/";
     this.listAssetPath = urlJoin(this.publicPath, "/");
 
-    this.memFsCwd = this.devMiddleware.fileSystem.existsSync(process.cwd()) ? process.cwd() : "/";
+    const outputFileSystem: any = this.devMiddleware.context.outputFileSystem;
+
+    this.memFsCwd = outputFileSystem.existsSync(process.cwd()) ? process.cwd() : "/";
     this.cwdMemIndex = serveIndex(this.memFsCwd, {
       icons: true,
       hidden: true,
-      fs: this.devMiddleware.fileSystem,
+      fs: outputFileSystem,
       path: Path.posix
     });
 
@@ -211,7 +211,7 @@ export class Middleware {
 
     this.returnReporter = undefined;
 
-    defaultReporter = (_middlewareOptions, reporterOptions) => {
+    const defaultReporter = (_middlewareOptions, reporterOptions) => {
       if (!reporterOptions.state) {
         process.send({
           name: "webpack-report",
@@ -277,6 +277,13 @@ export class Middleware {
         refreshModules
       });
     };
+
+    compiler.hooks.done.tap("webpack-dev-middleware", stats => {
+      defaultReporter({}, { state: true, stats });
+    });
+    compiler.hooks.invalid.tap("webpack-dev-middleware", () => {
+      defaultReporter({}, { state: false });
+    });
   }
 
   process(req, res, cycle) {
@@ -363,14 +370,16 @@ ${jumpToError}</body></html>
       // do nothing and continue to webpack dev middleware
       return Promise.resolve(this.canContinue);
     } else if (req.url === this.publicPath || req.url === this.listAssetPath) {
-      const outputPath = this.devMiddleware.getFilenameFromUrl(this.publicPath);
-      const filesystem = this.devMiddleware.fileSystem;
+      const outputPath = Path.dirname(
+        getFilenameFromUrl(this.devMiddleware.context, this.publicPath)
+      );
+      const outputFileSystem = this.devMiddleware.context.outputFileSystem;
 
       const listDirectoryHtml = (baseUrl, basePath) => {
         return (
-          filesystem.readdirSync(basePath).reduce((a, item) => {
+          outputFileSystem.readdirSync(basePath).reduce((a, item) => {
             const p = `${basePath}/${item}`;
-            if (filesystem.statSync(p).isFile()) {
+            if (outputFileSystem.statSync(p).isFile()) {
               return `${a}<li><a href="${baseUrl}${item}">${item}</a></li>\n`;
             } else {
               return `${a}<li>${item}<br>` + listDirectoryHtml(`${baseUrl}${item}/`, p) + "</li>\n";
@@ -390,7 +399,7 @@ ${listDirectoryHtml(this.listAssetPath, outputPath)}
       const isMemFs = true;
       return serveStatic(
         this.cwdContextBaseUrl,
-        this.devMiddleware.fileSystem,
+        this.devMiddleware.context.outputFileSystem,
         this.cwdMemIndex,
         this.memFsCwd,
         isMemFs
diff --git a/packages/xarc-webpack/src/partials/subapp2.ts b/packages/xarc-webpack/src/partials/subapp2.ts
index d820e4c47..41bc3b767 100644
--- a/packages/xarc-webpack/src/partials/subapp2.ts
+++ b/packages/xarc-webpack/src/partials/subapp2.ts
@@ -2,7 +2,7 @@
  * SubApp version 2 support
  */
 
-import { SubAppWebpackPlugin } from "../plugins/subapp-plugin";
+import { SubAppWebpackPlugin } from "../plugins/subapp-plugin-webpack5";
 
 module.exports = function(opts) {
   return {
@@ -14,7 +14,7 @@ module.exports = function(opts) {
     plugins: [
       new SubAppWebpackPlugin({
         // let plugin figure out webpack version
-        // webpackVersion: 4,
+        webpackVersion: 5,
         assetsFile: "../subapps.json"
       })
     ]
diff --git a/packages/xarc-webpack/src/plugins/subapp-plugin-webpck5.ts b/packages/xarc-webpack/src/plugins/subapp-plugin-webpack5.ts
similarity index 96%
rename from packages/xarc-webpack/src/plugins/subapp-plugin-webpck5.ts
rename to packages/xarc-webpack/src/plugins/subapp-plugin-webpack5.ts
index 83a9a7aae..b46f965d6 100644
--- a/packages/xarc-webpack/src/plugins/subapp-plugin-webpck5.ts
+++ b/packages/xarc-webpack/src/plugins/subapp-plugin-webpack5.ts
@@ -258,10 +258,20 @@ export class SubAppWebpackPlugin {
     return undefined;
   }
 
+  /**
+   * Webpack 5 Reference:
+   * - lib/HotModuleReplacementPlugin.js
+   *
+   * @param compiler
+   */
   _applyHmrInject(compiler) {
     compiler.hooks.compilation.tap(pluginName, (compilation, { normalModuleFactory }) => {
-      const hotUpdateChunkTemplate = compilation.hotUpdateChunkTemplate;
-      if (!hotUpdateChunkTemplate) return;
+      // This applies the HMR injection only to the targeted compiler
+      // It should not affect child compilations
+      if (compilation.compiler !== compiler) return;
+
+      // const hotUpdateChunkTemplate = compilation.hotUpdateChunkTemplate;
+      // if (!hotUpdateChunkTemplate) return;
 
       compilation.dependencyFactories.set(SubAppHotAcceptDependency, normalModuleFactory);