Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refine Mapbox scripts to modern ESM standards #13414

Open
michtio opened this issue Feb 24, 2025 · 2 comments
Open

Refine Mapbox scripts to modern ESM standards #13414

michtio opened this issue Feb 24, 2025 · 2 comments

Comments

@michtio
Copy link

michtio commented Feb 24, 2025

Motivation

The mapbox scripts feel very heavy, and don't comply with modern coding standards, all we see is one big chunk of code, no matter the complexity, this should be functionally programmed, and the UI layer should be taken out for the controls.

Treeshaking needs to be made available.

Since we are stubbornly being ignored in a topic where people are basically begging for a solution and to reopen, I do it this way. It's not okay to simply ignore the people using your project, while there is obviously a lot of improvements possible.

Sometimes you need to rethink and reengineer for a moment to be able to move forward again.

#6320

@netlas
Copy link

netlas commented Feb 24, 2025

+1

@navidemad
Copy link

I tried the new Claude Sonnet 3.7 Thinking LLM with the problem, here are the result if it can be useful:


Reducing Bundle Size through ESM Migration

Current Challenges

The Mapbox-GL library faces a critical issue: oversized builds that include unnecessary code for specific use cases. For instance, users who only need 2D map rendering capabilities are forced to include 3D rendering, advanced shader support, and other features they may never use.

The root causes of this problem are:

  1. Non-ESM Module Structure: The codebase doesn't leverage modern ESM standards
  2. Monolithic Architecture: Features are tightly coupled rather than modularized
  3. Limited Tree-Shaking: Current build tools cannot effectively eliminate unused code
  4. Single Entry Point: Limited options for partial imports of the library

Architecture Analysis

The first step is conducting a thorough architecture analysis to understand dependencies and identify modularization opportunities.

flowchart TD
subgraph Core["Core (Essential)"]
A[Map Rendering Engine]
B[Projection Systems]
C[Event System]
D[Basic UI Controls]
end
subgraph Features["Feature Modules"]
E[2D Rendering]
F[3D Rendering]
G[Advanced Shaders]
H[Animation System]
I[Interaction Handlers]
J[Data Processing]
K[Performance Optimizations]
end
subgraph Optional["Optional Components"]
L[Custom Layers]
M[Advanced Styling]
N[External Data Sources]
O[Terrain Rendering]
P[Globe View]
end
A --> B
A --> C
A --> E
A --> F
E --> G
F --> G
F --> O
F --> P
H --> E
H --> F
I --> C
J --> E
J --> F
K --> A
L --> A
M --> E
M --> F
N --> J
Loading

Dependency Mapping Process

1. Static Analysis Tools: Use tools like Madge to generate dependency graphs

