3
votes

I'm currently trying to load a Leaflet map in a personal project. but my code does not execute because of an import problem. i installed leaflet type definitions with the following command

npm install --save @types/leaflet

it has one dependency so ive installed geojson too

npm install --save @types/geojson

this is part of my tsconfig.json file

{
  "compilerOptions": {
    "typeRoots": ["node_modules/@types"],
    "rootDir": ".",
    "outDir": "build",
    "target": "es2018",
    "lib": [
      "es2018",
      "dom"
    ],
    "types": [
      "leaflet",
      "geojson"
    ]
  },
  "include": [
    "src/**/*.ts"
  ],
  "exclude": [
    "node_modules"
  ]
}

i'm following the basic example in the documentation of leaflet, but instead of writing inline code i made a class.

this is a part of the index where i load all my js files, the map div is inside the body (not shown here).

<link rel="stylesheet" type="text/css" href="ts\node_modules\leaflet\dist\leaflet.css">
<script src="ts\node_modules\leaflet\dist\leaflet.js"></script>
<script src="./ts/build/src/mapsmanager.js" type="module"></script>

<script type="module">
  // Import classes
  import { MapsManager } from './ts/build/src/mapsmanager.js';

  initialize();

  function initialize()
  {
    /* ADD MAP SCRIPT */ 
    let mapsman = new MapsManager();
  } 
</script>

this is my mapsmanager.ts file where i get the error from

import * as Leaf from 'leaflet';

export class MapsManager
{
/*DO STUFF*/
}

this line

import * as Leaf from 'leaflet';

gives me the following runtime error:

TypeError: Error resolving module specifier: leaflet

i've also tried to load leaflet as a module

<script src="ts\node_modules\leaflet\dist\leaflet.js" type="module"></script>

but it didn't work, it gave me another runtime error:

TypeError: t is undefined (inside leaflet.js)

IMPORTANT without using classes and by using inline JS inside the index the map works fine. it has probably something to do with the project configuration/declarations/definitions/modules stuff or maybe even leaflet.

this is part of my package.json

  "files": [
    "build",
    "src"
  ],
  "devDependencies": {
    "gts": "^2.0.0",
    "typescript": "~3.8.0",
    "@types/node": "^10.0.3"
  },
  "dependencies": {
    "@types/geojson": "^7946.0.7",
    "@types/leaflet": "^1.5.12",
    "leaflet": "^1.6.0"
  }

I've also tried to add a index.d.ts file where i put a declaration of the leaflet module because before leaflet i tried to use Google Maps JS API which uses this method but it didn't work.

I hope my description of the problem have been exhaustive

1
import L from 'leaflet'; does not work?kboul
@kboul unfortunatly no, there is no default exportPrometeoPrime
Have you installed leaflet, besides the types? What does your package.json look like?ghybs
@ghybs I have installed it, but currently i was trying to download the CSS and JS from their repository. i could try making it work locally, i will add my package.json to my question. i will update you ASAPPrometeoPrime
even by adding leaflet locally in the index with <link rel="stylesheet" type="text/css" href="ts\node_modules\leaflet\dist\leaflet.css"> <script src="ts\node_modules\leaflet\dist\leaflet.js"></script> i get the same error. might be a problem with the setup of the project?PrometeoPrime

1 Answers

1
votes

The issue is very probably caused by the 2 different uses of import in your architecture:

  1. As TypeScript import (for both the library and automatically resolved corresponding types)
  2. As in browser script module import

For TypeScript transpilation step, the transpiler knows that an absolute path ("leaflet") can be in your project "node_modules" folder.

But that is not the case for in browser module import: here you need to specify the exact (may be relative) path to your file (or at least the location of the module package.json file), similarly to what you would have specified in the src attribute of a <script> tag.

In this case, you have to modify the "import leaflet" path so that the final JS file has correct path.

Since that would probably break the step 1 TypeScript, you then need to update your tsconfig to tell TypeScript how to resolve that path. See e.g. TypeScript Import Path Alias

Note: usually this is not an issue because very few people actually use in browser module import, but instead use a build engine (which can encompass the TypeScript transpilation step) which bundles all JS in a single file (e.g. webpack or Rollup), therefore the resolution is all made at build stage, and you can configure all the resolvers so they look into your "node_modules" folder (default behaviour obviously, so usually no special configuration is needed).