Skip to content

Commit 48c5fa1

Browse files
committed
bug #2199 [Map] Fix Google/Leaflet bridges when using Webpack Encore (Kocal)
This PR was squashed before being merged into the 2.x branch. Discussion ---------- [Map] Fix Google/Leaflet bridges when using Webpack Encore | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no <!-- please update src/**/CHANGELOG.md files --> | Issues | Fix #2105 <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead --> | License | MIT <!-- Replace this notice by a description of your feature/bugfix. This will help reviewers and should be a good start for the documentation. Additionally (see https://symfony.com/releases): - Always add tests and ensure they pass. - For new features, provide some code snippets to help understand usage. - Features and deprecations must be submitted against branch main. - Changelog entry should follow https://symfony.com/doc/current/contributing/code/conventions.html#writing-a-changelog-entry - Never break backward compatibility (see https://symfony.com/bc). --> This PR fixes #2105, and ensures Leaflet and GoogleMaps bridges are working fine with Webpack Encore. To be sure: 1. I've created a new Symfony app (no `--webapp`), 2. Installed Encore, Stimulus, and Map 3. Added `.addAliases({ 'leaflet/dist/leaflet.min.css': 'leaflet/dist/leaflet.css' })` and `.enableStimulusBridge('./assets/controllers.json')` in `webpack.config.js` 4. Created the Map (`new Map()`) and rendered it (`ux_map(map, { style: 'height: ...' })`) I am able to display a Leaflet map: <img width="1568" alt="image" src="https://github.com/user-attachments/assets/0a44eb8e-8346-452a-9598-2774af17f0ad"> And a GoogleMap maps: <img width="1537" alt="image" src="https://github.com/user-attachments/assets/2fae715e-fa2d-41c3-a566-886a340f9c1d"> --- The Map rendered on ux.symfony.com is also working (after updating the `importmap.php` as documented): <img width="1543" alt="image" src="https://github.com/user-attachments/assets/c869cad6-e48b-4c24-8ea3-490e7109a05d"> Commits ------- b3283f4 [Site] Adjust importmap.php due to last changes on Map 0d1bc8b [Map] Fix Google/Leaflet bridges when using Webpack Encore
2 parents 365dd97 + b3283f4 commit 48c5fa1

16 files changed

+142
-22
lines changed

src/Map/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
- Add `ux_map` Twig function (replaces `render_map` with a more flexible
88
interface)
99
- Add `<twig:ux:map />` Twig component
10+
- The importmap entry `@symfony/ux-map/abstract-map-controller` can be removed
11+
from your importmap, it is no longer needed.
1012

1113
## 2.19
1214