Show summary
  mapbox-gl-js git:(main)  madge ./src/** --extensions ts --summary
Processed 586 files (5.9s) (26 warnings)

94 shaders/shaders.ts
66 render/painter.ts
65 style/style.ts
56 ui/map.ts
49 terrain/terrain.ts
48 source/tile.ts
43 data/bucket/symbol_bucket.ts
41 index.ts
34 data/bucket/fill_extrusion_bucket.ts
32 data/bucket/line_bucket.ts
31 source/worker_tile.ts
30 style-spec/expression/definitions/index.ts
29 style-spec/validate/validate.ts
28 ../3d-style/render/draw_model.ts
26 ../3d-style/render/shadow_renderer.ts
26 render/draw_symbol.ts
26 source/image_source.ts
25 render/draw_fill_extrusion.ts
24 data/bucket/circle_bucket.ts
24 data/bucket/fill_bucket.ts
24 data/feature_index.ts
24 render/draw_raster_particle.ts
24 render/program/program_uniforms.ts
24 style-spec/expression/index.ts
23 ../3d-style/data/bucket/model_bucket.ts
23 ../3d-style/data/bucket/tiled_3d_model_bucket.ts
23 data/program_configuration.ts
23 symbol/symbol_layout.ts
22 source/source.ts
22 ui/handler_manager.ts
21 geo/transform.ts
21 render/draw_raster.ts
21 source/vector_tile_source.ts
21 source/worker.ts
21 style/style_layer/symbol_style_layer.ts
20 render/program.ts
20 style/style_layer/circle_style_layer.ts
20 style/style_layer/heatmap_style_layer.ts
20 style/style_layer/line_style_layer.ts
20 symbol/placement.ts
20 terrain/draw_terrain_raster.ts
19 ../3d-style/style/style_layer/model_style_layer.ts
19 render/draw_atmosphere.ts
19 source/worker_source.ts
19 style/create_style_layer.ts
19 style/style_layer.ts
18 ../3d-style/data/model.ts
18 render/draw_circle.ts
18 source/raster_tile_source.ts
18 source/source_cache.ts
18 style-spec/style-spec.ts
18 ui/camera.ts
17 ../3d-style/source/tiled_3d_model_source.ts
17 geo/projection/globe_util.ts
17 render/draw_line.ts
17 style/fog.ts
16 render/draw_collision_debug.ts
16 render/draw_heatmap.ts
16 source/geojson_source.ts
16 style-spec/expression/parsing_context.ts
16 style/style_layer/fill_extrusion_style_layer.ts
15 ../3d-style/source/tiled_3d_model_worker_source.ts
15 data/bucket.ts
15 data/bucket/clip_bucket.ts
15 precipitation/draw_rain.ts
15 render/image_manager.ts
15 source/raster_array_tile_source.ts
15 style-spec/validate_style.min.ts
15 style/style_layer/fill_style_layer.ts
14 precipitation/draw_snow.ts
14 source/raster_dem_tile_source.ts
14 style/query_geometry.ts
13 geo/projection/globe.ts
13 gl/context.ts
13 render/draw_fill.ts
13 render/draw_hillshade.ts
13 render/draw_sky.ts
13 symbol/collision_index.ts
12 render/draw_debug.ts
12 style/style_layer/raster_particle_style_layer.ts
12 style/style_layer/sky_style_layer.ts
12 symbol/quads.ts
12 ui/marker.ts
12 util/mapbox.ts
11 ../3d-style/source/model_source.ts
11 geo/projection/index.ts
11 precipitation/vignette.ts
11 source/custom_source.ts
11 source/geojson_worker_source.ts
11 source/source_types.ts
11 style-spec/expression/definitions/coercion.ts
11 style-spec/validate/validate_source.ts
11 style/rain.ts
11 style/snow.ts
11 symbol/shaping.ts
11 ui/popup.ts
11 util/web_worker_transfer.ts
10 ../3d-style/source/model_loader.ts
10 ../3d-style/util/model_util.ts
10 render/draw_background.ts
10 render/program/hillshade_program.ts
10 source/building_index.ts
10 source/query_features.ts
10 source/vector_tile_worker_source.ts
10 style-spec/expression/definitions/interpolate.ts
10 style-spec/function/index.ts
10 style/pauseable_placement.ts
10 style/properties.ts
10 style/style_layer/raster_style_layer.ts
10 ui/control/geolocate_control.ts
9 ../3d-style/util/loaders.ts
9 render/draw_custom.ts
9 render/glyph_manager.ts
9 render/program/background_program.ts
9 render/program/circle_program.ts
9 render/program/heatmap_program.ts
9 render/program/line_program.ts
9 render/raster_particle_state.ts
9 source/raster_array_tile.ts
9 style-spec/validate/validate_function.ts
9 style-spec/validate/validate_layer.ts
9 style/light.ts
9 symbol/projection.ts
8 ../3d-style/render/model_manager.ts
8 geo/projection/projection.ts
8 precipitation/common.ts
8 render/image_rasterizer.ts
8 render/program/fill_extrusion_program.ts
8 render/program/symbol_program.ts
8 source/load_tilejson.ts
8 source/video_source.ts
8 style-spec/expression/definitions/config.ts
8 style-spec/expression/definitions/distance.ts
8 style-spec/validate/validate_filter.ts
8 style-spec/validate/validate_property.ts
8 style/style_layer/clip_style_layer.ts
8 style/style_layer/typed_style_layer.ts
8 terrain/elevation.ts
8 ui/events.ts
8 ui/handler/scroll_zoom.ts
8 ui/interactions.ts
7 ../3d-style/render/lights.ts
7 ../3d-style/render/program/model_program.ts
7 ../3d-style/source/replacement_source.ts
7 ../3d-style/style/lights.ts
7 data/debug_viz.ts
7 data/dem_data.ts
7 data/elevation_feature.ts
7 geo/projection/tile_transform.ts
7 render/image_atlas.ts
7 render/program/pattern.ts
7 style-spec/expression/definitions/comparison.ts
7 style-spec/expression/definitions/within.ts
7 style-spec/feature_filter/index.ts
7 style/load_sprite.ts
7 style/style_layer/symbol_style_layer_properties.ts
7 symbol/cross_tile_symbol_index.ts
7 symbol/symbol_size.ts
7 types/deprecated-aliases.ts
7 util/actor.ts
7 util/ajax.ts
7 util/lut.ts
6 ../3d-style/style/style_layer/model_style_layer_properties.ts
6 data/bucket/pattern_bucket_features.ts
6 data/load_geometry.ts
6 render/atmosphere_buffer.ts
6 render/fog.ts
6 render/program/collision_program.ts
6 render/program/fill_program.ts
6 render/skybox_geometry.ts
6 source/canvas_source.ts
6 source/tile_mesh.ts
6 style-spec/expression/definitions/assertion.ts
6 style-spec/expression/definitions/at.ts
6 style-spec/expression/definitions/format.ts
6 style-spec/expression/definitions/image.ts
6 style-spec/expression/definitions/in.ts
6 style-spec/expression/definitions/index_of.ts
6 style-spec/expression/definitions/length.ts
6 style-spec/expression/definitions/slice.ts
6 style-spec/expression/evaluation_context.ts
6 style-spec/validate/validate_expression.ts
6 style-spec/validate/validate_import.ts
6 style/format_section_override.ts
6 style/indoor_manager.ts
6 style/load_iconset.ts
6 style/style_layer/background_style_layer.ts
6 style/style_layer/background_style_layer_properties.ts
6 style/style_layer/circle_style_layer_properties.ts
6 style/style_layer/clip_style_layer_properties.ts
6 style/style_layer/custom_style_layer.ts
6 style/style_layer/fill_extrusion_style_layer_properties.ts
6 style/style_layer/fill_style_layer_properties.ts
6 style/style_layer/heatmap_style_layer_properties.ts
6 style/style_layer/hillshade_style_layer.ts
6 style/style_layer/hillshade_style_layer_properties.ts
6 style/style_layer/line_style_layer_properties.ts
6 style/style_layer/raster_particle_style_layer_properties.ts
6 style/style_layer/raster_style_layer_properties.ts
6 style/style_layer/sky_style_layer_properties.ts
6 style/style_layer/slot_style_layer_properties.ts
6 style/style_layer_index.ts
6 style/terrain.ts
6 util/debug.ts
5 geo/projection/adjustments.ts
5 geo/projection/albers.ts
5 geo/projection/cylindrical_equal_area.ts
5 geo/projection/equirectangular.ts
5 geo/projection/lambert.ts
5 render/cutoff.ts
5 render/program/raster_program.ts
5 render/raster_fade.ts
5 source/rtl_text_plugin.ts
5 style-spec/expression/compound_expression.ts
5 style-spec/expression/definitions/coalesce.ts
5 style-spec/expression/definitions/collator.ts
5 style-spec/expression/definitions/literal.ts
5 style-spec/expression/definitions/match.ts
5 style-spec/expression/definitions/step.ts
5 style-spec/expression/is_constant.ts
5 style-spec/expression/values.ts
5 style-spec/migrate/expressions.ts
5 style-spec/validate/validate_style.ts
5 style-spec/validate_mapbox_api_supported.ts
5 style/fog_helpers.ts
5 style/load_glyph_range.ts
5 ui/control/attribution_control.ts
5 ui/handler/touch_pan.ts
5 ui/handler_inertia.ts
5 util/dispatcher.ts
4 ../3d-style/style/ambient_light_properties.ts
4 ../3d-style/style/directional_light_properties.ts
4 ../3d-style/style/flat_light_properties.ts
4 data/segment.ts
4 data/usvg/usvg_pb_renderer.ts
4 geo/mercator_coordinate.ts
4 geo/projection/equal_earth.ts
4 geo/projection/mercator.ts
4 geo/projection/natural_earth.ts
4 geo/projection/projection_util.ts
4 geo/projection/winkel_tripel.ts
4 render/glyph_atlas.ts
4 render/vertex_array_object.ts
4 source/geojson_rt.ts
4 source/load_vector_tile.ts
4 source/pixels_to_tile_units.ts
4 source/raster_array_tile_worker_source.ts
4 source/source_state.ts
4 style-spec/expression/definitions/case.ts
4 style-spec/expression/definitions/let.ts
4 style-spec/expression/definitions/number_format.ts
4 style-spec/expression/definitions/var.ts
4 style-spec/validate/validate_formatted.ts
4 style-spec/validate/validate_image.ts
4 style-spec/validate/validate_lights.ts
4 style-spec/validate/validate_terrain.ts
4 style-spec/validate_style.ts
4 style/query_utils.ts
4 style/style_layer/slot_style_layer.ts
4 style/validate_style.ts
4 symbol/get_anchors.ts
4 symbol/transform_text.ts
4 ui/control/logo_control.ts
4 ui/control/navigation_control.ts
4 ui/free_camera.ts
4 ui/handler/box_zoom.ts
4 ui/handler/map_event.ts
4 ui/handler/touch_zoom_rotate.ts
4 util/color_ramp.ts
4 util/scheduler.ts
4 util/worker_performance_utils.ts
3 ../3d-style/style/rain_properties.ts
3 ../3d-style/style/snow_properties.ts
3 data/bucket/heatmap_bucket.ts
3 data/dem_tree.ts
3 gl/framebuffer.ts
3 gl/index_buffer.ts
3 gl/value.ts
3 gl/vertex_buffer.ts
3 render/line_atlas.ts
3 render/program/debug_program.ts
3 render/program/skybox_capture_program.ts
3 render/program/skybox_program.ts
3 render/wireframe_cache.ts
3 source/raster_dem_tile_worker_source.ts
3 source/tile_bounds.ts
3 style-spec/expression/expression.ts
3 style-spec/validate/validate_array.ts
3 style-spec/validate/validate_boolean.ts
3 style-spec/validate/validate_color.ts
3 style-spec/validate/validate_enum.ts
3 style-spec/validate/validate_fog.ts
3 style-spec/validate/validate_glyphs_url.ts
3 style-spec/validate/validate_light.ts
3 style-spec/validate/validate_model.ts
3 style-spec/validate/validate_number.ts
3 style-spec/validate/validate_object.ts
3 style-spec/validate/validate_projection.ts
3 style-spec/validate/validate_rain.ts
3 style-spec/validate/validate_snow.ts
3 style-spec/validate/validate_string.ts
3 style-spec/visit.ts
3 style/evaluation_parameters.ts
3 style/style_image.ts
3 tracked-parameters/tracked_parameters.ts
3 ui/control/fullscreen_control.ts
3 ui/control/scale_control.ts
3 ui/handler/tap_zoom.ts
3 ui/hash.ts
3 util/image.ts
3 util/performance.ts
3 util/tile_request_cache.ts
2 ../3d-style/render/program/ground_shadow_program.ts
2 ../3d-style/render/shadow_uniforms.ts
2 ../3d-style/util/conflation.ts
2 data/array_types.ts
2 data/elevation_feature_parser.ts
2 data/mrt_data.ts
2 geo/edge_insets.ts
2 geo/line_geometry.ts
2 geo/lng_lat.ts
2 geo/projection/far_z.ts
2 gl/color_mode.ts
2 precipitation/rain_program.ts
2 precipitation/snow_program.ts
2 precipitation/vignette_program.ts
2 render/program/clipping_mask_program.ts
2 render/program/occlusion_program.ts
2 render/program/raster_particle_program.ts
2 render/texture.ts
2 render/uniform_binding.ts
2 source/tile_cache.ts
2 style-spec/deref.ts
2 style-spec/diff.ts
2 style-spec/expression/stops.ts
2 style-spec/expression/types/formatted.ts
2 style-spec/expression/types/resolved_image.ts
2 style-spec/feature_filter/convert.ts
2 style-spec/function/convert.ts
2 style-spec/group_by_layout.ts
2 style-spec/migrate.ts
2 style-spec/util/color.ts
2 style-spec/util/color_spaces.ts
2 style-spec/validate/validate_layout_property.ts
2 style-spec/validate/validate_paint_property.ts
2 style/parse_glyph_pbf.ts
2 terrain/globe_raster_program.ts
2 terrain/stars_program.ts
2 terrain/terrain_raster_program.ts
2 tracked-parameters/tracked_parameters_base.ts
2 types/worker.ts
2 ui/handler.ts
2 ui/handler/click_zoom.ts
2 ui/handler/keyboard.ts
2 ui/handler/mouse.ts
2 ui/handler/shim/dblclick_zoom.ts
2 ui/handler/shim/drag_pan.ts
2 ui/handler/shim/touch_zoom_rotate.ts
2 ui/handler/tap_drag_zoom.ts
2 util/browser.ts
2 util/live_performance.ts
2 util/primitives.ts
2 util/smart_wrap.ts
2 util/triangle_grid_index.ts
2 util/util.ts
2 util/vectortile_to_geojson.ts
1 ../3d-style/data/model_attributes.ts
1 data/bounds_attributes.ts
1 data/bucket/circle_attributes.ts
1 data/bucket/dash_attributes.ts
1 data/bucket/fill_attributes.ts
1 data/bucket/fill_extrusion_attributes.ts
1 data/bucket/line_attributes.ts
1 data/bucket/line_attributes_ext.ts
1 data/bucket/line_attributes_pattern.ts
1 data/bucket/pattern_attributes.ts
1 data/bucket/symbol_attributes.ts
1 data/evaluation_feature.ts
1 data/feature_position_map.ts
1 data/index_array_type.ts
1 data/particle_attributes.ts
1 data/pos_attributes.ts
1 data/usvg/usvg_pb_decoder.ts
1 geo/projection/globe_constants.ts
1 gl/cull_face_mode.ts
1 gl/depth_mode.ts
1 gl/query.ts
1 gl/stencil_mode.ts
1 precipitation/precipitation_reveal_params.ts
1 precipitation/rain_attributes.ts
1 precipitation/snow_attributes.ts
1 precipitation/vignette_attributes.ts
1 render/atmosphere_attributes.ts
1 render/occlusion_params.ts
1 render/skybox_attributes.ts
1 render/stars_attributes.ts
1 shaders/encode_attribute.ts
1 source/geojson_wrapper.ts
1 source/tile_id.ts
1 style-spec/empty.ts
1 style-spec/expression/scope.ts
1 style-spec/expression/types/image_id_with_options.ts
1 style-spec/format.ts
1 style-spec/migrate/v8.ts
1 style-spec/migrate/v9.ts
1 style-spec/read_style.ts
1 style-spec/reference/latest.ts
1 style-spec/types.ts
1 style-spec/types/config_options.ts
1 style-spec/util/interpolate.ts
1 style-spec/util/properties.ts
1 style/style_changes.ts
1 style/style_glyph.ts
1 symbol/anchor.ts
1 symbol/check_max_angle.ts
1 symbol/mergelines.ts
1 symbol/opacity_state.ts
1 symbol/path_interpolator.ts
1 terrain/globe_attributes.ts
1 types/tilejson.ts
1 ui/handler/shim/drag_rotate.ts
1 ui/handler/tap_recognizer.ts
1 util/classify_rings.ts
1 util/eased_variable.ts
1 util/evented.ts
1 util/find_pole_of_inaccessibility.ts
1 util/intersection_tests.ts
1 util/mapbox_url.ts
1 util/polygon_clipping.ts
1 util/script_detection.ts
1 util/struct_array.ts
1 util/verticalize_punctuation.ts
1 util/web_worker.ts
1 util/worker_class.ts
1 util/worker_pool.ts
1 util/worker_pool_factory.ts
0 ../3d-style/render/texture_slots.ts
0 ../3d-style/shaders/_prelude_shadow.fragment.glsl
0 ../3d-style/shaders/_prelude_shadow.vertex.glsl
0 ../3d-style/shaders/fill_extrusion_depth.fragment.glsl
0 ../3d-style/shaders/fill_extrusion_depth.vertex.glsl
0 ../3d-style/shaders/ground_shadow.fragment.glsl
0 ../3d-style/shaders/ground_shadow.vertex.glsl
0 ../3d-style/shaders/model.fragment.glsl
0 ../3d-style/shaders/model.vertex.glsl
0 ../3d-style/shaders/model_depth.fragment.glsl
0 ../3d-style/shaders/model_depth.vertex.glsl
0 ../3d-style/util/draco_decoder_gltf.ts
0 ../3d-style/util/meshopt_decoder.ts
0 ../package.json
0 data/elevation_constants.ts
0 data/mrt/mrt.esm.js
0 geo/projection/resample.ts
0 gl/types.ts
0 render/raster.ts
0 shaders/_prelude.fragment.glsl
0 shaders/_prelude.glsl
0 shaders/_prelude.vertex.glsl
0 shaders/_prelude_fog.fragment.glsl
0 shaders/_prelude_fog.vertex.glsl
0 shaders/_prelude_lighting.glsl
0 shaders/_prelude_raster_array.glsl
0 shaders/_prelude_raster_particle.glsl
0 shaders/_prelude_terrain.vertex.glsl
0 shaders/atmosphere.fragment.glsl
0 shaders/atmosphere.vertex.glsl
0 shaders/background.fragment.glsl
0 shaders/background.vertex.glsl
0 shaders/background_pattern.fragment.glsl
0 shaders/background_pattern.vertex.glsl
0 shaders/circle.fragment.glsl
0 shaders/circle.vertex.glsl
0 shaders/clipping_mask.fragment.glsl
0 shaders/clipping_mask.vertex.glsl
0 shaders/collision_box.fragment.glsl
0 shaders/collision_box.vertex.glsl
0 shaders/collision_circle.fragment.glsl
0 shaders/collision_circle.vertex.glsl
0 shaders/debug.fragment.glsl
0 shaders/debug.vertex.glsl
0 shaders/fill.fragment.glsl
0 shaders/fill.vertex.glsl
0 shaders/fill_extrusion.fragment.glsl
0 shaders/fill_extrusion.vertex.glsl
0 shaders/fill_extrusion_ground_effect.fragment.glsl
0 shaders/fill_extrusion_ground_effect.vertex.glsl
0 shaders/fill_extrusion_pattern.fragment.glsl
0 shaders/fill_extrusion_pattern.vertex.glsl
0 shaders/fill_outline.fragment.glsl
0 shaders/fill_outline.vertex.glsl
0 shaders/fill_outline_pattern.fragment.glsl
0 shaders/fill_outline_pattern.vertex.glsl
0 shaders/fill_pattern.fragment.glsl
0 shaders/fill_pattern.vertex.glsl
0 shaders/globe_raster.fragment.glsl
0 shaders/globe_raster.vertex.glsl
0 shaders/heatmap.fragment.glsl
0 shaders/heatmap.vertex.glsl
0 shaders/heatmap_texture.fragment.glsl
0 shaders/heatmap_texture.vertex.glsl
0 shaders/hillshade.fragment.glsl
0 shaders/hillshade.vertex.glsl
0 shaders/hillshade_prepare.fragment.glsl
0 shaders/hillshade_prepare.vertex.glsl
0 shaders/line.fragment.glsl
0 shaders/line.vertex.glsl
0 shaders/line_pattern.fragment.glsl
0 shaders/line_pattern.vertex.glsl
0 shaders/occlusion.fragment.glsl
0 shaders/occlusion.vertex.glsl
0 shaders/rain_particle.fragment.glsl
0 shaders/rain_particle.vertex.glsl
0 shaders/raster.fragment.glsl
0 shaders/raster.vertex.glsl
0 shaders/raster_particle.fragment.glsl
0 shaders/raster_particle.vertex.glsl
0 shaders/raster_particle_draw.fragment.glsl
0 shaders/raster_particle_draw.vertex.glsl
0 shaders/raster_particle_texture.fragment.glsl
0 shaders/raster_particle_texture.vertex.glsl
0 shaders/raster_particle_update.fragment.glsl
0 shaders/raster_particle_update.vertex.glsl
0 shaders/skybox.fragment.glsl
0 shaders/skybox.vertex.glsl
0 shaders/skybox_capture.fragment.glsl
0 shaders/skybox_capture.vertex.glsl
0 shaders/skybox_gradient.fragment.glsl
0 shaders/snow_particle.fragment.glsl
0 shaders/snow_particle.vertex.glsl
0 shaders/stars.fragment.glsl
0 shaders/stars.vertex.glsl
0 shaders/symbol.fragment.glsl
0 shaders/symbol.vertex.glsl
0 shaders/terrain_depth.fragment.glsl
0 shaders/terrain_depth.vertex.glsl
0 shaders/terrain_raster.fragment.glsl
0 shaders/terrain_raster.vertex.glsl
0 shaders/vignette.fragment.glsl
0 shaders/vignette.vertex.glsl
0 style-spec/composite.ts
0 style-spec/data/extent.ts
0 style-spec/error/parsing_error.ts
0 style-spec/error/validation_error.ts
0 style-spec/expression/parsing_error.ts
0 style-spec/expression/runtime_error.ts
0 style-spec/expression/types.ts
0 style-spec/expression/types/collator.ts
0 style-spec/reference/v8.json
0 style-spec/types/lut.ts
0 style-spec/types/tile_id.ts
0 style-spec/union-to-intersection.ts
0 style-spec/util/deep_equal.ts
0 style-spec/util/extend.ts
0 style-spec/util/geometry_util.ts
0 style-spec/util/get_type.ts
0 style-spec/util/random.ts
0 style-spec/util/ref_properties.ts
0 style-spec/util/result.ts
0 style-spec/util/unbundle_jsonlint.ts
0 symbol/clip_line.ts
0 symbol/grid_index.ts
0 symbol/one_em.ts
0 types/callback.ts
0 types/cancelable.ts
0 types/class.ts
0 types/grid-index.ts
0 types/import-meta.d.ts
0 types/point-like.ts
0 types/transferable.ts
0 ui/anchor.ts
0 ui/default_locale.ts
0 ui/handler/handler_util.ts
0 util/config.ts
0 util/dictionary_coder.ts
0 util/dom.ts
0 util/fqid.ts
0 util/is_char_in_unicode_block.ts
0 util/lru.ts
0 util/offscreen_canvas_supported.ts
0 util/resolve_tokens.ts
0 util/sku_token.ts
0 util/task_queue.ts
0 util/throttle.ts
0 util/throttled_invoker.ts
0 util/url.ts
0 util/webp_supported.ts
  1. Import/Export Analysis: Review all import/export statements to identify module relationships
  2. Feature Categorization: Classify features into "core," "common," and "specialized" categories
  3. Circular Dependency Detection: Identify and resolve circular dependencies that would complicate modularization

ESM Migration Strategy

Converting to ESM requires a strategic approach to maintain compatibility while enabling future optimization:

1. Module Structure Design

mapbox-gl/
├── core/
│   ├── map.js
│   ├── events.js
│   ├── projection.js
│   └── index.js
├── render/
│   ├── 2d/
│   │   ├── renderer.js
│   │   └── index.js
│   ├── 3d/
│   │   ├── renderer.js
│   │   ├── terrain.js
│   │   └── index.js
│   └── index.js
├── shaders/
│   ├── basic.js
│   ├── advanced.js
│   └── index.js
├── controls/
│   ├── navigation.js
│   ├── scale.js
│   └── index.js
└── index.js

2. Export Management

// core/index.js
export { Map } from './map.js';
export { EventManager } from './events.js';
export { Projection } from './projection.js';

// No re-export of internal utilities

// render/index.js
export { Renderer2D } from './2d/index.js';
// Only export 3D if explicitly imported
// export { Renderer3D } from './3d/index.js';

// Main index.js - Full backward compatible export
export * from './core/index.js';
export * from './render/index.js';
export * from './shaders/index.js';
export * from './controls/index.js';

3. Subpath Exports Configuration

// package.json
{
  "name": "mapbox-gl",
  "type": "module",
  "exports": {
    ".": {
      "import": "./dist/esm/index.js",
      "require": "./dist/cjs/index.js"
    },
    "./core": {
      "import": "./dist/esm/core/index.js",
      "require": "./dist/cjs/core/index.js"
    },
    "./render/2d": {
      "import": "./dist/esm/render/2d/index.js",
      "require": "./dist/cjs/render/2d/index.js"
    },
    "./render/3d": {
      "import": "./dist/esm/render/3d/index.js",
      "require": "./dist/cjs/render/3d/index.js"
    },
    "./controls/*": {
      "import": "./dist/esm/controls/*.js",
      "require": "./dist/cjs/controls/*.js"
    }
  },
  "sideEffects": false
}

Modular Design Implementation

1. Feature Flag System

Implement a feature flag system to enable/disable components at build time:

// config.js
export const FEATURES = {
  ENABLE_3D: true,
  ENABLE_TERRAIN: true,
  ENABLE_ADVANCED_SHADERS: true
};

// Usage example
import { FEATURES } from '../config.js';

export class Renderer {
  constructor() {
    // Basic renderer setup
    if (FEATURES.ENABLE_3D) {
      this.setup3DCapabilities();
    }
  }

  setup3DCapabilities() {
    // Only included in builds with 3D enabled
  }
}

2. Lazy Loading Implementation

// map.js
export class Map {
  async enableTerrain() {
    if (!this.terrain) {
      // Dynamically import terrain module only when needed
      const { TerrainHandler } = await import('./terrain.js');
      this.terrain = new TerrainHandler(this);
    }
    return this.terrain;
  }
}

3. Plugin Architecture

flowchart LR
A[Core Map Object] --> B[Plugin Registry]
B --> C[Plugin Interface]
C --> D[3D Plugin]
C --> E[Terrain Plugin]
C --> F[Advanced Shader Plugin]
C --> G[Custom Layer Plugin]
Loading

Implementation example:

// plugin-system.js
export class PluginRegistry {
  constructor() {
    this.plugins = new Map();
  }

  register(name, plugin) {
    this.plugins.set(name, plugin);
    plugin.onRegister();
    return this;
  }

  get(name) {
    return this.plugins.get(name);
  }
}

// Usage
import { Map } from 'mapbox-gl/core';
import { TerrainPlugin } from 'mapbox-gl/plugins/terrain';

const map = new Map({ /* config */ });
map.plugins.register('terrain', new TerrainPlugin());

