Split js chunks
All checks were successful
Deploy Spot / deploy (push) Successful in 34s

This commit is contained in:
2026-05-23 00:12:15 +02:00
parent 8a590aa2fc
commit e0fc62df84
5 changed files with 78 additions and 10 deletions

View File

@@ -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'))
])
);
}

View File

@@ -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);
}

View File

@@ -10,7 +10,7 @@
},
"name": "spot",
"description": "FindMeSpot & GPX integration",
"version": "2.0.0",
"version": "2.1.0",
"main": "index.js",
"private": true,
"scripts": {

View File

@@ -1,12 +1,11 @@
<script>
import { defineAsyncComponent } from 'vue';
import Project from '@components/project';
import Admin from '@components/admin';
import Upload from '@components/upload';
const aoRoutes = {
'project': Project,
'admin': Admin,
'upload': Upload
'project': Project, //Merge app.js and project.js calls to avoid extra http request on inital page
'admin': defineAsyncComponent(() => import(/* webpackChunkName: "admin" */ '@components/admin')),
'upload': defineAsyncComponent(() => import(/* webpackChunkName: "upload" */ '@components/upload'))
};
export default {

View File

@@ -19,11 +19,13 @@
<meta name="msapplication-TileColor" content="#00a300">
<meta name="msapplication-config" content="images/icons/browserconfig.xml?v=GvmqYyKwbb">
<meta name="theme-color" content="#ffffff">
<script id="app-config" type="application/json">[#]APP_CONFIG[#]</script>
<script id="app-config" type="application/json">[#]app_config[#]</script>
<title>Spotty</title>
</head>
<body>
<div id="container"></div>
<script type="module" src="[#]filepath_js[#]"></script>
<!-- [PART] entrypoint [START] -->
<script defer src="[#]filename[#]"></script>
<!-- [PART] entrypoint [END] -->
</body>
</html>