src/Map/assets/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88
"types": "dist/abstract_map_controller.d.ts",
99
"symfony": {
1010
"importmap": {
11-
"@hotwired/stimulus": "^3.0.0",
12-
"@symfony/ux-map/abstract-map-controller": "path:%PACKAGE%/dist/abstract_map_controller.js"
11+
"@hotwired/stimulus": "^3.0.0"
1312
}
1413
},
1514
"peerDependencies": {
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# CHANGELOG
22

3+
## 2.20
4+
5+
### BC Breaks
6+
7+
- Renamed importmap entry `@symfony/ux-google-map/map-controller` to `@symfony/ux-google-map`,
8+
you will need to update your importmap.
9+
310
## 2.19
411

512
- Bridge added

src/Map/src/Bridge/Google/assets/dist/map_controller.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import AbstractMapController from '@symfony/ux-map/abstract-map-controller';
2-
import type { Point, MarkerDefinition } from '@symfony/ux-map/abstract-map-controller';
1+
import AbstractMapController from '@symfony/ux-map';
2+
import type { Point, MarkerDefinition } from '@symfony/ux-map';
33
import type { LoaderOptions } from '@googlemaps/js-api-loader';
44
type MapOptions = Pick<google.maps.MapOptions, 'mapId' | 'gestureHandling' | 'backgroundColor' | 'disableDoubleClickZoom' | 'zoomControl' | 'zoomControlOptions' | 'mapTypeControl' | 'mapTypeControlOptions' | 'streetViewControl' | 'streetViewControlOptions' | 'fullscreenControl' | 'fullscreenControlOptions'>;
55
export default class extends AbstractMapController<MapOptions, google.maps.Map, google.maps.marker.AdvancedMarkerElement, google.maps.InfoWindow> {

src/Map/src/Bridge/Google/assets/dist/map_controller.js

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,48 @@
1-
import AbstractMapController from '@symfony/ux-map/abstract-map-controller';
1+
import { Controller } from '@hotwired/stimulus';
22
import { Loader } from '@googlemaps/js-api-loader';
33

4+
let default_1$1 = class default_1 extends Controller {
5+
constructor() {
6+
super(...arguments);
7+
this.markers = [];
8+
this.infoWindows = [];
9+
}
10+
connect() {
11+
const { center, zoom, options, markers, fitBoundsToMarkers } = this.viewValue;
12+
this.dispatchEvent('pre-connect', { options });
13+
this.map = this.doCreateMap({ center, zoom, options });
14+
markers.forEach((marker) => this.createMarker(marker));
15+
if (fitBoundsToMarkers) {
16+
this.doFitBoundsToMarkers();
17+
}
18+
this.dispatchEvent('connect', {
19+
map: this.map,
20+
markers: this.markers,
21+
infoWindows: this.infoWindows,
22+
});
23+
}
24+
createMarker(definition) {
25+
this.dispatchEvent('marker:before-create', { definition });
26+
const marker = this.doCreateMarker(definition);
27+
this.dispatchEvent('marker:after-create', { marker });
28+
this.markers.push(marker);
29+
return marker;
30+
}
31+
createInfoWindow({ definition, marker, }) {
32+
this.dispatchEvent('info-window:before-create', { definition, marker });
33+
const infoWindow = this.doCreateInfoWindow({ definition, marker });
34+
this.dispatchEvent('info-window:after-create', { infoWindow, marker });
35+
this.infoWindows.push(infoWindow);
36+
return infoWindow;
37+
}
38+
};
39+
default_1$1.values = {
40+
providerOptions: Object,
41+
view: Object,
42+
};
43+
444
let _google;
5-
class default_1 extends AbstractMapController {
45+
class default_1 extends default_1$1 {
646
async connect() {
747
if (!_google) {
848
_google = { maps: {} };

src/Map/src/Bridge/Google/assets/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"importmap": {
1919
"@hotwired/stimulus": "^3.0.0",
2020
"@googlemaps/js-api-loader": "^1.16.6",
21-
"@symfony/ux-google-map/map-controller": "path:%PACKAGE%/dist/map_controller.js"
21+
"@symfony/ux-google-map": "path:%PACKAGE%/dist/map_controller.js"
2222
}
2323
},
2424
"peerDependencies": {

src/Map/src/Bridge/Google/assets/src/map_controller.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
* file that was distributed with this source code.
88
*/
99

10-
import AbstractMapController from '@symfony/ux-map/abstract-map-controller';
11-
import type { Point, MarkerDefinition } from '@symfony/ux-map/abstract-map-controller';
10+
import AbstractMapController from '@symfony/ux-map';
11+
import type { Point, MarkerDefinition } from '@symfony/ux-map';
1212
import type { LoaderOptions } from '@googlemaps/js-api-loader';
1313
import { Loader } from '@googlemaps/js-api-loader';
1414

src/Map/src/Bridge/Google/assets/vitest.config.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export default mergeConfig(
66
defineConfig({
77
resolve: {
88
alias: {
9-
'@symfony/ux-map/abstract-map-controller': __dirname + '/../../../../assets/src/abstract_map_controller.ts',
9+
'@symfony/ux-map': __dirname + '/../../../../assets/src/abstract_map_controller.ts',
1010
},
1111
},
1212
define: {
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# CHANGELOG
22

3+
## 2.20
4+
5+
### BC Breaks
6+
7+
- Renamed importmap entry `@symfony/ux-leaflet-map/map-controller` to `@symfony/ux-leaflet-map`,
8+
you will need to update your importmap.
9+
310
## 2.19
411

512
- Bridge added

src/Map/src/Bridge/Leaflet/README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,34 @@ export default class extends Controller
9090
}
9191
```
9292

93+
## Known issues
94+
95+
### Unable to find `leaflet/dist/leaflet.min.css` file when using Webpack Encore
96+
97+
When using Webpack Encore with the Leaflet bridge, you may encounter the following error:
98+
```
99+
Module build failed: Module not found:
100+
"./node_modules/.pnpm/file+vendor+symfony+ux-leaflet-map+assets_@hotwired+stimulus@3.0.0_leaflet@1.9.4/node_modules/@symfony/ux-leaflet-map/dist/map_controller.js" contains a reference to the file "leaflet/dist/leaflet.min.css".
101+
This file can not be found, please check it for typos or update it if the file got moved.
102+
103+
Entrypoint app = runtime.67292354.js 488.0777101a.js app.b75294ae.css app.0975a86d.js
104+
webpack compiled with 1 error
105+
 ELIFECYCLE  Command failed with exit code 1.
106+
```
107+
108+
That's because the Leaflet's Stimulus controller references the `leaflet/dist/leaflet.min.css` file,
109+
which exists on [jsDelivr](https://www.jsdelivr.com/package/npm/leaflet) (used by the Symfony AssetMapper component),
110+
but does not in the [`leaflet` npm package](https://www.npmjs.com/package/leaflet).
111+
The correct path is `leaflet/dist/leaflet.css`, but it is not possible to fix it because it would break compatibility
112+
with the Symfony AssetMapper component.
113+
114+
As a workaround, you can configure Webpack Encore to add an alias for the `leaflet/dist/leaflet.min.css` file:
115+
```js
116+
Encore.addAliases({
117+
'leaflet/dist/leaflet.min.css': 'leaflet/dist/leaflet.css',
118+
})
119+
```
120+
93121
## Resources
94122

95123
- [Documentation](https://symfony.com/bundles/ux-map/current/index.html)

src/Map/src/Bridge/Leaflet/assets/dist/map_controller.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import AbstractMapController from '@symfony/ux-map/abstract-map-controller';
2-
import type { Point, MarkerDefinition } from '@symfony/ux-map/abstract-map-controller';
1+
import AbstractMapController from '@symfony/ux-map';
2+
import type { Point, MarkerDefinition } from '@symfony/ux-map';
33
import 'leaflet/dist/leaflet.min.css';
44
import * as L from 'leaflet';
55
import type { MapOptions as LeafletMapOptions, MarkerOptions, PopupOptions } from 'leaflet';

src/Map/src/Bridge/Leaflet/assets/dist/map_controller.js

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,48 @@
1-
import AbstractMapController from '@symfony/ux-map/abstract-map-controller';
1+
import { Controller } from '@hotwired/stimulus';
22
import 'leaflet/dist/leaflet.min.css';
33
import * as L from 'leaflet';
44

5-
class map_controller extends AbstractMapController {
5+
class default_1 extends Controller {
6+
constructor() {
7+
super(...arguments);
8+
this.markers = [];
9+
this.infoWindows = [];
10+
}
11+
connect() {
12+
const { center, zoom, options, markers, fitBoundsToMarkers } = this.viewValue;
13+
this.dispatchEvent('pre-connect', { options });
14+
this.map = this.doCreateMap({ center, zoom, options });
15+
markers.forEach((marker) => this.createMarker(marker));
16+
if (fitBoundsToMarkers) {
17+
this.doFitBoundsToMarkers();
18+
}
19+
this.dispatchEvent('connect', {
20+
map: this.map,
21+
markers: this.markers,
22+
infoWindows: this.infoWindows,
23+
});
24+
}
25+
createMarker(definition) {
26+
this.dispatchEvent('marker:before-create', { definition });
27+
const marker = this.doCreateMarker(definition);
28+
this.dispatchEvent('marker:after-create', { marker });
29+
this.markers.push(marker);
30+
return marker;
31+
}
32+
createInfoWindow({ definition, marker, }) {
33+
this.dispatchEvent('info-window:before-create', { definition, marker });
34+
const infoWindow = this.doCreateInfoWindow({ definition, marker });
35+
this.dispatchEvent('info-window:after-create', { infoWindow, marker });
36+
this.infoWindows.push(infoWindow);
37+
return infoWindow;
38+
}
39+
}
40+
default_1.values = {
41+
providerOptions: Object,
42+
view: Object,
43+
};
44+
45+
class map_controller extends default_1 {
646
connect() {
747
L.Marker.prototype.options.icon = L.divIcon({
848
html: '<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" fill-rule="evenodd" stroke-linecap="round" clip-rule="evenodd" viewBox="0 0 500 820"><defs><linearGradient id="__sf_ux_map_gradient_marker_fill" x1="0" x2="1" y1="0" y2="0" gradientTransform="matrix(0 -37.57 37.57 0 416.45 541)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#126FC6"/><stop offset="1" stop-color="#4C9CD1"/></linearGradient><linearGradient id="__sf_ux_map_gradient_marker_border" x1="0" x2="1" y1="0" y2="0" gradientTransform="matrix(0 -19.05 19.05 0 414.48 522.49)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#2E6C97"/><stop offset="1" stop-color="#3883B7"/></linearGradient></defs><circle cx="252.31" cy="266.24" r="83.99" fill="#fff"/><path fill="url(#__sf_ux_map_gradient_marker_fill)" stroke="url(#__sf_ux_map_gradient_marker_border)" stroke-width="1.1" d="M416.54 503.61c-6.57 0-12.04 5.7-12.04 11.87 0 2.78 1.56 6.3 2.7 8.74l9.3 17.88 9.26-17.88c1.13-2.43 2.74-5.79 2.74-8.74 0-6.18-5.38-11.87-11.96-11.87Zm0 7.16a4.69 4.69 0 1 1-.02 9.4 4.69 4.69 0 0 1 .02-9.4Z" transform="translate(-7889.1 -9807.44) scale(19.54)"/></svg>',

src/Map/src/Bridge/Leaflet/assets/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"importmap": {
1919
"@hotwired/stimulus": "^3.0.0",
2020
"leaflet": "^1.9.4",
21-
"@symfony/ux-leaflet-map/map-controller": "path:%PACKAGE%/dist/map_controller.js"
21+
"@symfony/ux-leaflet-map": "path:%PACKAGE%/dist/map_controller.js"
2222
}
2323
},
2424
"peerDependencies": {

src/Map/src/Bridge/Leaflet/assets/src/map_controller.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import AbstractMapController from '@symfony/ux-map/abstract-map-controller';
2-
import type { Point, MarkerDefinition } from '@symfony/ux-map/abstract-map-controller';
1+
import AbstractMapController from '@symfony/ux-map';
2+
import type { Point, MarkerDefinition } from '@symfony/ux-map';
33
import 'leaflet/dist/leaflet.min.css';
44
import * as L from 'leaflet';
55
import type { MapOptions as LeafletMapOptions, MarkerOptions, PopupOptions } from 'leaflet';

src/Map/src/Bridge/Leaflet/assets/vitest.config.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export default mergeConfig(
66
defineConfig({
77
resolve: {
88
alias: {
9-
'@symfony/ux-map/abstract-map-controller': __dirname + '/../../../../assets/src/abstract_map_controller.ts',
9+
'@symfony/ux-map': __dirname + '/../../../../assets/src/abstract_map_controller.ts',
1010
'leaflet/dist/leaflet.min.css': 'leaflet/dist/leaflet.css',
1111
},
1212
},

ux.symfony.com/importmap.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -190,17 +190,14 @@
190190
'chart.js' => [
191191
'version' => '4.4.3',
192192
],
193-
'@symfony/ux-map/abstract-map-controller' => [
194-
'path' => './vendor/symfony/ux-map/assets/dist/abstract_map_controller.js',
195-
],
196193
'leaflet' => [
197194
'version' => '1.9.4',
198195
],
199196
'leaflet/dist/leaflet.min.css' => [
200197
'version' => '1.9.4',
201198
'type' => 'css',
202199
],
203-
'@symfony/ux-leaflet-map/map-controller' => [
200+
'@symfony/ux-leaflet-map' => [
204201
'path' => './vendor/symfony/ux-leaflet-map/assets/dist/map_controller.js',
205202
],
206203
];

0 commit comments

Comments
 (0)