// Later use
map.plugins.get('terrain').setElevation(elevation);

Build System Modernization

1. Build Pipeline Architecture

flowchart TB
A[Source Code] --> B[ESBuild/Rollup]
B --> C{Output Formats}
C --> D[ESM Bundle]
C --> E[CommonJS Bundle]
C --> F[UMD Bundle]
G[Bundle Analyzer] --> B
H[TreeShaking] --> B
I[Minification] --> B
D --> J[Core Package]
D --> K[Feature Packages]
D --> L[Full Package]
Loading

2. Build Configuration for Multiple Entry Points

// rollup.config.js
import resolve from '@rollup/plugin-node-resolve';
import { terser } from 'rollup-plugin-terser';
import analyze from 'rollup-plugin-analyzer';

// Define the different bundles we want to create
const bundles = [
  {
    name: 'core',
    input: 'src/core/index.js',
    output: 'dist/mapbox-gl-core.js'
  },
  {
    name: 'render-2d',
    input: 'src/render/2d/index.js',
    output: 'dist/mapbox-gl-render-2d.js'
  },
  {
    name: 'render-3d',
    input: 'src/render/3d/index.js',
    output: 'dist/mapbox-gl-render-3d.js'
  },
  {
    name: 'full',
    input: 'src/index.js',
    output: 'dist/mapbox-gl.js'
  }
];

