matt-e-king / vue-mapp-kit

3 stars 0 forks source link

Nuxt support? #56

Open liamb13 opened 2 years ago

liamb13 commented 2 years ago

Are there plans to add a Nuxt version in the pipelines?

liamb13 commented 2 years ago

For anyone trying to add this to Nuxt, current work around:

Create a nuxt plugin:

# /plugins/vue-mapp-kit.js
import Vue from 'vue'
import MappKitLeaflet from '@vue-mapp-kit/leaflet'
import MappKitEsriLeaflet from '@vue-mapp-kit/esri-leaflet'

export default (store) => {
  Vue.use(MappKitLeaflet, { store })
  Vue.use(MappKitEsriLeaflet)
}

I haven't quite figured out how to add this to nuxt.config.js, so my approach is to call the plugin inside a Layout:

# /layouts/MapLayout.vue
<template>
  <div>
    <Nuxt />
  </div>
</template>
<script>
import VueMapp from '~/plugins/vue-mapp-kit'
export default {
  created() {
    VueMapp(this.$store)
  },
}
</script>
eLBirador commented 1 year ago

Hi liamb13. do you happen to have more examples on this approach? tried adding this into my Nuxt app but getting VITE_Error instead. also since its under the plugins director. shouldn't it be something like this? I am not sure also though.

export default defineNuxtPlugin((app) => { app.vueApp.use(MappKitLeaflet, { }) app.vueApp.use(MappKitEsriLeaflet) })

thanks

matt-e-king commented 1 year ago

Wow. @liamb13 I'm terribly sorry about such a major delay on responding to this issue. The sad truth is that I actively use this library in so many of my projects, yet I'm so unorganized in the upkeep of it being a "public project". All the "latest features" have been tucked in 4.0.0-alpha.1 version. I went ahead, just this morning, and released v4.0.0 and updated the master branch for this to all make more sense.

(I'm also actively working on v5 of this library which will be all Vite builds and support Vue3, see more below)

I know this response is long over due, but I've incorporate this project into many Nuxt v2 projects like this:

Create a plugin file inside /<srcDir>/plugins/vue-mapp-kit.js, with the following contents:

import Vue from 'vue'
import MappKitLeaflet from '@vue-mapp-kit/leaflet'
import MappKitEsriLeaflet from '@vue-mapp-kit/esri-leaflet'

Vue.use(MappKitLeaflet)
Vue.use(MappKitEsriLeaflet)

In nuxt.config.js add an entry to the plugins property:

plugins: [
   ....
    '~/plugins/vue-mapp-kit',
   ....
  ],

BUT importing this library as a Vue.use plugin only gives you access to an additional bus that the library uses internally. Otherwise, you don't need to install these libraries with Vue.use, you can import the components directly:

import {
  LMap,
  LTileLayer
} from '@vue-mapp-kit/leaflet'
import ELFeatureLayer from '@vue-mapp-kit/esri-leaflet/lib/ELFeatureLayer/ELFeatureLayer'

There are more leaflet examples here: https://github.com/matt-e-king/vue-mapp-kit/tree/master/packages/leaflet-examples


@eLBirador are you attempting to use this library in a Nuxt3/Vue3 project with your Vite build? The latest version of this library still only supports Vue2. That being said, I'm actively building out support for Vue3. I have a bulk of the upgrade finished, I'm just working on code examples and documentation.

liamb13 commented 1 year ago

@matt-e-king no apology needed, you still got there in the end! Completely understand that, there's a lot involved in maintain a public package.

Excited to see what V5 brings!

eLBirador commented 1 year ago

@matt-e-king , yes I am playing around Nux3/Vue3 project. all good! I will wait for the Vue3 support. thank you for this library!

matt-e-king commented 1 year ago

@eLBirador I put out the release candidate for Vue3 compatibility: https://github.com/matt-e-king/vue-mapp-kit/tree/release/5.0.0

It's not fully refactored to take advantage of Vue3 composition API, this version is just to ensure it works. I have yet to incorporate this into a Nuxt3 application, but I'm curious to here your experience.

karis commented 1 year ago

hi @matt-e-king and all

i just make /plugins/esrileaflet.client.js


import VueMappKitLeafet from '@vue-mapp-kit/leaflet'
// eslint-disable-next-line no-undef
export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.use(VueMappKitLeafet)
})

then i add into nuxt.config.ts

