vuejs / router

🚦 The official router for Vue.js
https://router.vuejs.org/
MIT License
3.86k stars 1.18k forks source link

ESM browser module distribution depends on unsupported import #694

Open besenwagen opened 3 years ago

besenwagen commented 3 years ago

Version

4.0.2

Reproduction link

https://besenwagen.github.io/vue-router-next-broken-esm-browser-dist/

Steps to reproduce

1) Open reproduction URL in a browser 2) Observe TypeError in console

What is expected?

The ES module import is resolved.

What is actually happening?

A TypeError is thrown because 'vue' is not resolvable.

posva commented 3 years ago

I'm aware of this but I couldn't find any standard/agreement on how to write an import on a browser module file without forcing the user to use a specific CDN (which I can't)...

One (quite complicated) way to deal with this is to use a service worker to redirect the request for vue' to a CDN like unpkg or jsdelivr.

FYI, in vue router 3 we handled this the same way it is handled here: https://github.com/vuejs/vue-router/pull/2705

I'm open to suggestions!

besenwagen commented 3 years ago

One (quite complicated) way to deal with this is to use a service worker to redirect the request for vue' to a CDN like unpkg or jsdelivr.

The module URL must be resolved before a request can be initiated (and intercepted). Parsing the message property of a caught exception isn't complicated but madness. Sounds like a job for jQuery. 😂

FYI, in vue router 3 we handled this the same way it is handled here: vuejs/vue-router#2705

I saw that after opening this issue, thanks. It is extremely discouraging that the Vue 2 ecosystem did allow coding like it's 2015. ☹

I'm open to suggestions!

I wish I had any. At this point I fail to see te use case of these build artefacts. The answer is appreciated, anyhow.

besenwagen commented 3 years ago

One (quite complicated) way to deal with this is to use a service worker to redirect the request for vue' to a CDN like unpkg or jsdelivr.

While it's not possible to intercept bare modules because that fails before there is a request, it turns out it's still possible to create a workaround with a service worker:

It's quite mad, but still better than using the global legacy build for modern development without Node.

posva commented 3 years ago

Currently, one needs to use Skypack or https://www.chromestatus.com/feature/5315286962012160 (chrome only). I think this will make sense as a cookbook entry once these topics are more mature

besenwagen commented 3 years ago

Skypack or https://www.chromestatus.com/feature/5315286962012160

Thanks, both were new to me. Cookbook entries and generally more documentation would be great, esm-browser in a CDN file name raises expectations that are not currently met.

kngai commented 3 years ago

Any updates to this issue? I'm getting the same error too in my <script type="module">:

import { createApp, ref, computed, watch, onMounted } from 'https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.7/vue.esm-browser.prod.js'
import { useRoute } from 'https://cdnjs.cloudflare.com/ajax/libs/vue-router/4.0.9/vue-router.esm-browser.js'
Uncaught TypeError: Failed to resolve module specifier "vue". Relative references must start with either "/", "./", or "../".
AimForNaN commented 1 year ago

vue-router.esm-browser.prod.js for latest version doesn't exist (though I'm not sure if that would remove the dependency). @vue/devtools-api dependency is very inconvenient. While import maps are a quick workaround, I would prefer to be without such a dependency for production.

stefnotch commented 1 year ago

It looks like every browser, other than old Safari, supports import maps https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap

I suppose it would be possible to use the ESM browser module, and add a documentation note about "this needs an import map polyfill if you're targeting Safari".

charlesprescottcollins commented 11 months ago

So how does one work around this with skypack?

9mm commented 10 months ago

So I'm trying to use vue-router in browser with import maps... how do I workaround these errors?

pin "vue",                           to: "https://unpkg.com/vue@latest/dist/vue.esm-browser.prod.js"
pin "vue-router",                    to: "https://esm.sh/vue-router"
import { createApp } from "vue";
import { createRouter, createWebHistory } from "vue-router";

This is failing with devtools errors?

blacelle commented 2 weeks ago

Until @vue/devtools-api is dropped (e.g. into some vue-router.esm-browser.prod.js), one way to move forward is:

<script type="importmap">
{
  "imports": {
    "vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js",
    "vue-router": "https://unpkg.com/vue-router@4.4.3/dist/vue-router.esm-browser.js",
    "@vue/devtools-api": "https://unpkg.com/@vue/devtools-api@6.2.1/lib/esm/index.js"
  }
}
</script>