diff --git a/.gitignore b/.gitignore index d5dd622..d92d502 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,10 @@ aprsme-*.tar # Ignore assets that are produced by build tools. /priv/static/assets/ +# Ignore vendor JavaScript/CSS files (downloaded from CDNs) +/assets/vendor/*.js +/assets/vendor/*.css + # Ignore digested assets cache. /priv/static/cache_manifest.json diff --git a/assets/css/app.css b/assets/css/app.css index e084e31..8040096 100644 --- a/assets/css/app.css +++ b/assets/css/app.css @@ -3,6 +3,11 @@ @source "../js"; @source "../../lib/aprsme_web"; +/* Import vendor CSS files */ +@import "../vendor/leaflet.css"; +@import "../vendor/MarkerCluster.css"; +@import "../vendor/MarkerCluster.Default.css"; + /* A Tailwind plugin that makes "hero-#{ICON}" classes available. The heroicons installation itself is managed by your mix.exs */ @plugin "../vendor/heroicons"; diff --git a/assets/download-vendor-files.sh b/assets/download-vendor-files.sh new file mode 100755 index 0000000..fe5efdb --- /dev/null +++ b/assets/download-vendor-files.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +# Script to download vendor JavaScript and CSS files +# Run this from the project root: ./assets/download-vendor-files.sh + +set -e + +echo "Downloading vendor files..." + +# Ensure vendor directory exists +mkdir -p assets/vendor + +cd assets/vendor + +# Download JavaScript files +echo "Downloading Leaflet..." +curl -L -o leaflet.js https://unpkg.com/leaflet@1.9.4/dist/leaflet.js + +echo "Downloading Leaflet Heat..." +curl -L -o leaflet-heat.js https://cdn.jsdelivr.net/npm/leaflet.heat@0.2.0/dist/leaflet-heat.js + +echo "Downloading Chart.js..." +curl -L -o chart.umd.js https://cdn.jsdelivr.net/npm/chart.js@4.5.0/dist/chart.umd.js + +echo "Downloading Chart.js date adapter..." +curl -L -o chartjs-adapter-date-fns.bundle.min.js https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns@3.0.0/dist/chartjs-adapter-date-fns.bundle.min.js + +echo "Downloading Leaflet MarkerCluster..." +curl -L -o leaflet.markercluster.js https://unpkg.com/leaflet.markercluster@1.5.3/dist/leaflet.markercluster.js + +echo "Downloading OverlappingMarkerSpiderfier..." +curl -L -o oms.min.js https://cdnjs.cloudflare.com/ajax/libs/OverlappingMarkerSpiderfier-Leaflet/0.2.6/oms.min.js + +# Download CSS files +echo "Downloading Leaflet CSS..." +curl -L -o leaflet.css https://unpkg.com/leaflet@1.9.4/dist/leaflet.css + +echo "Downloading MarkerCluster CSS..." +curl -L -o MarkerCluster.css https://unpkg.com/leaflet.markercluster@1.5.3/dist/MarkerCluster.css +curl -L -o MarkerCluster.Default.css https://unpkg.com/leaflet.markercluster@1.5.3/dist/MarkerCluster.Default.css + +echo "All vendor files downloaded successfully!" +echo "Run 'mix esbuild vendor' to build the vendor bundle." \ No newline at end of file diff --git a/assets/js/vendor.js b/assets/js/vendor.js new file mode 100644 index 0000000..f198665 --- /dev/null +++ b/assets/js/vendor.js @@ -0,0 +1,23 @@ +// Vendor libraries bundle +// This file loads all external libraries and makes them available globally + +// Load Leaflet first (required by plugins) +import '../vendor/leaflet.js'; + +// Load Leaflet plugins (they expect window.L to exist) +import '../vendor/leaflet-heat.js'; +import '../vendor/leaflet.markercluster.js'; +import '../vendor/oms.min.js'; + +// Load Chart.js +import '../vendor/chart.umd.js'; + +// Load Chart.js adapter (requires Chart to be loaded first) +import '../vendor/chartjs-adapter-date-fns.bundle.min.js'; + +// Ensure global availability +if (typeof window !== 'undefined') { + // Leaflet should already be on window.L from the library + // Chart should already be on window.Chart from the library + console.log('Vendor libraries loaded: Leaflet', !!window.L, 'Chart.js', !!window.Chart); +} \ No newline at end of file diff --git a/assets/vendor/README.md b/assets/vendor/README.md new file mode 100644 index 0000000..1b6d44c --- /dev/null +++ b/assets/vendor/README.md @@ -0,0 +1,56 @@ +# Vendor JavaScript Libraries + +This directory contains third-party JavaScript and CSS libraries that are bundled locally instead of loading from CDNs. + +## Required Files + +The following files need to be downloaded: + +### JavaScript Files +- `leaflet.js` - from https://unpkg.com/leaflet@1.9.4/dist/leaflet.js +- `leaflet-heat.js` - from https://cdn.jsdelivr.net/npm/leaflet.heat@0.2.0/dist/leaflet-heat.js +- `chart.umd.js` - from https://cdn.jsdelivr.net/npm/chart.js@4.5.0/dist/chart.umd.js +- `chartjs-adapter-date-fns.bundle.min.js` - from https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns@3.0.0/dist/chartjs-adapter-date-fns.bundle.min.js +- `leaflet.markercluster.js` - from https://unpkg.com/leaflet.markercluster@1.5.3/dist/leaflet.markercluster.js +- `oms.min.js` - from https://cdnjs.cloudflare.com/ajax/libs/OverlappingMarkerSpiderfier-Leaflet/0.2.6/oms.min.js + +### CSS Files +- `leaflet.css` - from https://unpkg.com/leaflet@1.9.4/dist/leaflet.css +- `MarkerCluster.css` - from https://unpkg.com/leaflet.markercluster@1.5.3/dist/MarkerCluster.css +- `MarkerCluster.Default.css` - from https://unpkg.com/leaflet.markercluster@1.5.3/dist/MarkerCluster.Default.css + +## Download Script + +To download all vendor files, run: + +```bash +# From the project root +cd assets/vendor + +# Download JavaScript files +curl -L -o leaflet.js https://unpkg.com/leaflet@1.9.4/dist/leaflet.js +curl -L -o leaflet-heat.js https://cdn.jsdelivr.net/npm/leaflet.heat@0.2.0/dist/leaflet-heat.js +curl -L -o chart.umd.js https://cdn.jsdelivr.net/npm/chart.js@4.5.0/dist/chart.umd.js +curl -L -o chartjs-adapter-date-fns.bundle.min.js https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns@3.0.0/dist/chartjs-adapter-date-fns.bundle.min.js +curl -L -o leaflet.markercluster.js https://unpkg.com/leaflet.markercluster@1.5.3/dist/leaflet.markercluster.js +curl -L -o oms.min.js https://cdnjs.cloudflare.com/ajax/libs/OverlappingMarkerSpiderfier-Leaflet/0.2.6/oms.min.js + +# Download CSS files +curl -L -o leaflet.css https://unpkg.com/leaflet@1.9.4/dist/leaflet.css +curl -L -o MarkerCluster.css https://unpkg.com/leaflet.markercluster@1.5.3/dist/MarkerCluster.css +curl -L -o MarkerCluster.Default.css https://unpkg.com/leaflet.markercluster@1.5.3/dist/MarkerCluster.Default.css +``` + +## Building + +The vendor files are bundled using esbuild: + +```bash +# Build vendor bundle +mix esbuild vendor + +# Build with minification (for production) +mix esbuild vendor --minify +``` + +The vendor bundle is automatically included in the asset deployment pipeline. \ No newline at end of file diff --git a/config/config.exs b/config/config.exs index 9830370..664f0a0 100644 --- a/config/config.exs +++ b/config/config.exs @@ -85,6 +85,12 @@ config :esbuild, ~w(js/app.js --bundle --target=es2017 --outdir=../priv/static/assets --external:/fonts/* --external:/images/* --external:chart.js/auto --define:global.L=window.L), cd: Path.expand("../assets", __DIR__), env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)} + ], + vendor: [ + args: + ~w(js/vendor.js --bundle --target=es2017 --outdir=../priv/static/assets --minify), + cd: Path.expand("../assets", __DIR__), + env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)} ] config :gettext, :plural_forms, GettextPseudolocalize.Plural diff --git a/config/dev.exs b/config/dev.exs index 37809d2..6b3debe 100644 --- a/config/dev.exs +++ b/config/dev.exs @@ -53,6 +53,12 @@ config :aprsme, AprsmeWeb.Endpoint, :default, ~w(--sourcemap=inline --watch --loader:.ts=ts) ]}, + esbuild_vendor: + {Esbuild, :install_and_run, + [ + :vendor, + ~w(--sourcemap=inline --watch) + ]}, tailwind: {Tailwind, :install_and_run, [:default, ~w(--watch)]} ] diff --git a/lib/aprsme_web/components/layouts/root.html.heex b/lib/aprsme_web/components/layouts/root.html.heex index e583c06..f111dc2 100644 --- a/lib/aprsme_web/components/layouts/root.html.heex +++ b/lib/aprsme_web/components/layouts/root.html.heex @@ -26,41 +26,8 @@ {assigns[:page_title] || "Aprs"} - - - <%!-- Load Leaflet.heat after Leaflet is loaded --%> - - - diff --git a/lib/aprsme_web/live/map_live/index.ex b/lib/aprsme_web/live/map_live/index.ex index c8cc2d6..afb8fb7 100644 --- a/lib/aprsme_web/live/map_live/index.ex +++ b/lib/aprsme_web/live/map_live/index.ex @@ -774,24 +774,7 @@ defmodule AprsmeWeb.MapLive.Index do @impl true def render(assigns) do ~H""" - - - - - - + <%!-- All vendor libraries are now loaded from vendor.js bundle --%>