I managed to get Leaflet working with Angular 2 and Webpack by following this project.
I can see the typings configured in "browser.d.ts":
/// <reference path="browser\ambient\leaflet\leaflet.d.ts" />
webpack.config.js defines an entry point:
...
entry: {
'polyfills': './src/polyfills.ts',
'libs': './src/libs.ts',
'main': './src/main.ts'
},
...
The "libs.ts" contains the import of the Leaflet module:
import 'leaflet';
I'm using Atom as a code editor. It now recognises all the Leaflet classes and methods. I can now do things like this in Angular 2:
import {Map, TileLayer} from 'leaflet';
...
this.baseMaps = {
StreetMap: new TileLayer('mapbox.streets')
};
Here is where my problems start. I'm trying to use mapbox.js. What I did was I installed mapbox.js library and typings:
npm install mapbox.js --save
typings install mapbox --save
This is where I'm stuck. For the life of me I can't figure out how to do what Leaflet managed to do.
import 'mapbox';
Doesn't work.
ERROR in ./src/libs.ts
Module not found: Error: Cannot resolve module 'mapbox' in C:\Develop\angular2-webpack-starter\src
@ ./src/libs.ts 3:0-17
I can see "browser.d.ts" has the following:
/// <reference path="browser\ambient\leaflet\leaflet.d.ts" />
/// <reference path="browser\ambient\mapbox\mapbox.d.ts" />
I thought maybe Mapbox will just work, because it extends the Leaflet library?
It seems that I can basically do something like this, which is the standard javascript way:
this.baseMaps = {
StreetMap: L.mapbox.tileLayer('mapbox.streets')
};
But not this:
this.baseMaps = {
StreetMap: new TileLayer('mapbox.streets')
};
This obviously doesn't work either:
import {Map, TileLayer} from 'mapbox';
What am I doing wrong?
For anyone like me who just wanted to get a map to show in their project, here's how I got it. Based mostly on Angular2 Mapbox-gl Starter.
Adding Mapbox-gl to Angular 2 - Webpack and Typescript
Install the needed packages...
npm install mapbox-gl --save
npm install @types/mapbox-gl --save
npm install @types/geojson --save
Add stuff to webpack...
module.exports = function(options) {
return {
resolve: {
alias: {
'mapbox-gl': '../node_modules/mapbox-gl/dist/mapbox-gl.js'
}
},
module: {
postLoaders: [
{
include: /node_modules\/mapbox-gl-shaders/,
loader: 'transform',
query: 'brfs'
}
]
}
}
}
Add a map.service.ts (For some reason I had to use full relative paths in the imports)...
import { Injectable } from '@angular/core';
import * as mapboxgl from '../../../../node_modules/mapbox-gl/dist/mapbox-gl.js';
import { Map } from '../../../../node_modules/mapbox-gl/dist/mapbox-gl.js';
@Injectable()
export class MapService {
map: Map<any, any>;
constructor() {
(mapboxgl as any).accessToken = 'YOUR_MAPBOX_TOKEN_HERE';
}
}
Add maps to your component...
import { Component } from '@angular/core';
import { MapService } from '../../api/resources/map.service';
import { Map } from '../../../../node_modules/mapbox-gl/dist/mapbox-gl.js';
@Component({
selector: 'my-component',
styles: [ require('./my-component.component.less') ],
template: require('./my-component.component.html'),
providers: [ MapService ]
})
export class MyComponentComponent {
constructor(private mapService: MapService) { }
ngOnInit() {
let map = new Map({
container: 'map',
style: 'mapbox://styles/mapbox/light-v9',
zoom: 5,
center: [-78.880453, 42.897852]
});
this.mapService.map = map;
}
}
Add map div to your html...
// my-component.component.html
<div id="map" class="mapboxgl-map"></div>
For styles, I use LESS
, so I imported the mapbox styles there...
// my-component.component.less
@import (less) '../../../../node_modules/mapbox-gl/dist/mapbox-gl.css';