export default bundles.map(bundle => ({
  input: bundle.input,
  output: [
    {
      file: bundle.output.replace('.js', '.esm.js'),
      format: 'esm'
    },
    {
      file: bundle.output.replace('.js', '.cjs.js'),
      format: 'cjs'
    },
    {
      file: bundle.output.replace('.js', '.umd.js'),
      format: 'umd',
      name: 'mapboxgl' + (bundle.name !== 'full' ? '.' + bundle.name : '')
    }
  ],
  plugins: [
    resolve(),
    terser(),
    analyze({ summaryOnly: true })
  ]
}));

3. Side-Effects Management

Properly marking files without side effects is crucial for tree-shaking:

// package.json
{
  "sideEffects": [
    "./src/polyfills.js",
    "./src/initialize.js"
  ]
}

Practical Implementation Path

Breaking this down into achievable milestones:

gantt
title Mapbox-GL Modernization Roadmap
dateFormat YYYY-MM-DD
section Analysis
Dependency Analysis :a1, 2023-07-01, 14d
Module Boundary Definition :a2, after a1, 14d
Architecture Design :a3, after a2, 21d
section Infrastructure
Build System Setup :b1, after a3, 14d
CI/CD Integration :b2, after b1, 7d
Bundle Analysis Tools :b3, after b2, 7d
section Implementation
Core Module Conversion :c1, after b3, 30d
Render Module Separation :c2, after c1, 30d
Plugin System :c3, after c2, 21d
Feature Flagging :c4, after c3, 14d
section Testing
Test Infrastructure :d1, after c4, 14d
Compatibility Testing :d2, after d1, 21d
Performance Benchmarking :d3, after d2, 14d
section Release
Documentation :e1, after d3, 21d
Beta Release :e2, after e1, 14d
Stable Release :e3, after e2, 14d
Loading

