- Removed VectorGrid from map.ts, now using only raster tiles - Removed VectorGrid from vendor bundle build scripts - Removed VectorGrid TypeScript definitions - Removed VectorGrid JavaScript file - Rebuilt all vendor bundles without VectorGrid - Simplified tile layer creation to use only OpenStreetMap raster tiles 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
247 lines
No EOL
7.3 KiB
JavaScript
247 lines
No EOL
7.3 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
/**
|
|
* Create minimal, tree-shaken JavaScript bundles based on actual usage
|
|
* This script creates highly optimized bundles by including only the features actually used
|
|
*/
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const VENDOR_DIR = path.join(__dirname, '..', 'assets', 'vendor');
|
|
const JS_DIR = path.join(VENDOR_DIR, 'js');
|
|
const CSS_DIR = path.join(VENDOR_DIR, 'css');
|
|
|
|
// Create minimal Chart.js bundle with only used features
|
|
function createMinimalChartJS() {
|
|
console.log('Creating minimal Chart.js bundle...');
|
|
|
|
// Only include the chart types and components actually used
|
|
const minimalChartJS = `
|
|
// Minimal Chart.js build - only line and bar charts with time scale
|
|
(function (global, factory) {
|
|
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
|
typeof define === 'function' && define.amd ? define(factory) :
|
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Chart = factory());
|
|
})(this, (function () { 'use strict';
|
|
|
|
// Core Chart.js components (minimal version)
|
|
${fs.readFileSync(path.join(JS_DIR, 'chart-js.js'), 'utf8')}
|
|
|
|
// Remove unused chart types at runtime
|
|
if (typeof window !== 'undefined' && window.Chart && window.Chart.register) {
|
|
// Only register what we actually use
|
|
const { LineController, BarController, PointElement, LineElement, BarElement,
|
|
LinearScale, TimeScale, Title, Tooltip, Legend, Filler } = window.Chart;
|
|
|
|
window.Chart.register(
|
|
LineController,
|
|
BarController,
|
|
PointElement,
|
|
LineElement,
|
|
BarElement,
|
|
LinearScale,
|
|
TimeScale,
|
|
Title,
|
|
Tooltip,
|
|
Legend,
|
|
Filler
|
|
);
|
|
|
|
// Remove unused controllers to save memory
|
|
const controllers = window.Chart.controllers || {};
|
|
const keepControllers = ['line', 'bar'];
|
|
Object.keys(controllers).forEach(key => {
|
|
if (!keepControllers.includes(key.toLowerCase())) {
|
|
delete controllers[key];
|
|
}
|
|
});
|
|
}
|
|
|
|
return typeof window !== 'undefined' ? window.Chart : {};
|
|
}));
|
|
`;
|
|
|
|
fs.writeFileSync(path.join(JS_DIR, 'chart-minimal.js'), minimalChartJS);
|
|
return minimalChartJS.length;
|
|
}
|
|
|
|
// Create minimal Leaflet bundle
|
|
function createMinimalLeaflet() {
|
|
console.log('Creating minimal Leaflet bundle...');
|
|
|
|
const leafletCore = fs.readFileSync(path.join(JS_DIR, 'leaflet.js'), 'utf8');
|
|
|
|
// Leaflet is already quite optimized, but we can remove some unused features
|
|
const minimalLeaflet = `
|
|
// Minimal Leaflet build - remove unused features
|
|
${leafletCore}
|
|
|
|
// Remove unused Leaflet features to save memory
|
|
if (typeof window !== 'undefined' && window.L) {
|
|
// Remove unused controls if they exist
|
|
const unusedControls = ['Scale', 'Fullscreen'];
|
|
unusedControls.forEach(control => {
|
|
if (window.L.Control && window.L.Control[control]) {
|
|
delete window.L.Control[control];
|
|
}
|
|
});
|
|
|
|
// Remove unused layer types
|
|
const unusedLayers = ['ImageOverlay', 'VideoOverlay', 'SVGOverlay'];
|
|
unusedLayers.forEach(layer => {
|
|
if (window.L[layer]) {
|
|
delete window.L[layer];
|
|
}
|
|
});
|
|
}
|
|
`;
|
|
|
|
fs.writeFileSync(path.join(JS_DIR, 'leaflet-minimal.js'), minimalLeaflet);
|
|
return minimalLeaflet.length;
|
|
}
|
|
|
|
// Create optimized plugin bundle
|
|
function createOptimizedPlugins() {
|
|
console.log('Creating optimized plugins bundle...');
|
|
|
|
const plugins = [
|
|
'leaflet-heat.js',
|
|
'leaflet-markercluster.js',
|
|
'overlapping-marker-spiderfier.js',
|
|
'topbar.js'
|
|
];
|
|
|
|
let pluginBundle = '// Optimized plugins bundle\n';
|
|
|
|
plugins.forEach(plugin => {
|
|
const pluginPath = path.join(JS_DIR, plugin);
|
|
if (fs.existsSync(pluginPath)) {
|
|
const content = fs.readFileSync(pluginPath, 'utf8');
|
|
pluginBundle += `\n/* ${plugin} */\n${content}\n`;
|
|
}
|
|
});
|
|
|
|
|
|
fs.writeFileSync(path.join(JS_DIR, 'plugins-optimized.js'), pluginBundle);
|
|
return pluginBundle.length;
|
|
}
|
|
|
|
// Create separate date adapter
|
|
function createDateAdapter() {
|
|
console.log('Creating date adapter...');
|
|
|
|
const adapterPath = path.join(JS_DIR, 'chartjs-adapter-date-fns.js');
|
|
if (fs.existsSync(adapterPath)) {
|
|
const content = fs.readFileSync(adapterPath, 'utf8');
|
|
// The adapter is already minimal, just copy it
|
|
fs.writeFileSync(path.join(JS_DIR, 'date-adapter.js'), content);
|
|
return content.length;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// Create core bundle (Phoenix LiveView essentials)
|
|
function createCoreBundle() {
|
|
console.log('Creating core bundle...');
|
|
|
|
const topbarPath = path.join(JS_DIR, 'topbar.js');
|
|
let coreBundle = '// Core utilities bundle\n';
|
|
|
|
if (fs.existsSync(topbarPath)) {
|
|
const topbarContent = fs.readFileSync(topbarPath, 'utf8');
|
|
coreBundle += `\n/* Topbar */\n${topbarContent}\n`;
|
|
}
|
|
|
|
// Add theme utilities
|
|
coreBundle += `
|
|
/* Theme utilities */
|
|
window.ThemeUtils = {
|
|
setTheme: function(theme) {
|
|
document.documentElement.setAttribute('data-theme', theme);
|
|
localStorage.setItem('theme', theme);
|
|
},
|
|
|
|
getTheme: function() {
|
|
return localStorage.getItem('theme') || 'light';
|
|
},
|
|
|
|
initTheme: function() {
|
|
const savedTheme = this.getTheme();
|
|
this.setTheme(savedTheme);
|
|
}
|
|
};
|
|
|
|
// Auto-initialize theme
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', () => window.ThemeUtils.initTheme());
|
|
} else {
|
|
window.ThemeUtils.initTheme();
|
|
}
|
|
`;
|
|
|
|
fs.writeFileSync(path.join(JS_DIR, 'core-bundle.js'), coreBundle);
|
|
return coreBundle.length;
|
|
}
|
|
|
|
// Create minimal CSS bundle
|
|
function createMinimalCSS() {
|
|
console.log('Creating minimal CSS bundle...');
|
|
|
|
const cssFiles = [
|
|
'leaflet.css',
|
|
'leaflet-markercluster.css',
|
|
'leaflet-markercluster-default.css'
|
|
];
|
|
|
|
let cssBundle = '/* Minimal CSS bundle - only required styles */\n';
|
|
|
|
cssFiles.forEach(file => {
|
|
const filePath = path.join(CSS_DIR, file);
|
|
if (fs.existsSync(filePath)) {
|
|
const content = fs.readFileSync(filePath, 'utf8');
|
|
cssBundle += `\n/* ${file} */\n${content}\n`;
|
|
}
|
|
});
|
|
|
|
fs.writeFileSync(path.join(CSS_DIR, 'minimal-bundle.css'), cssBundle);
|
|
return cssBundle.length;
|
|
}
|
|
|
|
// Main optimization function
|
|
function createOptimizedBundles() {
|
|
console.log('🚀 Creating optimized JavaScript bundles...\n');
|
|
|
|
// Ensure directories exist
|
|
fs.mkdirSync(JS_DIR, { recursive: true });
|
|
fs.mkdirSync(CSS_DIR, { recursive: true });
|
|
|
|
const sizes = {
|
|
core: createCoreBundle(),
|
|
leaflet: createMinimalLeaflet(),
|
|
plugins: createOptimizedPlugins(),
|
|
chart: createMinimalChartJS(),
|
|
dateAdapter: createDateAdapter(),
|
|
css: createMinimalCSS()
|
|
};
|
|
|
|
console.log('\n📊 Optimized Bundle Sizes:');
|
|
console.log(`Core Bundle: ${(sizes.core / 1024).toFixed(2)} KB`);
|
|
console.log(`Leaflet Minimal: ${(sizes.leaflet / 1024).toFixed(2)} KB`);
|
|
console.log(`Plugins Optimized: ${(sizes.plugins / 1024).toFixed(2)} KB`);
|
|
console.log(`Chart.js Minimal: ${(sizes.chart / 1024).toFixed(2)} KB`);
|
|
console.log(`Date Adapter: ${(sizes.dateAdapter / 1024).toFixed(2)} KB`);
|
|
console.log(`CSS Minimal: ${(sizes.css / 1024).toFixed(2)} KB`);
|
|
|
|
const totalJS = sizes.core + sizes.leaflet + sizes.plugins + sizes.chart + sizes.dateAdapter;
|
|
console.log(`\n🎯 Total Optimized Size: ${(totalJS / 1024).toFixed(2)} KB JS + ${(sizes.css / 1024).toFixed(2)} KB CSS`);
|
|
|
|
return sizes;
|
|
}
|
|
|
|
// Run optimization
|
|
if (require.main === module) {
|
|
createOptimizedBundles();
|
|
}
|
|
|
|
module.exports = { createOptimizedBundles }; |