From 8bce10e61b77f9d0b7f536616f878ff1af897cbc Mon Sep 17 00:00:00 2001 From: sebseb7 Date: Sat, 28 Mar 2026 18:21:39 +0100 Subject: [PATCH] refactor: Improve git commit hash retrieval method and enhance webpack configuration for better lazy loading of components --- webpack.config.js | 63 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 5 deletions(-) diff --git a/webpack.config.js b/webpack.config.js index 4d574ee..687ddec 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -5,17 +5,31 @@ import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin'; import MiniCssExtractPlugin from 'mini-css-extract-plugin'; import ESLintPlugin from 'eslint-webpack-plugin'; import { cpSync } from 'fs'; -import { execSync } from 'child_process'; +import { execFileSync } from 'child_process'; import webpack from 'webpack'; import fs from 'fs'; import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'; -// Get git commit hash +// Git hash for meta tag / currentHash.json — prefer env (CI), then git without shell (avoids EPERM on spawn /bin/sh in some sandboxes) const getGitCommitHash = () => { + const fromEnv = + process.env.GIT_COMMIT || + process.env.VERCEL_GIT_COMMIT_SHA || + process.env.CI_COMMIT_SHA || + process.env.GITHUB_SHA || + ''; + if (fromEnv) return String(fromEnv).trim(); + try { - return execSync('git rev-parse HEAD').toString().trim(); + return execFileSync('git', ['rev-parse', 'HEAD'], { + encoding: 'utf8', + maxBuffer: 1024 * 1024, + }).trim(); } catch (e) { - console.error('Failed to get git commit hash:', e); + console.warn( + 'Git commit hash unavailable (set GIT_COMMIT or run build in a git repo):', + e && e.message ? e.message : e + ); return 'unknown'; } }; @@ -301,14 +315,53 @@ export default { priority: 20, reuseExistingChunk: true, }, + // Keep Stripe checkout out of the initial vendor bundle (loaded with payment routes) + stripe: { + test: /[\\/]node_modules[\\/]@stripe[\\/]/, + name: 'stripe', + priority: 19, + chunks: 'async', + reuseExistingChunk: true, + enforce: true, + }, + // QR / SEPA helpers — checkout & profile only (not htmlParser: that caused CLS on product pages) + payments: { + test: /[\\/]node_modules[\\/](qrcode|sepa-payment-qr-code|iban)[\\/]/, + name: 'payments', + priority: 17, + chunks: 'async', + reuseExistingChunk: true, + enforce: true, + }, // socket.io-client and its dependencies — always async, never initial socketio: { - test: /[\\/]node_modules[\\/](socket\.io-client|engine\.io-client|@socket\.io|socket\.io-parser|socket\.io-msgpack-parser)[\\/]/, + test: /[\\/]node_modules[\\/](socket\.io-client|engine\.io-client|engine\.io-parser|@socket\.io|socket\.io-parser|socket\.io-msgpack-parser)[\\/]/, name: 'socketio', priority: 15, chunks: 'async', reuseExistingChunk: true, }, + // Language switcher flags: dynamic import() must stay async-only. The catch-all `vendor` + // group below uses chunks: 'all' and would otherwise merge this into vendor → no extra + // network request on menu open (flags shipped in initial load). + countryFlagIcons: { + test: /[\\/]node_modules[\\/]country-flag-icons[\\/]/, + name: 'country-flag-icons', + priority: 12, + chunks: 'async', + reuseExistingChunk: true, + enforce: true, + }, + // LazySanitizedHtml (product HTML etc.): keep parser stack out of initial vendor. + // Do NOT include postcss here — it is used by other tools and forced async caused CLS before. + htmlSanitizeAsync: { + test: /[\\/]node_modules[\\/](html-react-parser|sanitize-html|htmlparser2|domhandler|dom-serializer|entities|react-property|parse-srcset)[\\/]/, + name: 'html-sanitize-async', + priority: 11, + chunks: 'async', + reuseExistingChunk: true, + enforce: true, + }, // Other vendor libraries vendor: { test: /[\\/]node_modules[\\/]/,