Phase 1: Analysis & Planning (1-2 months)

  • Create comprehensive dependency maps
  • Identify module boundaries
  • Create architectural design documents
  • Establish performance metrics and benchmarks

Phase 2: Infrastructure Setup (2-4 weeks)

  • Configure build tooling (ESBuild/Rollup)
  • Set up multiple bundle outputs
  • Implement bundle analysis tools
  • Configure CI/CD for multiple builds

Phase 3: Core Refactoring (2-3 months)

  • Convert core modules to ESM
  • Implement proper exports
  • Create package entry points
  • Refactor circular dependencies

Phase 4: Feature Modularization (3-4 months)

  • Separate 2D and 3D rendering paths
  • Implement plugin architecture
  • Create feature flags system
  • Implement lazy loading for heavy components

Phase 5: Testing & Optimization (2-3 months)

  • Create comprehensive tests for each module
  • Benchmark performance of different configurations
  • Test browser compatibility
  • Optimize critical rendering paths

Backward Compatibility

To ensure a smooth transition for existing users:

1. Compatibility Layer

// compat.js - For users still using the old import style
import * as core from './core/index.js';
import * as render2d from './render/2d/index.js';
import * as render3d from './render/3d/index.js';
import * as shaders from './shaders/index.js';
import * as controls from './controls/index.js';

