Bundle all vendor JavaScript files locally instead of loading from CDNs
This change eliminates all external CDN dependencies by bundling JavaScript libraries locally using esbuild. All vendor files are now served from the application's own assets, improving reliability and privacy. Changes: - Created assets/js/vendor.js to bundle all external libraries - Added vendor bundle configuration to esbuild in config files - Updated all templates to use local vendor.js instead of CDN scripts - Created download-vendor-files.sh script to fetch vendor libraries - Added vendor files to .gitignore (they're downloaded during setup) - Updated CSS imports to include vendor stylesheets - Added vendor build step to assets.deploy mix task Bundled libraries: - Leaflet 1.9.4 (mapping library) - Leaflet.heat 0.2.0 (heatmap plugin) - Leaflet.markercluster 1.5.3 (marker clustering) - OverlappingMarkerSpiderfier 0.2.6 (overlapping marker handling) - Chart.js 4.5.0 (charting library) - chartjs-adapter-date-fns 3.0.0 (date adapter for Chart.js) All functionality tested and working correctly with local bundles. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
a8e7b17ee1
commit
7dc6c616a2
11 changed files with 148 additions and 59 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
43
assets/download-vendor-files.sh
Executable file
43
assets/download-vendor-files.sh
Executable file
|
|
@ -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."
|
||||
23
assets/js/vendor.js
Normal file
23
assets/js/vendor.js
Normal file
|
|
@ -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);
|
||||
}
|
||||
56
assets/vendor/README.md
vendored
Normal file
56
assets/vendor/README.md
vendored
Normal file
|
|
@ -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.
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)]}
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -26,41 +26,8 @@
|
|||
{assigns[:page_title] || "Aprs"}
|
||||
</.live_title>
|
||||
<link phx-track-static rel="stylesheet" href={~p"/assets/css/app.css"} />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
|
||||
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
|
||||
crossorigin=""
|
||||
/>
|
||||
<script
|
||||
defer
|
||||
phx-track-static
|
||||
type="text/javascript"
|
||||
src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
|
||||
data-source-map="false"
|
||||
>
|
||||
</script>
|
||||
<%!-- Load Leaflet.heat after Leaflet is loaded --%>
|
||||
<script
|
||||
defer
|
||||
phx-track-static
|
||||
type="text/javascript"
|
||||
src="https://cdn.jsdelivr.net/npm/leaflet.heat@0.2.0/dist/leaflet-heat.js"
|
||||
>
|
||||
</script>
|
||||
<script
|
||||
defer
|
||||
phx-track-static
|
||||
type="text/javascript"
|
||||
src="https://cdn.jsdelivr.net/npm/chart.js@4.5.0/dist/chart.umd.js"
|
||||
>
|
||||
</script>
|
||||
<script
|
||||
defer
|
||||
phx-track-static
|
||||
type="text/javascript"
|
||||
src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns@3.0.0/dist/chartjs-adapter-date-fns.bundle.min.js"
|
||||
>
|
||||
<%!-- Vendor libraries are now bundled locally --%>
|
||||
<script defer phx-track-static type="text/javascript" src={~p"/assets/vendor.js"}>
|
||||
</script>
|
||||
<script defer phx-track-static type="text/javascript" src={~p"/assets/app.js"}>
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -774,24 +774,7 @@ defmodule AprsmeWeb.MapLive.Index do
|
|||
@impl true
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
|
||||
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
|
||||
crossorigin=""
|
||||
/>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.5.3/dist/MarkerCluster.css" />
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.5.3/dist/MarkerCluster.Default.css" />
|
||||
<script
|
||||
src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
|
||||
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
|
||||
crossorigin=""
|
||||
>
|
||||
</script>
|
||||
<script src="https://unpkg.com/leaflet.markercluster@1.5.3/dist/leaflet.markercluster.js">
|
||||
</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/OverlappingMarkerSpiderfier-Leaflet/0.2.6/oms.min.js">
|
||||
</script>
|
||||
<%!-- All vendor libraries are now loaded from vendor.js bundle --%>
|
||||
|
||||
<style>
|
||||
#aprs-map {
|
||||
|
|
|
|||
|
|
@ -230,12 +230,7 @@
|
|||
<canvas></canvas>
|
||||
</div>
|
||||
<% end %>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.5.0/dist/chart.umd.js">
|
||||
</script>
|
||||
<script
|
||||
src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns@3.0.0/dist/chartjs-adapter-date-fns.bundle.min.js"
|
||||
>
|
||||
</script>
|
||||
<%!-- Chart.js and adapter are now loaded from vendor.js bundle --%>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
1
mix.exs
1
mix.exs
|
|
@ -136,6 +136,7 @@ defmodule Aprsme.MixProject do
|
|||
"assets.deploy": [
|
||||
"tailwind default --minify",
|
||||
"esbuild default --minify",
|
||||
"esbuild vendor --minify",
|
||||
"phx.digest"
|
||||
]
|
||||
]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue