From e0fc62df84f17b8dd8623541e00e01e993543f81 Mon Sep 17 00:00:00 2001 From: Franzz Date: Sat, 23 May 2026 00:12:15 +0200 Subject: [PATCH] Split js chunks --- build/webpack.config.js | 54 +++++++++++++++++++++++++++++++++++++++++ lib/Spot.php | 17 +++++++++++-- package.json | 2 +- src/Spot.vue | 9 +++---- src/masks/index.html | 6 +++-- 5 files changed, 78 insertions(+), 10 deletions(-) diff --git a/build/webpack.config.js b/build/webpack.config.js index e1d41c5..e02f326 100644 --- a/build/webpack.config.js +++ b/build/webpack.config.js @@ -1,4 +1,5 @@ const path = require('path'); +const fs = require('fs'); const webpack = require('webpack'); const CopyWebpackPlugin = require('copy-webpack-plugin'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); @@ -24,8 +25,35 @@ module.exports = (env, argv) => { output: { path: DIST, filename: '[name].js', + chunkFilename: '[name].js', publicPath: './' }, + optimization: { + splitChunks: { + chunks: 'all', + cacheGroups: { + maplibre: { + test: /[\\/]node_modules[\\/]maplibre-gl[\\/]/, + name: 'maplibre', + chunks: 'all', + priority: 30, + enforce: true + }, + uppy: { + test: /[\\/]node_modules[\\/](@uppy|@transloadit|namespace-emitter|nanoid)[\\/]/, + name: 'uppy', + chunks: 'async', + priority: 20, + enforce: true + } + } + } + }, + performance: { + hints: isDev ? false : 'warning', + maxEntrypointSize: 1500 * 1024, + maxAssetSize: 1100 * 1024 + }, module: { rules: [{ test: /\.vue$/, @@ -90,6 +118,18 @@ module.exports = (env, argv) => { __VUE_PROD_DEVTOOLS__: 'false', __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'false' }), + { + apply(compiler) { + compiler.hooks.done.tap('EntryPointManifestPlugin', (stats) => { + const manifest = { + entrypoints: mapChunkGroups(stats.compilation.entrypoints), + chunkGroups: mapChunkGroups(stats.compilation.chunkGroups) + }; + + fs.writeFileSync(path.resolve(DIST, 'entrypoints.json'), JSON.stringify(manifest, null, '\t')); + }); + } + }, new VueLoaderPlugin() ], resolve: { @@ -102,3 +142,17 @@ module.exports = (env, argv) => { } }; }; + +function mapChunkGroups(chunkGroups = {}) { + const chunkGroupEntries = (chunkGroups instanceof Map)?Array.from(chunkGroups.entries()):Array.from(chunkGroups).map((chunkGroup) => [chunkGroup.name, chunkGroup]); + return Object.fromEntries( + chunkGroupEntries + .filter(([name]) => name) + .map(([name, chunkGroup]) => [ + name, + Array.from((typeof chunkGroup.getFiles === 'function')?chunkGroup.getFiles():chunkGroup.assets) + .map((asset) => (typeof asset === 'string')?asset:asset.name) + .filter((file) => file.endsWith('.js')) + ]) + ); +} \ No newline at end of file diff --git a/lib/Spot.php b/lib/Spot.php index 949dfc1..934b117 100755 --- a/lib/Spot.php +++ b/lib/Spot.php @@ -44,6 +44,8 @@ class Spot extends Main const MAIN_PAGE = 'index'; + const DIST_FOLDER = '../dist/'; + private Project $oProject; private Media $oMedia; private User $oUser; @@ -188,13 +190,24 @@ class Spot extends Main ), self::MAIN_PAGE, array( - 'language' => $this->oLang->getLanguage(), - 'filepath_js' => self::addTimestampToFilePath('app.js'), + 'tags' => [ + 'language' => $this->oLang->getLanguage() + ], + 'instances' => [ + 'entrypoint' => $this->getAppEntryPoints() + ] ), $asPages ); } + private function getAppEntryPoints() { + return array_map( + function($sFileName) {return ['filename' => self::addTimestampToFilePath($sFileName)];}, + json_decode(file_get_contents(self::DIST_FOLDER.'entrypoints.json'), true)['entrypoints']['app'] + ); + } + public function checkUserClearance($iClearance) { return $this->oUser->checkUserClearance($iClearance); } diff --git a/package.json b/package.json index a0859c2..1d25bf9 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ }, "name": "spot", "description": "FindMeSpot & GPX integration", - "version": "2.0.0", + "version": "2.1.0", "main": "index.js", "private": true, "scripts": { diff --git a/src/Spot.vue b/src/Spot.vue index 5841690..adc4a5c 100644 --- a/src/Spot.vue +++ b/src/Spot.vue @@ -1,12 +1,11 @@ + Spotty
- + + +