// Recreate the old structure
export const mapboxgl = {
  ...core,
  ...render2d,
  ...render3d,
  ...shaders,
  ...controls
};

// In UMD build, expose as global
if (typeof window !== 'undefined') {
  window.mapboxgl = mapboxgl;
}

2. Version-Specific Imports

// package.json
{
  "exports": {
    "./v1": {
      "import": "./dist/v1/index.js",
      "require": "./dist/v1/index.cjs"
    },
    "./v2": {
      "import": "./dist/v2/index.js",
      "require": "./dist/v2/index.cjs"
    }
  }
}

3. Feature Detection and Warnings

// terrain.js
export class TerrainControl {
  constructor(map) {
    // Check if 3D rendering is available
    if (!map.renderer.supports3D) {
      console.warn(
        'TerrainControl requires 3D rendering support. ' +
        'Please import the 3D renderer: import "mapbox-gl/render/3d"'
      );
      return;
    }
    // Initialize terrain control
  }
}

Performance Monitoring

Establish metrics to measure success:

1. Bundle Size Tracking

// build-analyzer.js
const fs = require('fs');
const path = require('path');
const zlib = require('zlib');

// Get all bundles
const bundles = fs.readdirSync('./dist')
  .filter(file => file.endsWith('.js'));

// Measure and report
bundles.forEach(bundle => {
  const filePath = path.join('./dist', bundle);
  const content = fs.readFileSync(filePath);
  const gzipped = zlib.gzipSync(content);
  
  console.log(`${bundle}:`);
  console.log(`  Raw size: ${(content.length / 1024).toFixed(2)} KB`);
  console.log(`  Gzipped: ${(gzipped.length / 1024).toFixed(2)} KB`);
});

