vitejs / vite

Next generation frontend tooling. It's fast!
http://vitejs.dev
MIT License
66.85k stars 6k forks source link

Vite errors on import of @googlemaps/js-api-loader #15620

Open apparchsysad opened 7 months ago

apparchsysad commented 7 months ago

Describe the bug

I'm trying to use the Google Maps api-loader library to inject the Google Maps api script into my sveltekit webapp. The library was installed in my project with "npm i @googlemaps/js-api-loader" and is invoked in my webapp code with "import { Loader } from '@googlemaps/js-api-loader';".

When I run "npm run dev", the procedure fails with the following error :

22:04:04 [vite] Error when evaluating SSR module /src/routes/+page.svelte: failed to import "@googlemaps/js-api-loader" |- SyntaxError: [vite] Named export 'Loader' not found. The requested module '@googlemaps/js-api-loader' is a CommonJS module, which may not support all module.exports as named exports.

The message goes on to explain how I might try using a default export :

_The requested module '@googlemaps/js-api-loader' is a CommonJS module, which may not support all module.exports as named exports. CommonJS modules can always be imported via the default export, for example using:

import pkg from '@googlemaps/js-api-loader'; const {Loader} = pkg;_

But when I try this, the webapp itself fails telling me that the api-loader package doesn't provide a default export:

_app.js:16 SyntaxError: The requested module '/node_modules/.vite/deps/@googlemapsjs-api-loader.js?v=5fcf71f8' does not provide an export named 'default'

Others have reported similar issues with 'npm run build' but as far as I can see I'm the only one with an 'npm run dev' problem

Reproduction

https://github.com/apparchsysad/test

Steps to reproduce

The test repository at https://github.com/apparchsysad/test was created as a skeleton webapp with the following npm commands:

npm create svelte@latest . npm install npm i @googlemaps/js-api-loader

The skeleton +page.svelte file was then modified to import the loader and display a Google map

System Info

System is a terminal session in VSCode on a Windows 11 PC

Used Package Manager

npm

Logs

No response

Validations

sapphi-red commented 7 months ago

The error happens with named imports because in SSR, the package is externalized and Node uses the main field that is a UMD file. Only default import can be used for UMD files. The error happens with default imports because in non-SSR, the package is not externalized and module field is used and that is a ESM file. Default import doesn't exist in that ESM file.

There's three ways I can think of to use this dependency:

  1. Set ssr.noExternal: ['@googlemaps/js-api-loader'] in vite.config.ts
  2. Write a separate file for server and client
  3. Patch @googlemaps/js-api-loader

vite-plugin-cjs-interop might work as well.

gajus commented 7 months ago

I am facing similar issue.

Setting ssr.noExternal then produces error:

error:
  name:    ReferenceError
  message: module is not defined
  stack:
    """
      ReferenceError: module is not defined
          at eval (/Users/gajus/Developer/contra/gaia/node_modules/.pnpm/relay-runtime@16.1.0/node_modules/relay-runtime/index.js:12:1)
          at instantiateModule (file:///Users/gajus/Developer/contra/gaia/node_modules/.pnpm/vite@5.1.0-beta.2_@types+node@20.10.0_sass@1.69.0/node_modules/vite/dist/node/chunks/dep-BzxBS-ea.js:54170:15)
    """
sapphi-red commented 7 months ago

@gajus That one is different from this issue. I think it's #14158.

kelbyfaessler commented 5 months ago

I also have this issue. Has anyone been successful with workarounds?

kelbyfaessler commented 5 months ago

ok so

Set ssr.noExternal: ['@googlemaps/js-api-loader'] in vite.config.ts

worked for me after I remembered to revert my import back to import { Loader } from '@googlemaps/js-api-loader';

bshesh7 commented 5 months ago

were you able to come up with the solution?

apparchsysad commented 5 months ago

I'm disappointed that Vite has never assigned anybody to this, but it was never a big issue for me as I was just noodling around with Svete at the time.

