Coder Social home page Coder Social logo

Comments (8)

Raruto avatar Raruto commented on June 15, 2024 1

Hi Fabian,

in this regard I did a quick test in the past.

You can found it listed within the FAQs:

3. How can I import this library as ES module?

Usually, when working with a js bundler like Vite or Webpack, you need to provide to this library the full path to some dynamically imported files from the srcFolder:

import './your-custom-style.css';
import 'leaflet/dist/leaflet.css';
import L from 'leaflet';
import '@raruto/leaflet-elevation/src/index.js';
import '@raruto/leaflet-elevation/src/index.css';

const map = L.map('map', {
    center: [41.4583, 12.7059]
    zoom: 5,
});

const controlElevation = L.control.elevation({
    // CHANGE ME: with your own http server folder (eg. "http://custom-server/public/path/to/leaflet-elevation/src/")
    srcFolder: 'http://unpkg.com/@raruto/leaflet-elevation/src/'
}).addTo(map);

// Load track from url (allowed data types: "*.geojson", "*.gpx", "*.tcx")
controlElevation.load("https://raruto.github.io/leaflet-elevation/examples/via-emilia.gpx");

All external dependencies are lazy loaded (by default from unpkg.com) if they are not found within the HTML page before running the leaflet-elevation script (e.g. togoejson, d3js, ..)

👋 Raruto

from leaflet-elevation.

Raruto avatar Raruto commented on June 15, 2024 1

Do I need to configure my webpack?

I'd say it shouldn't be necessary, if you're able to disable lazy loading completely.

Probably the sample code mentioned in the FAQ was tested with Vite (which is overall easier to set up).


Can I import the handlers by myself?

Just prevent the lazy loading logic by providing your own handlers, it should be something like following:

import { Distance } from "@raruto/leaflet-elevation/src/handlers/distance.js";
import { Time } from "@raruto/leaflet-elevation/src/handlers/time.js"
...
  handlers: [
    Distance,
    Time,
    ...
  ]

Original source: #229 (comment)


If you still have problems, try to expose them globally as well:

import { Distance } from "@raruto/leaflet-elevation/src/handlers/distance.js";
import { Time } from "@raruto/leaflet-elevation/src/handlers/time.js"
import '@raruto/leaflet-elevation/src/index.js';

...

L.Control.Elevation.Distance = Distance;
L.Control.Elevation.Time = Time;

...

const controlElevation = L.control.elevation({ ... }).addTo(map);

Related source:

_loadModules(handlers) {
// First map known classnames (eg. "Altitude" --> L.Control.Elevation.Altitude)
handlers = handlers.map((h) => typeof h === 'string' && typeof Elevation[h] !== "undefined" ? Elevation[h] : h);
// Then load optional classes and custom imports (eg. "Cadence" --> import('../src/handlers/cadence.js'))
let modules = handlers.map(file => (typeof file === 'string' && this.import(this.__modulesFolder + file.toLowerCase() + '.js')) || (file instanceof Promise && file) || Promise.resolve());
return Promise.all(modules).then((m) => {
_.each(m, (exported, i) => {
let fn = exported && Object.keys(exported)[0];
if (fn) {
handlers[i] = Elevation[fn] = (Elevation[fn] ?? exported[fn]);
}
});
_.each(handlers, h => ["function", "object"].includes(typeof h) && this._registerHandler(h));
});
},


If I add the following comment /* webpackIgnore: true */ in here, everything works with the lazy loading.

Maybe this should be added in a PR?

Within your local code (to apply some patch or quick test), you can always monkey patch any native functionality through the L.Control.Elevation.include().

For more info: old issues

👋 Raruto

from leaflet-elevation.

FabianSchmick avatar FabianSchmick commented on June 15, 2024

Hi @Raruto

Thank you for your quick reply. I didn't see the FAQs. But with your answer, I could resolve the first error:

Uncaught (in promise) Error: Cannot find module 'https://unpkg.com/@tmcw/[email protected]/dist/togeojson.umd.js'

The solution was:

import * as L from 'leaflet';
import * as d3 from 'd3';
global.d3 = d3;
import * as toGeoJSON from '@tmcw/togeojson';
global.toGeoJSON = toGeoJSON;
import 'leaflet-geometryutil';
import 'leaflet-almostover';

But I still have the other error

Uncaught (in promise) Error: Cannot find module 'http://localhost/src/handlers/distance.js'

The file is also public, available at http://localhost/src/handlers/distance.js
Can I import the handlers by myself and don't use the lazy loading? Or do I need to configure my webpack for this?


If I import the handlers by myself like:

