From 1102ab2613630fdab7d8fd5b169097b5957b0046 Mon Sep 17 00:00:00 2001 From: ReznoRMichael Date: Mon, 25 Jan 2021 14:34:39 +0100 Subject: [PATCH] Clean Webpack plugin --- .eslintrc.js | 4 +- docs/app.js | 2 +- package-lock.json | 151 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 4 +- webpack.dev.js | 2 + webpack.prod.js | 20 +++--- 6 files changed, 172 insertions(+), 11 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 0f7c024..8651b45 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -2,11 +2,11 @@ module.exports = { "env": { "browser": true, - "es6": true + "es2021": true }, "extends": "eslint:recommended", "parserOptions": { - "ecmaVersion": 2015, + "ecmaVersion": 2021, "sourceType": "module", }, "rules": { diff --git a/docs/app.js b/docs/app.js index d9e01ad..2a62fe7 100644 --- a/docs/app.js +++ b/docs/app.js @@ -26,7 +26,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _img \********************************/ /***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { -eval("/* global require HKReadTextArea */\n// AES JS\nvar aesjs = __webpack_require__(/*! ./aes-js.js */ \"./src/js/aes-js.js\");\n/* \r\n Parts of the code thanks to bloodorca https://github.com/bloodorca/hollow (base64.js, functions.js) with slight modifications.\r\n The steps used there for decryption were taken from KayDeeTee https://github.com/KayDeeTee/Hollow-Knight-SaveManager\r\n Without these two people the existence of this tool wouldn't be possible :)\r\n*/\n// ---------------- Constants ----------------- //\n\n\nvar CSHARP_HEADER = [0, 1, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 0, 0, 0, 0, 6, 1, 0, 0, 0]; // 22 bytes\n\nvar BASE64_ARRAY = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\".split(\"\").map(function (c) {\n return c.charCodeAt(0);\n});\nvar BASE64_DECODE_TABLE = new Map(BASE64_ARRAY.map(function (ord, i) {\n return [ord, i];\n}));\nvar AES_KEY = new TextEncoder().encode('UKu52ePUBwetZ9wNX88o54dnfKRu0T1l'); // encodes a string to Uint8Array (prepare for AES JS)\n\nvar ECB_STREAM_CIPHER = new aesjs.ModeOfOperation.ecb(AES_KEY); // create a new AES stream cipher object using the encoded key\n// ---------------- Variables ----------------- //\n\nvar benchLSFBegin, benchLSFEnd, benchTotal; // ---------------- Functions ----------------- //\n\n/**\r\n * Main input tag file function. Selects the first file, reads it as an Array Buffer, starts the processing of the file when loaded.\r\n * Starts benchmarking.\r\n * @param {FileList} input FileList object containing a list of File objects. The FileList behaves like an array, so you can check its length property to get the number of selected files.\r\n */\n// eslint-disable-next-line no-unused-vars\n\nfunction LoadSaveFile(input) {\n var startTime = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Date();\n // console.info(\"Input length: \" + input.files.length)\n // Cease further processing if user canceled the file input dialog\n if (input.files.length < 1) return false; // start benchmark\n\n benchLSFBegin = startTime; // Prepares a File object from the first file of the input files for reading as an Array Buffer\n\n var inputFileObject = input.files[0]; // Cleans the file list to avoid problems after subsequent use\n // document.getElementById(\"save-area-file\").value = \"\";\n // 1. read file\n // The ArrayBuffer object is used to represent a generic, fixed-length raw binary data buffer.\n // It is an array of bytes, often referred to in other languages as a \"byte array\".\n // new FileReader()\n\n var inputReader = new FileReader(); // readAsArrayBuffer(file)\n\n inputReader.readAsArrayBuffer(inputFileObject); // addEventListener(\"load\", function) - to decode the file when loaded\n\n inputReader.addEventListener(\"load\", ProcessFileObject);\n}\n/**\r\n * Reads the File object as an Array Buffer and does all other operations (decoding, decryption, conversion to string, pasting to text area).\r\n * Launches the HKReadTextArea() function automatically after pasting the string to text area\r\n */\n\n\nfunction ProcessFileObject() {\n var inputArrayBuffer = this.result;\n var decodedString; // 2. Decode file\n\n try {\n // Uint8Array(ArrayBuffer) uint8_t equivalent in C\n inputArrayBuffer = new Uint8Array(inputArrayBuffer); // ArrayBuffer.slice()\n // The slice() method copies up to, but not including, the byte indicated by the end parameter.\n\n inputArrayBuffer.slice(); // remove C# header and LengthPrefixedString header (ArrayBuffer)\n\n inputArrayBuffer = RemoveHeaders(inputArrayBuffer); // base64 Decoding (ArrayBuffer)\n\n inputArrayBuffer = Base64Decode(inputArrayBuffer); // AES decryption (ECB) removes pkcs7 padding (ArrayBuffer)\n\n inputArrayBuffer = AESDecryption(inputArrayBuffer); // Convert ArrayBuffer to string/text TextDecoder().decode(ArrayBuffer)\n\n decodedString = new TextDecoder().decode(inputArrayBuffer); // 4. Paste decoded string file to text area\n\n document.getElementById(\"save-area\").value = \"\";\n document.getElementById(\"save-area\").value = decodedString; // finish and show benchmark\n\n benchLSFEnd = new Date();\n console.info(\"LoadSaveFile() time (ms) =\", benchLSFEnd - benchLSFBegin); // after pasting the decoded string, launch the main analyzing function immediately\n\n HKReadTextArea(); // finish total and show benchmark\n\n benchTotal = new Date();\n console.info(\"Total time (ms) =\", benchTotal - benchLSFBegin); // alert(`Decoded String: ${decodedString}`);\n // alert(`Array Buffer: ${inputArrayBuffer}`);\n } catch (error) {\n alert(\"The file cannot be decoded. \".concat(error));\n console.info(\"The file cannot be decoded. \".concat(error));\n }\n}\n/**\r\n * Removes C# header, LengthPrefixedString header and byte 11 at the end of the Uint8 Array Buffer\r\n * @param {Uint8Array} buffer Uint8Array buffer for removing the header from\r\n * @param {Uint8Array} csHeader Uint8Array for the C# header length calculation\r\n * @returns {Uint8Array}\r\n */\n\n\nfunction RemoveHeaders(buffer) {\n var csHeader = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : CSHARP_HEADER;\n // Remove the fixed C# header and byte 11 at the end. \n buffer = buffer.subarray(csHeader.length, buffer.length - 1); // Remove LengthPrefixedString header\n\n var lengthCount = 0;\n\n for (var i = 0; i < 5; i++) {\n lengthCount++;\n\n if ((buffer[i] & 0x80) == 0) {\n break;\n }\n }\n\n return buffer.subarray(lengthCount);\n}\n/**\r\n * Decodes an Array Buffer using a Base64 decode table\r\n * @param {Uint8Array} buffer Uint8Array Buffer to decode\r\n * @returns {Uint8Array}\r\n */\n\n\nfunction Base64Decode(buffer) {\n buffer = new Uint8Array(buffer).slice();\n buffer = buffer.map(function (v) {\n return BASE64_DECODE_TABLE.get(v);\n }); // The indexOf() method returns the first index at which a given element can be found in the array, or -1 if it is not present.\n\n var p = buffer.indexOf(64);\n var end;\n\n if (p != -1) {\n end = p;\n } else {\n end = buffer.length;\n }\n\n buffer = buffer.subarray(0, end);\n var output = new Uint8Array(3 * buffer.length / 4);\n var continuous = Math.floor(buffer.length / 4) * 4;\n\n for (var i = 0; i < continuous; i += 4) {\n var k = 3 * i / 4;\n output[k] = buffer[i] << 2 | buffer[i + 1] >> 4;\n output[k + 1] = (buffer[i + 1] & 0x0F) << 4 | buffer[i + 2] >> 2;\n output[k + 2] = (buffer[i + 2] & 0x03) << 6 | buffer[i + 3];\n }\n\n if (buffer[continuous] != undefined) {\n var _k = 3 * continuous / 4;\n\n output[_k] = buffer[continuous] << 2 | buffer[continuous + 1] >> 4;\n\n if (buffer[continuous + 2] != undefined) {\n output[_k + 1] = (buffer[continuous + 1] & 0x0F) << 4 | buffer[continuous + 2] >> 2;\n }\n }\n\n return output;\n}\n/**\r\n * Decrypt an Uint8Array Buffer using aesjs (ECB) and a predefined AES key + remove pkcs7 padding\r\n * @param {Uint8Array} buffer Uint8Array buffer to decrypt\r\n * @returns {Uint8Array}\r\n */\n\n\nfunction AESDecryption(buffer) {\n var cipherObject = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ECB_STREAM_CIPHER;\n var output = cipherObject.decrypt(buffer);\n return output.subarray(0, -output[output.length - 1]);\n}\n\nwindow.LoadSaveFile = LoadSaveFile;\n\n//# sourceURL=webpack://hollow-knight-completion-check/./src/js/LoadSaveFile.js?"); +eval("/* global require HKReadTextArea */\n// AES JS\nvar aesjs = __webpack_require__(/*! ./aes-js.js */ \"./src/js/aes-js.js\");\n/* \r\n Parts of the code thanks to bloodorca https://github.com/bloodorca/hollow (base64.js, functions.js) with slight modifications.\r\n The steps used there for decryption were taken from KayDeeTee https://github.com/KayDeeTee/Hollow-Knight-SaveManager\r\n Without these two people the existence of this tool wouldn't be possible :)\r\n*/\n// ---------------- Constants ----------------- //\n\n\nvar CSHARP_HEADER = [0, 1, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 0, 0, 0, 0, 6, 1, 0, 0, 0]; // 22 bytes\n\nvar BASE64_ARRAY = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\".split(\"\").map(function (c) {\n return c.charCodeAt(0);\n});\nvar BASE64_DECODE_TABLE = new Map(BASE64_ARRAY.map(function (ord, i) {\n return [ord, i];\n}));\nvar AES_KEY = new TextEncoder().encode('UKu52ePUBwetZ9wNX88o54dnfKRu0T1l'); // encodes a string to Uint8Array (prepare for AES JS)\n\nvar ECB_STREAM_CIPHER = new aesjs.ModeOfOperation.ecb(AES_KEY); // create a new AES stream cipher object using the encoded key\n// ---------------- Variables ----------------- //\n\nvar benchLSFBegin, benchLSFEnd, benchTotal; // ---------------- Functions ----------------- //\n\n/**\r\n * Main input tag file function. Selects the first file, reads it as an Array Buffer, starts the processing of the file when loaded.\r\n * Starts benchmarking.\r\n * @param {FileList} input FileList object containing a list of File objects. The FileList behaves like an array, so you can check its length property to get the number of selected files.\r\n */\n// eslint-disable-next-line no-unused-vars\n\nfunction LoadSaveFile(input) {\n var startTime = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Date();\n // console.info(\"Input length: \" + input.files.length)\n // Cease further processing if user canceled the file input dialog\n if (input.files.length < 1) return false; // start benchmark\n\n benchLSFBegin = startTime; // Prepares a File object from the first file of the input files for reading as an Array Buffer\n\n var inputFileObject = input.files[0]; // Cleans the file list to avoid problems after subsequent use\n // document.getElementById(\"save-area-file\").value = \"\";\n // 1. read file\n // The ArrayBuffer object is used to represent a generic, fixed-length raw binary data buffer.\n // It is an array of bytes, often referred to in other languages as a \"byte array\".\n // new FileReader()\n\n var inputReader = new FileReader(); // readAsArrayBuffer(file)\n\n inputReader.readAsArrayBuffer(inputFileObject); // addEventListener(\"load\", function) - to decode the file when loaded\n\n inputReader.addEventListener(\"load\", ProcessFileObject);\n}\n/**\r\n * Reads the File object as an Array Buffer and does all other operations (decoding, decryption, conversion to string, pasting to text area).\r\n * Launches the HKReadTextArea() function automatically after pasting the string to text area\r\n */\n\n\nfunction ProcessFileObject() {\n var inputArrayBuffer = this.result;\n var decodedString; // 2. Decode file\n\n try {\n // Uint8Array(ArrayBuffer) uint8_t equivalent in C\n inputArrayBuffer = new Uint8Array(inputArrayBuffer); // ArrayBuffer.slice()\n // The slice() method copies up to, but not including, the byte indicated by the end parameter.\n\n inputArrayBuffer.slice(); // remove C# header and LengthPrefixedString header (ArrayBuffer)\n\n inputArrayBuffer = RemoveHeaders(inputArrayBuffer); // base64 Decoding (ArrayBuffer)\n\n inputArrayBuffer = Base64Decode(inputArrayBuffer); // AES decryption (ECB) removes pkcs7 padding (ArrayBuffer)\n\n inputArrayBuffer = AESDecryption(inputArrayBuffer); // Convert ArrayBuffer to string/text TextDecoder().decode(ArrayBuffer)\n\n decodedString = new TextDecoder().decode(inputArrayBuffer); // 4. Paste decoded string file to text area\n\n document.getElementById(\"save-area\").value = \"\";\n document.getElementById(\"save-area\").value = decodedString; // finish and show benchmark\n\n benchLSFEnd = new Date();\n console.info(\"LoadSaveFile() time (ms) =\", benchLSFEnd - benchLSFBegin); // after pasting the decoded string, launch the main analyzing function immediately\n\n HKReadTextArea(); // finish total and show benchmark\n\n benchTotal = new Date();\n console.info(\"Total time (ms) =\", benchTotal - benchLSFBegin); // alert(`Decoded String: ${decodedString}`);\n // alert(`Array Buffer: ${inputArrayBuffer}`);\n } catch (error) {\n alert(\"The file cannot be decoded. \".concat(error));\n console.info(\"The file cannot be decoded. \".concat(error));\n }\n}\n/**\r\n * Removes C# header, LengthPrefixedString header and byte 11 at the end of the Uint8 Array Buffer\r\n * @param {Uint8Array} buffer Uint8Array buffer for removing the header from\r\n * @param {Uint8Array} csHeader Uint8Array for the C# header length calculation\r\n * @returns {Uint8Array}\r\n */\n\n\nfunction RemoveHeaders(buffer) {\n var csHeader = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : CSHARP_HEADER;\n // Remove the fixed C# header and byte 11 at the end. \n buffer = buffer.subarray(csHeader.length, buffer.length - 1); // Remove LengthPrefixedString header\n\n var lengthCount = 0;\n\n for (var i = 0; i < 5; i++) {\n lengthCount++;\n\n if ((buffer[i] & 0x80) == 0) {\n break;\n }\n }\n\n return buffer.subarray(lengthCount);\n}\n/**\r\n * Decodes an Array Buffer using a Base64 decode table\r\n * @param {Uint8Array} buffer Uint8Array Buffer to decode\r\n * @returns {Uint8Array}\r\n */\n\n\nfunction Base64Decode(buffer) {\n buffer = new Uint8Array(buffer).slice();\n buffer = buffer.map(function (v) {\n return BASE64_DECODE_TABLE.get(v);\n }); // The indexOf() method returns the first index at which a given element can be found in the array, or -1 if it is not present.\n\n var p = buffer.indexOf(64);\n var end;\n\n if (p != -1) {\n end = p;\n } else {\n end = buffer.length;\n }\n\n buffer = buffer.subarray(0, end);\n var output = new Uint8Array(3 * buffer.length / 4);\n var continuous = Math.floor(buffer.length / 4) * 4;\n\n for (var i = 0; i < continuous; i += 4) {\n var k = 3 * i / 4;\n output[k] = buffer[i] << 2 | buffer[i + 1] >> 4;\n output[k + 1] = (buffer[i + 1] & 0x0F) << 4 | buffer[i + 2] >> 2;\n output[k + 2] = (buffer[i + 2] & 0x03) << 6 | buffer[i + 3];\n }\n\n if (buffer[continuous] != undefined) {\n var _k = 3 * continuous / 4;\n\n output[_k] = buffer[continuous] << 2 | buffer[continuous + 1] >> 4;\n\n if (buffer[continuous + 2] != undefined) {\n output[_k + 1] = (buffer[continuous + 1] & 0x0F) << 4 | buffer[continuous + 2] >> 2;\n }\n }\n\n return output;\n}\n/**\r\n * Decrypt an Uint8Array Buffer using aesjs (ECB) and a predefined AES key + remove pkcs7 padding\r\n * @param {Uint8Array} buffer Uint8Array buffer to decrypt\r\n * @returns {Uint8Array}\r\n */\n\n\nfunction AESDecryption(buffer) {\n var cipherObject = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ECB_STREAM_CIPHER;\n var output = cipherObject.decrypt(buffer);\n return output.subarray(0, -output[output.length - 1]);\n} // Make functions global so they can be used on click and change events (for Webpack)\n\n\nwindow.LoadSaveFile = LoadSaveFile;\n\n//# sourceURL=webpack://hollow-knight-completion-check/./src/js/LoadSaveFile.js?"); /***/ }), diff --git a/package-lock.json b/package-lock.json index 69367b6..0b66920 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1147,6 +1147,16 @@ "integrity": "sha512-laIjwTQaD+5DukBZaygQ79K1Z0jb1bPEMRrkXSLjtCcZm+abyp5YbrqpSLzD42FwWW6gK/aS4NYpJ804nG2brg==", "dev": true }, + "@types/glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", + "dev": true, + "requires": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, "@types/html-minifier-terser": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", @@ -1159,6 +1169,12 @@ "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", "dev": true }, + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, "@types/node": { "version": "14.14.22", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.22.tgz", @@ -1480,6 +1496,21 @@ "sprintf-js": "~1.0.2" } }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, "astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -1785,6 +1816,16 @@ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true }, + "clean-webpack-plugin": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", + "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==", + "dev": true, + "requires": { + "@types/webpack": "^4.4.31", + "del": "^4.1.1" + } + }, "clone-deep": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", @@ -2364,6 +2405,38 @@ "object-keys": "^1.0.12" } }, + "del": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", + "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "globby": "^6.1.0", + "is-path-cwd": "^2.0.0", + "is-path-in-cwd": "^2.0.0", + "p-map": "^2.0.0", + "pify": "^4.0.1", + "rimraf": "^2.6.3" + }, + "dependencies": { + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -2939,6 +3012,27 @@ "type-fest": "^0.8.1" } }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, "graceful-fs": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", @@ -3333,6 +3427,30 @@ "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "dev": true }, + "is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true + }, + "is-path-in-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", + "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", + "dev": true, + "requires": { + "is-path-inside": "^2.1.0" + } + }, + "is-path-inside": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", + "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", + "dev": true, + "requires": { + "path-is-inside": "^1.0.2" + } + }, "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -3771,6 +3889,12 @@ "boolbase": "~1.0.0" } }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, "object-inspect": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", @@ -3950,6 +4074,12 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -3962,6 +4092,27 @@ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, "pkg-dir": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", diff --git a/package.json b/package.json index e021a70..f2d9473 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "main": "index.html", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "start": "webpack --config webpack.dev.js --mode development" + "start": "webpack --config webpack.dev.js --mode development", + "prod": "webpack --config webpack.prod.js --mode production" }, "repository": { "type": "git", @@ -34,6 +35,7 @@ "@babel/core": "^7.12.10", "@babel/preset-env": "^7.12.11", "babel-loader": "^8.2.2", + "clean-webpack-plugin": "^3.0.0", "css-loader": "^5.0.1", "css-minimizer-webpack-plugin": "^1.2.0", "eslint": "^7.18.0", diff --git a/webpack.dev.js b/webpack.dev.js index bf31b81..a91efec 100644 --- a/webpack.dev.js +++ b/webpack.dev.js @@ -1,6 +1,7 @@ /* global require module __dirname */ const HtmlWebpackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); +const { CleanWebpackPlugin } = require('clean-webpack-plugin'); module.exports = { entry: { @@ -13,6 +14,7 @@ module.exports = { assetModuleFilename: 'img/[hash][ext][query]', }, plugins: [ + new CleanWebpackPlugin(), new MiniCssExtractPlugin(), new HtmlWebpackPlugin({ template: './src/index.html', diff --git a/webpack.prod.js b/webpack.prod.js index ce4a466..c0818c3 100644 --- a/webpack.prod.js +++ b/webpack.prod.js @@ -3,12 +3,13 @@ const HtmlWebpackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); const TerserPlugin = require('terser-webpack-plugin'); +const { CleanWebpackPlugin } = require('clean-webpack-plugin'); module.exports = { entry: { index: './src/js/index.js', }, - mode: 'production', // or development + mode: 'production', optimization: { minimize: true, minimizer: [ @@ -21,14 +22,17 @@ module.exports = { output: { path: `${__dirname}/docs`, filename: 'app.js', + assetModuleFilename: 'img/[hash][ext][query]', }, plugins: [ + new CleanWebpackPlugin(), new MiniCssExtractPlugin(), new HtmlWebpackPlugin({ template: './src/index.html', inject: true, chunks: ['index'], - filename: 'index.html' + filename: 'index.html', + favicon: "./src/favicon.png", }) ], module: { @@ -44,8 +48,12 @@ module.exports = { }, { test: /\.css$/, - use: [ - MiniCssExtractPlugin.loader, + use: [{ + loader: MiniCssExtractPlugin.loader, + options: { + publicPath: "", + }, + }, // 'style-loader', 'css-loader', // 'sass-loader', @@ -53,9 +61,7 @@ module.exports = { }, { test: /\.(svg|jpg|png|ttf|eot|woff|woff2)$/, - use: [ - 'url-loader', - ], + type: 'asset', }, ], },