....
plugins: [
            { src: '~/plugins/esrileaflet.client.js', mode: 'client' },
          ],
          vue: {  
            compilerOptions: {
              isCustomElement: (tag) => ['ELTiledMapLayer','EMap','LMap'].includes(tag),
              // warning log : If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.
              // solution : https://stackoverflow.com/a/75435365/21834348
            },
          }
...

then i make a test app.vue

<ClientOnly>
        <LMap
          :map-id="mapId"
          :options="{
            center: [30.70, -81.47],
            zoom: 10
          }"
        >
          <ELTiledMapLayer
            :options="{
              url: 'https://services.arcgisonline.com/ArcGIS/rest/services/USA_Topo_Maps/MapServer'
            }"
          />
        </LMap>
    </ClientOnly>

i got window is not defined may be some can give me a clue..

thanks

matt-e-king commented 1 year ago

Hello @karis! Can you confirm which version of Nuxt and vue-mapp-kit you are using? Does your Nuxt app run server-side as well? Is that why you needed to configure mode: 'client' for the plugin entry?

The current version of vue-mapp-kit does not support Vue3/Nuxt3, but the release candidate does: https://github.com/matt-e-king/vue-mapp-kit/tree/release/5.0.0

I have successfully implemented vue-mapp-kit/leaflet and vue-mapp-kit/esri-leaflet in a Nuxt3 app. The only issue I've run into with the release candidate is EsriLeaflet won't use the ESM version of leaflet. I though putting "type": "module" in the root app package.json would resolve this.

karis commented 1 year ago

hi @matt-e-king

ofcourse, here it is:

   "@types/leaflet": "^1.9.3",
    "@types/node": "^18",
    "@vue-mapp-kit/esri-leaflet": "5.0.0-rc.0",
    "@vue-mapp-kit/leaflet": "5.0.0-rc.0",
    "esri-leaflet": "^3.0.10",
    "leaflet": "^1.9.4",
    "nuxt": "^3.5.2",

yes, it is server-side render, then i try to change vue-mapp-kit as mode: 'client' . i got this temporary solution from several posting.

if it has to be change into module type. i don't know the impact in production.

matt-e-king commented 1 year ago

@karis I believe the main issue is you need to put all the "client only" code into it's own component. Your app.vue should not be importing anything from these libraries, or it makes the nuxt <ClientOnly> component useless because you are still referencing these client side libraries in the <script> of app.vue. So try this:

app.vue

<template>
  <div>
    <ClientOnly>
        <MainMap />
    </ClientOnly>
  </div>
</template>

Make a new component called MainMap (this example requires you to yarn add -D sass FYI):

<template>
  <div id="map" class="ExampleMap">
    <LMap
      map-id="mainMap"
      :options="{
        center: [30.70, -81.47],
        zoom: 10
      }"
    >
      <ELTiledMapLayer
        :options="{
          url: 'https://services.arcgisonline.com/ArcGIS/rest/services/USA_Topo_Maps/MapServer'
        }"
      />
    </LMap>
  </div>
</template>

<script setup>
import { LMap } from '@vue-mapp-kit/leaflet'
import ELTiledMapLayer from '@vue-mapp-kit/esri-leaflet/lib/ELTiledMapLayer/ELTiledMapLayer.vue'
</script>

<style lang="sass">
@import "leaflet/dist/leaflet.css"

.ExampleMap
  position: relative
  height: 500px
  width: 500px
</style>

Chances are though you will get the following error:

Uncaught SyntaxError: The requested module '/_nuxt/node_modules/leaflet/dist/leaflet-src.js?v=7ff77983' does not provide an export named 'DomUtil'

I believe this has something to do with Vite/EsriLeaflet not correctly loading the ESM version of Leaflet. It appears this can be resolved by adding vite.optimizeDeps to your nuxt.config:

nuxt.config.js

// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
  devtools: { enabled: true },

  plugins: [
    { src: '~/plugins/esrileaflet.client.js', mode: 'client' }
  ],

  vite: {
    optimizeDeps: {
      include: ['leaflet', 'esri-leaflet']
    }
  }
})
karis commented 1 year ago

hi @matt-e-king

thank for your support.. i'll try this..

karis commented 1 year ago

hi @matt-e-king

i've follow your guidance.. and no error, but also no map previewed..

matt-e-king commented 1 year ago

@karis Maybe it's simple CSS thing. Did you import/include the leaflet/dist/leaflet.css any where?

If you put the <LMap> component inside another tag, be sure that tag has defined height and width, with position: relative. Inspect on the webpage where the map should go and see if it's a CSS thing, I'm curious.

Thanks.