import '@raruto/leaflet-elevation/src/handlers/distance.js';
import '@raruto/leaflet-elevation/src/handlers/time.js';
import '@raruto/leaflet-elevation/src/handlers/altitude.js';
import '@raruto/leaflet-elevation/src/handlers/slope.js';
import '@raruto/leaflet-elevation/src/handlers/speed.js';
import '@raruto/leaflet-elevation/src/handlers/acceleration.js';

It also results in the same error
And if I empty the handlers:

const controlElevation = L.control.elevation({
    handlers: []
}).addTo(map);

I get the error

Uncaught (in promise) Error: Cannot find module 'http://localhost/src/components/summary.js'

from leaflet-elevation.

hupe13 avatar hupe13 commented on June 15, 2024

Maybe this syntax helps:

handlers: [
...L.Control.Elevation.prototype.options.handlers, // built-in handlers
'Labels' // same as: import('https://unpkg.com/@raruto/leaflet-elevation/src/handlers/labels.js')

from leaflet-elevation.

FabianSchmick avatar FabianSchmick commented on June 15, 2024

If I add the following comment /* webpackIgnore: true */ in here:

return condition !== false
  ? import(/* webpackIgnore: true */ _.resolveURL(src, this.options.srcFolder))
  : Promise.resolve();

Everything works with the lazy loading.


Got the comment from webpack/webpack#8341 (comment) maybe this should be added in a PR?

Explanation from https://stackoverflow.com/a/56998596/5947371:

Webpack reinterprets the standard ES import statement. Within a standard webpack config, webpack uses this statement as a split point for bundles, so even modules that are dynamically imported are expected to be there at webpack build time (and the build process will fail if they are not available)

from leaflet-elevation.

FabianSchmick avatar FabianSchmick commented on June 15, 2024

@Raruto thank you for your support and help.

I try to prevent the lazy loading logic by providing my own handlers as you suggested. This works for the files in the handlers directory. For the files in the components directory, it will not work, as they still try to get lazy loaded.

But I will stick to the second approach and monkey patch the import function with the specific webpack comment 👍🏼 thank you again for the useful tips :)

from leaflet-elevation.

Raruto avatar Raruto commented on June 15, 2024

Ok @FabianSchmick.

When you're done, just to facilitate the searching job for those who will come later, remember to post your final code snippet as well.

😉 Raruto

from leaflet-elevation.

FabianSchmick avatar FabianSchmick commented on June 15, 2024

Final code:

import * as L from 'leaflet';
import * as d3 from 'd3';
global.d3 = d3;
import * as toGeoJSON from '@tmcw/togeojson';
global.toGeoJSON = toGeoJSON;
import 'leaflet-geometryutil';
import 'leaflet-almostover';
import '@raruto/leaflet-gesture-handling/dist/leaflet-gesture-handling';
import '@raruto/leaflet-elevation/libs/leaflet-edgescale.min.js';
import * as _ from '@raruto/leaflet-elevation/src/utils';
import '@raruto/leaflet-elevation/dist/leaflet-elevation';

let map = L.map('map', {
    center: [41.4583, 12.7059],
    zoom: 5,
});

L.tileLayer('https://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png', {
    maxZoom: 18,
    attribution: 'Data &copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap contributors</a>'
}).addTo(map);

// Monkey patch the import function -> https://leafletjs.com/examples/extending/extending-1-classes.html#lclassinclude
L.Control.Elevation.include({

    import: function(src, condition) {
        if (Array.isArray(src)) {
            return Promise.all(src.map(m => this.import(m)));
        }
        switch(src) {
            case this.__D3:          condition = typeof d3 !== 'object'; break;
            case this.__TOGEOJSON:   condition = typeof toGeoJSON !== 'object'; break;
            case this.__LGEOMUTIL:   condition = typeof L.GeometryUtil !== 'object'; break;
            case this.__LALMOSTOVER: condition = typeof L.Handler.AlmostOver  !== 'function'; break;
            case this.__LDISTANCEM:  condition = typeof L.DistanceMarkers  !== 'function'; break;
            case this.__LEDGESCALE:  condition = typeof L.Control.EdgeScale !== 'function'; break;
            case this.__LHOTLINE:    condition = typeof L.Hotline  !== 'function'; break;
        }

        // Add the ignore comment for webpack
        return condition !== false ? import(/* webpackIgnore: true */ _.resolveURL(src, this.options.srcFolder)) : Promise.resolve();
    }

});

const controlElevation = L.control.elevation().addTo(map);
controlElevation.load('https://raruto.github.io/leaflet-elevation/examples/via-emilia.gpx');

Last step, configure webpack to copy the node_modules/@raruto/leaflet-elevation/src directory to your public project directory, so the lazy loading can find the requested files.

from leaflet-elevation.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.