From 29431f3d6ac37ef2c2d037d8e3042b71ea8750f4 Mon Sep 17 00:00:00 2001 From: Dzhygun <5046351+dzhygun@users.noreply.github.com> Date: Sun, 14 Sep 2025 10:49:53 +0200 Subject: [PATCH 1/3] feature: minify .js scripts in Files.copyAssetsFiles; added terser dependency --- .../modules/render-html/helpers/files.js | 49 +++++++++++++++---- app/package-lock.json | 19 +++++++ app/package.json | 1 + 3 files changed, 60 insertions(+), 9 deletions(-) diff --git a/app/back-end/modules/render-html/helpers/files.js b/app/back-end/modules/render-html/helpers/files.js index 6bfd1574..eaf69e5b 100644 --- a/app/back-end/modules/render-html/helpers/files.js +++ b/app/back-end/modules/render-html/helpers/files.js @@ -6,6 +6,7 @@ const UtilsHelper = require('./../../../helpers/utils'); const normalizePath = require('normalize-path'); const DiffCopy = require('./diffCopy.js'); const PluginsHelpers = require('./../../plugins/plugins-helpers'); +const { minify } = require('terser'); class Files { /** @@ -17,7 +18,7 @@ class Files { static copyRootFiles(inputDir, outputDir) { let inputPath = path.join(inputDir, 'root-files'); let outputPath = path.join(outputDir); - + fs.copySync( path.join(inputPath), path.join(outputPath), @@ -54,7 +55,7 @@ class Files { flatten: true }).then(files => { let dynamicAssetsPath = path.join(assetsPath, 'dynamic'); - + files.filter(item => { let filename = path.parse(item.path).base; @@ -64,7 +65,7 @@ class Files { return themeConfig.files.ignoreAssets.indexOf(filename) === -1 }).forEach(item => { - if(item.mode.dir === false) { + if (item.mode.dir === false) { let filePath = normalizePath(item.path); let destinationPath = filePath.replace( normalizePath(assetsPath), @@ -75,6 +76,10 @@ class Files { filePath, destinationPath ); + + if (path.extname(destinationPath) === '.js') { + this.#minifyJsFile(destinationPath, false); + } } }); }); @@ -113,7 +118,7 @@ class Files { * @param outputDir * @param themeConfig */ - static copyDynamicAssetsFiles(themeDir, outputDir, themeConfig) { + static copyDynamicAssetsFiles(themeDir, outputDir, themeConfig) { if (!themeConfig.files.useDynamicAssets) { return; } @@ -164,7 +169,7 @@ class Files { * @param outputDir * @param postIDs */ - static async copyMediaFiles (inputDir, outputDir, postIDs, pageIDs) { + static async copyMediaFiles(inputDir, outputDir, postIDs, pageIDs) { let basePathInput = path.join(inputDir, 'media'); let basePathOutput = path.join(outputDir, 'media'); let dirs = ['website', 'files', 'tags', 'authors', 'posts/defaults']; @@ -199,7 +204,7 @@ class Files { ); } else { await DiffCopy.copy( - path.join(basePathInput, dirs[i]), + path.join(basePathInput, dirs[i]), path.join(basePathOutput, dirs[i]) ); } @@ -222,11 +227,11 @@ class Files { * @param inputDir * @param outputDir */ - static async copyPluginFiles (inputDir, outputDir, pluginsDir) { + static async copyPluginFiles(inputDir, outputDir, pluginsDir) { let pluginsList = PluginsHelpers.getActivePluginsList(path.join(inputDir, 'config', 'site.plugins.json')); let basePathInput = path.join(inputDir, 'media'); let basePathOutput = path.join(outputDir, 'media'); - + // create media dir if not exists if (!UtilsHelper.dirExists(path.join(basePathOutput))) { fs.mkdirSync(path.join(basePathOutput)); @@ -268,10 +273,36 @@ class Files { } } - static async removeEmptyDirectories (outputDir) { + static async removeEmptyDirectories(outputDir) { let basePathOutput = path.join(outputDir, 'media'); deleteEmpty(basePathOutput); } + + /** + * @param {{ string }} filePath + * @param {boolean} [keepOriginalFile=true] - If true, create an additional .min.js file; if false, overwrite the original. + * @returns {Promise} + */ + static async #minifyJsFile(filePath, keepOriginalFile = true) { + const filename = path.parse(filePath).base; + + if (!filename.endsWith('.js')) { + throw new Error(`Expected .js file path, got: ${filePath}`); + } + + const code = fs.readFileSync(filePath, 'utf8'); + const result = await minify(code, { compress: true, mangle: true }); + if (result.error) { + console.error(`Minify error for ${filePath}:`, result.error); + return; + } + + const outPath = keepOriginalFile + ? path.join(path.dirname(filePath), filename.replace(/\.js$/, '.min.js')) + : filePath; + + fs.writeFileSync(outPath, result.code); + } } module.exports = Files; diff --git a/app/package-lock.json b/app/package-lock.json index 4949cee8..99f91476 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -50,6 +50,7 @@ "ssh2-sftp-client": "10.0.3", "striptags": "3.2.0", "tar-fs": "3.0.4", + "terser": "^5.44.0", "transliteration": "2.3.5", "vue": "2.6.14", "vue-color": "2.4.5", @@ -6493,6 +6494,24 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/terser": { + "version": "5.44.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.0.tgz", + "integrity": "sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w==", + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", diff --git a/app/package.json b/app/package.json index 6b336cab..bc1b925e 100644 --- a/app/package.json +++ b/app/package.json @@ -66,6 +66,7 @@ "ssh2-sftp-client": "10.0.3", "striptags": "3.2.0", "tar-fs": "3.0.4", + "terser": "^5.44.0", "transliteration": "2.3.5", "vue": "2.6.14", "vue-color": "2.4.5", From 9b8ef13ff6d6f8b7524550bc3910e19f32355bc6 Mon Sep 17 00:00:00 2001 From: Dzhygun <5046351+dzhygun@users.noreply.github.com> Date: Mon, 15 Sep 2025 13:40:02 +0200 Subject: [PATCH 2/3] feature: minify .js - removed optional keepOriginalFiles - now original files are replaced with minified version in output/preview, because the original file name is referenced from .html files --- app/back-end/modules/render-html/helpers/files.js | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/app/back-end/modules/render-html/helpers/files.js b/app/back-end/modules/render-html/helpers/files.js index eaf69e5b..323521a8 100644 --- a/app/back-end/modules/render-html/helpers/files.js +++ b/app/back-end/modules/render-html/helpers/files.js @@ -78,7 +78,7 @@ class Files { ); if (path.extname(destinationPath) === '.js') { - this.#minifyJsFile(destinationPath, false); + this.#minifyJsFile(destinationPath); } } }); @@ -280,10 +280,9 @@ class Files { /** * @param {{ string }} filePath - * @param {boolean} [keepOriginalFile=true] - If true, create an additional .min.js file; if false, overwrite the original. * @returns {Promise} */ - static async #minifyJsFile(filePath, keepOriginalFile = true) { + static async #minifyJsFile(filePath) { const filename = path.parse(filePath).base; if (!filename.endsWith('.js')) { @@ -297,11 +296,7 @@ class Files { return; } - const outPath = keepOriginalFile - ? path.join(path.dirname(filePath), filename.replace(/\.js$/, '.min.js')) - : filePath; - - fs.writeFileSync(outPath, result.code); + fs.writeFileSync(filePath, result.code); } } From 7ed2f8b78470b12362003feac7ecfa214ed269c8 Mon Sep 17 00:00:00 2001 From: Dzhygun <5046351+dzhygun@users.noreply.github.com> Date: Mon, 15 Sep 2025 13:40:37 +0200 Subject: [PATCH 3/3] feature: minify .js - upd package-lock.json - automatically added libs for terser --- app/package-lock.json | 67 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/app/package-lock.json b/app/package-lock.json index 99f91476..d147ab91 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -1836,6 +1836,51 @@ "regenerator-runtime": "^0.13.3" } }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, "node_modules/@sindresorhus/is": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", @@ -2613,6 +2658,18 @@ "node": ">=6.5" } }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/adm-zip": { "version": "0.5.10", "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz", @@ -6173,6 +6230,16 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, "node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",