For what they're worth, here are the notes I made about the issue.

"Inserting a Google map was tricky. Repo at https://github.com/t108368527/Svelte_Map showed how a script in app.html could inject the Google map api into the browser so that Svelte code can access it. But this exposes the key. Google at https://developers.google.com/maps/documentation/javascript/load-maps-js-api recommend their api loader, but Vite seems to have problems importing this. See https://stackoverflow.com/questions/77704910/load-basic-google-map-with-array-of-coordinates-in-sveltekit for an implementation. In the end used a "shared api" technique at https://gist.github.com/wlkns/64d8ab123d9f2c3d4d8c6df61cb5ea9b to inject the api and its key from a function - seems OK"

I'll mail you my code if you want to follow this up.

Best wishes, MJ

On Sat, 23 Mar 2024 at 00:06, bshesh7 @.***> wrote:

were you able to come up with the solution?

— Reply to this email directly, view it on GitHub https://github.com/vitejs/vite/issues/15620#issuecomment-2016199248, or unsubscribe https://github.com/notifications/unsubscribe-auth/BCA4WYQO6BHWUSBTA37SOWLYZTBPXAVCNFSM6AAAAABB4TMQTSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMJWGE4TSMRUHA . You are receiving this because you authored the thread.Message ID: @.***>

bshesh7 commented 5 months ago

owed how a script in app.html could inject the Google map api into the browser so that Svelte code can

Can you please mail me @ bshesh7@gmail.com please

apparchsysad commented 5 months ago

No prob - attached source for three files from my svelte project. Follow the trail for AppArchMap that starts in the +page.svelte section. I''ve had to combine them into a single text file - Gmail wasn't happy about my attaching .js executables!

Hope they help.

Regards, MJ

On Sat, 23 Mar 2024 at 14:52, bshesh7 @.***> wrote:

owed how a script in app.html could inject the Google map api into the browser so that Svelte code can

Can you please mail me @ @.*** please

— Reply to this email directly, view it on GitHub https://github.com/vitejs/vite/issues/15620#issuecomment-2016515639, or unsubscribe https://github.com/notifications/unsubscribe-auth/BCA4WYTX3AYDAHKVH5GS333YZWJJRAVCNFSM6AAAAABB4TMQTSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMJWGUYTKNRTHE . You are receiving this because you authored the thread.Message ID: @.***>

sam-w commented 4 months ago

The fix that worked for me was quite simple. Applies to SvelteKit specifically, but may also apply to Vite users in general:

import * as gmapsLoader from '@googlemaps/js-api-loader';
const { Loader } = gmapsLoader;

This worked for me for both dev and build, SSR, prerendered, whatever.

Interesting side note: for js-api-loader 1.16.6, at least, doing the above results in a slightly different (and by the looks of it, more up-to-date) type for Loader:

import { Loader as OldLoader } from '@googlemaps/js-api-loader';

import * as gmapsLoader from '@googlemaps/js-api-loader';
const { Loader } = gmapsLoader;

(new OldLoader(someParams)).loadCallback(callback); // fine
(new Loader(someParams)).loadCallback(callback); // deprecation warning
Keagel commented 4 months ago

The fix that worked for me was quite simple. Applies to SvelteKit specifically, but may also apply to Vite users in general:

import * as gmapsLoader from '@googlemaps/js-api-loader';
const { Loader } = gmapsLoader;

This worked for me for both dev and build, SSR, prerendered, whatever.

Are you saying that worked for you without adding ssr.noExternal: ['@googlemaps/js-api-loader']? Personally I get a TypeError: Loader is not a constructor message when using your example (also using SvelteKit). Adding the noExternal to vite.config.ts does the trick, but at that point the import * as gmapsLoader workaround is no longer needed.

elton971 commented 1 month ago

If u are using Nuxt or vue3 u can use this

https://stackoverflow.com/questions/72592413/cant-generate-nuxt-website-with-googlemaps-js-api-loader