From 2df5d067fb7f253c25d362fece60a006383a34ea Mon Sep 17 00:00:00 2001
From: Steffen Vogel <post@steffenvogel.de>
Date: Mon, 13 Jun 2022 00:36:28 +0200
Subject: [PATCH] use MiniCssExtractPlugin to load extract CSS styles from JS

---
 frontend/package-lock.json | 123 +++++++++++++++++++++++++++++++++++++
 frontend/package.json      |   1 +
 frontend/webpack.common.js |  13 ++--
 frontend/webpack.prod.js   |   1 +
 4 files changed, 133 insertions(+), 5 deletions(-)

diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 77b28e4..4707de3 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -25,6 +25,7 @@
                 "copy-webpack-plugin": "^11.0.0",
                 "css-loader": "^6.7.1",
                 "html-webpack-plugin": "^5.5.0",
+                "mini-css-extract-plugin": "^2.6.0",
                 "postcss": "^8.4.14",
                 "postcss-loader": "^7.0.0",
                 "sass": "^1.52.3",
@@ -4583,6 +4584,78 @@
                 "node": ">=6"
             }
         },
+        "node_modules/mini-css-extract-plugin": {
+            "version": "2.6.0",
+            "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.0.tgz",
+            "integrity": "sha512-ndG8nxCEnAemsg4FSgS+yNyHKgkTB4nPKqCOgh65j3/30qqC5RaSQQXMm++Y6sb6E1zRSxPkztj9fqxhS1Eo6w==",
+            "dev": true,
+            "dependencies": {
+                "schema-utils": "^4.0.0"
+            },
+            "engines": {
+                "node": ">= 12.13.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/webpack"
+            },
+            "peerDependencies": {
+                "webpack": "^5.0.0"
+            }
+        },
+        "node_modules/mini-css-extract-plugin/node_modules/ajv": {
+            "version": "8.11.0",
+            "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz",
+            "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==",
+            "dev": true,
+            "dependencies": {
+                "fast-deep-equal": "^3.1.1",
+                "json-schema-traverse": "^1.0.0",
+                "require-from-string": "^2.0.2",
+                "uri-js": "^4.2.2"
+            },
+            "funding": {
+                "type": "github",
+                "url": "https://github.com/sponsors/epoberezkin"
+            }
+        },
+        "node_modules/mini-css-extract-plugin/node_modules/ajv-keywords": {
+            "version": "5.1.0",
+            "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+            "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+            "dev": true,
+            "dependencies": {
+                "fast-deep-equal": "^3.1.3"
+            },
+            "peerDependencies": {
+                "ajv": "^8.8.2"
+            }
+        },
+        "node_modules/mini-css-extract-plugin/node_modules/json-schema-traverse": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+            "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+            "dev": true
+        },
+        "node_modules/mini-css-extract-plugin/node_modules/schema-utils": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz",
+            "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==",
+            "dev": true,
+            "dependencies": {
+                "@types/json-schema": "^7.0.9",
+                "ajv": "^8.8.0",
+                "ajv-formats": "^2.1.1",
+                "ajv-keywords": "^5.0.0"
+            },
+            "engines": {
+                "node": ">= 12.13.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/webpack"
+            }
+        },
         "node_modules/minimalistic-assert": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
@@ -10196,6 +10269,56 @@
             "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
             "dev": true
         },
+        "mini-css-extract-plugin": {
+            "version": "2.6.0",
+            "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.0.tgz",
+            "integrity": "sha512-ndG8nxCEnAemsg4FSgS+yNyHKgkTB4nPKqCOgh65j3/30qqC5RaSQQXMm++Y6sb6E1zRSxPkztj9fqxhS1Eo6w==",
+            "dev": true,
+            "requires": {
+                "schema-utils": "^4.0.0"
+            },
+            "dependencies": {
+                "ajv": {
+                    "version": "8.11.0",
+                    "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz",
+                    "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==",
+                    "dev": true,
+                    "requires": {
+                        "fast-deep-equal": "^3.1.1",
+                        "json-schema-traverse": "^1.0.0",
+                        "require-from-string": "^2.0.2",
+                        "uri-js": "^4.2.2"
+                    }
+                },
+                "ajv-keywords": {
+                    "version": "5.1.0",
+                    "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+                    "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+                    "dev": true,
+                    "requires": {
+                        "fast-deep-equal": "^3.1.3"
+                    }
+                },
+                "json-schema-traverse": {
+                    "version": "1.0.0",
+                    "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+                    "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+                    "dev": true
+                },
+                "schema-utils": {
+                    "version": "4.0.0",
+                    "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz",
+                    "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==",
+                    "dev": true,
+                    "requires": {
+                        "@types/json-schema": "^7.0.9",
+                        "ajv": "^8.8.0",
+                        "ajv-formats": "^2.1.1",
+                        "ajv-keywords": "^5.0.0"
+                    }
+                }
+            }
+        },
         "minimalistic-assert": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index 91a31b4..f746b13 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -21,6 +21,7 @@
         "copy-webpack-plugin": "^11.0.0",
         "css-loader": "^6.7.1",
         "html-webpack-plugin": "^5.5.0",
+        "mini-css-extract-plugin": "^2.6.0",
         "postcss": "^8.4.14",
         "postcss-loader": "^7.0.0",
         "sass": "^1.52.3",
diff --git a/frontend/webpack.common.js b/frontend/webpack.common.js
index e87eab3..062f210 100644
--- a/frontend/webpack.common.js
+++ b/frontend/webpack.common.js
@@ -1,6 +1,7 @@
 const path = require("path");
 const HtmlWebpackPlugin = require("html-webpack-plugin");
 const CopyPlugin = require("copy-webpack-plugin");
+const MiniCssExtractPlugin = require("mini-css-extract-plugin");
 
 module.exports = {
     entry: "./src/index.ts",
@@ -17,7 +18,8 @@ module.exports = {
             patterns: [
               { from: "img/*", to: "" }
             ],
-          }),
+        }),
+        new MiniCssExtractPlugin()
     ],    
     resolve: {
         modules: ["node_modules"],
@@ -32,11 +34,12 @@ module.exports = {
             },
             {
                 test: /\.(scss)$/,
-                use: [{
-                        loader: "style-loader", // inject CSS to page
-                    }, {
+                use: [
+                    MiniCssExtractPlugin.loader,
+                    {
                         loader: "css-loader", // translates CSS into CommonJS modules
-                    }, {
+                    },
+                    {
                         loader: "postcss-loader", // Run post css actions
                         options: {
                             postcssOptions: {
diff --git a/frontend/webpack.prod.js b/frontend/webpack.prod.js
index 95b8303..f451de9 100644
--- a/frontend/webpack.prod.js
+++ b/frontend/webpack.prod.js
@@ -3,4 +3,5 @@ const common = require("./webpack.common.js");
 
 module.exports = merge(common, {
     mode: "production",
+    devtool: "source-map",
 });