2. Runtime Performance Tracking

// performance-metrics.js
export class PerformanceMonitor {
  constructor() {
    this.metrics = {};
    this.markers = {};
  }

  startMeasure(name) {
    this.markers[name] = performance.now();
  }

  endMeasure(name) {
    if (this.markers[name]) {
      const duration = performance.now() - this.markers[name];
      if (!this.metrics[name]) {
        this.metrics[name] = [];
      }
      this.metrics[name].push(duration);
      delete this.markers[name];
    }
  }

  getAverages() {
    const averages = {};
    for (const [name, measurements] of Object.entries(this.metrics)) {
      averages[name] = measurements.reduce((sum, val) => sum + val, 0) / measurements.length;
    }
    return averages;
  }
}

Community Engagement Strategy

To ensure adoption and gather feedback:

  1. RFC Process: Create a detailed RFC (Request for Comments) document outlining the modernization plan
  2. Migration Guide: Provide comprehensive documentation with examples for different use cases
  3. Preview Releases: Offer alpha/beta builds for early adopters to test
  4. Telemetry (opt-in): Add optional telemetry to understand which modules are most used
  5. Examples Repository: Create a repository with examples showcasing the new module structure

Example Migration Guide Section

1. Before

import mapboxgl from 'mapbox-gl';

