vue3-openlayers
vue3-openlayers copied to clipboard
Cannot find module .../node_modules/ol/Feature Did you mean to import "ol/Feature.js"?
Describe the bug
Hello everyone!
I'm trying to integrate vue3-openlayers in my personal project.
My stack is:
- Astro
- Vue
I'm trying to run this code:
<script setup lang="ts">
import { Map, Layers, Sources } from "vue3-openlayers";
</script>
<template>
<Map.OlMap style="min-width: 400px; min-height: 400px;">
<Map.OlView :center="[40, 40]" :zoom="5" projection="EPSG:4326" />
<Layers.OlTileLayer>
<Sources.OlSourceOsm />
</Layers.OlTileLayer>
</Map.OlMap>
</template>
But i got this error:
Cannot find module '/Users/fabrizio/Documents/Projects/TechCompenso/Repositories/tech-compenso/node_modules/.pnpm/[email protected][email protected][email protected][email protected][email protected][email protected][email protected][email protected]_/node_modules/ol/Feature' imported from /Users/fabrizio/Documents/Projects/TechCompenso/Repositories/tech-compenso/node_modules/.pnpm/[email protected][email protected][email protected][email protected][email protected][email protected][email protected][email protected]_/node_modules/vue3-openlayers/dist/vue3-openlayers.es.js Did you mean to import "ol/Feature.js"?
If i edit manually the import in the build and append .js it works. I think it's something related to the tsconfig.jsonorastrobuild.
Consider that astro use vite for the building phase. So i can also do some tweaks on vite in the astro configuration if it is necessary.
These are respectively my tsconfig.jsonand astro.config.mjs:
tsconfig.json
{
"extends": "astro/tsconfigs/base",
"include": [
"netlify/*",
"node_modules/@prisma/client"
],
"compilerOptions": {
"baseUrl": ".",
"isolatedModules": true,
"esModuleInterop": true,
"target": "ESNext",
"paths": {
"@lib/*": [
"src/lib/*"
],
"@utils/*": [
"src/utils/*"
],
"@components/*": [
"src/components/*"
],
"@layouts/*": [
"src/layouts/*"
],
"@assets/*": [
"src/assets/*"
],
"@pages/*": [
"src/pages/*"
],
"@functions/*": [
"netlify/functions/*"
]
},
"jsx": "preserve",
}
}
astro.config.mjs
import { defineConfig } from "astro/config";
import tailwind from "@astrojs/tailwind";
import mdx from "@astrojs/mdx";
import netlify from "@astrojs/netlify";
// https://astro.build/config
import vue from "@astrojs/vue";
// https://astro.build/config
export default defineConfig({
site: "https://techcompenso.com",
output: "server",
integrations: [
tailwind(),
mdx({
optimize: true,
}),
vue({ appEntrypoint: "/src/app.js" }),
],
adapter: netlify(),
});
Affected version(s)
├── [email protected] -> ./node_modules/.pnpm/[email protected][email protected]/node_modules/ol-contextmenu
├── [email protected] -> ./node_modules/.pnpm/[email protected][email protected]/node_modules/ol-ext
├── [email protected] -> ./node_modules/.pnpm/[email protected]/node_modules/ol
├── [email protected] -> ./node_modules/.pnpm/[email protected][email protected]/node_modules/vue
└── [email protected] -> ./node_modules/.pnpm/[email protected][email protected][email protected][email protected][email protected][email protected][email protected][email protected]_/node_modules/vue3-openlayers
Expected behavior It should not throw any error for the import.
I would really appreciate your help. Thank you very much.
I have the same issue
ERROR in ./node_modules/vue3-openlayers/dist/vue3-openlayers.es.js 105:0-56
Module not found: Error: Can't resolve 'ol/events/condition' in '/Users/user/Documents/Projects/app/node_modules/vue3-openlayers/dist'
Did you mean 'condition.js'?
BREAKING CHANGE: The request 'ol/events/condition' failed to resolve only because it was resolved as fully specified
(probably because the origin is strict EcmaScript Module, e. g. a module with javascript mimetype, a '*.mjs' file, or a '*.js' file where the package.json contains '"type": "module"').
The extension in the request is mandatory for it to be fully specified.
Add the extension to the request.
@ ./src/vue/app.js 3:0-44 52:23-36
Check if you are not trying to render this component on the server side. I'm using Nuxt with Vue3, and it had the same error. Disabling SSR resolved the issue. I think wrapping the map in the ClientOnly component should work as well.
I had the same error with nuxt 3.
It can be solved in 2 ways:
- Via routeRules in nuxtConfig
export default defineNuxtConfig({
......
routeRules: {
'/sales': {ssr: false},
},
....
- As @vasyl-ko said, via the use of the ClientOnly Wrapper
// sales.vue
<template>
<ClientOnly>
<SalesMap/>
</ClientOnly>
</template>
// SalesMap.vue
<template>
<Map.OlMap style="min-width: 400px; min-height: 400px;">
<Map.OlView :center="[40, 40]" :zoom="5" projection="EPSG:4326"/>
<Layers.OlTileLayer>
<Sources.OlSourceOsm/>
</Layers.OlTileLayer>
</Map.OlMap>
</template>
<script lang="ts" setup>
import {Layers, Map, Sources} from 'vue3-openlayers'
</script>
So in General, rendering the map, at server side does not make a lot of sense in my opinion, doesn't it? In my opinion a hint for SSR and approaches like disabling ssr for a specific site or a ClientOnly directive as mentioned would be okay.
If you are using the plugin approach to import vue3-openlayers into your Nuxt project, you can just define your plugin as client only (and also wrap the outer component with <ClientOnly> of course) so that you won't need to disable the SSR feature of the page or even the whole site.
// nuxt.config.ts
plugins: [
{
src: '@/plugins/your-plugin-file-name-here',
mode: 'client'
}
]
I had this issue when using vue-3-openlayers with vitest. The fix was the following in my vitest.config.ts
// vitest.config.ts
ssr: {
noExternal: [/ol/, /vue3-openlayers/],
},