const map = new mapboxgl.Map({
  container: 'map',
  style: 'mapbox://styles/mapbox/streets-v11'
});

// Add 3D terrain
map.addTerrain({ source: 'terrain' });

2. After

// Option 1: Full bundle (same as before)
import mapboxgl from 'mapbox-gl';

// Option 2: Only what you need
import { Map } from 'mapbox-gl/core';
import 'mapbox-gl/render/3d'; // Needed for terrain

const map = new Map({
  container: 'map',
  style: 'mapbox://styles/mapbox/streets-v11'
});

// Add 3D terrain (works because 3D renderer was imported)
map.addTerrain({ source: 'terrain' });

Conclusion

Modernizing Mapbox-GL for more efficient builds requires a multi-faceted approach focusing on:

  1. ESM Module Structure: Proper exports and subpath configuration
  2. Feature Modularization: Clear boundaries between core and optional features
  3. Optimized Build System: Multiple bundle outputs with effective tree-shaking
  4. Backward Compatibility: Ensure existing applications continue working
  5. Progressive Implementation: Phased approach to maintain stability

By following this roadmap, the Mapbox-GL library can significantly reduce bundle sizes for users who only need specific features, while maintaining the comprehensive capabilities for those who need them. The result will be a more efficient, flexible library that aligns with modern JavaScript best practices.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants