ElMassimo / iles

🏝 The joyful site generator
https://iles.pages.dev
MIT License
1.08k stars 31 forks source link

"TypeError: error loading dynamically imported module" during hydration #15

Closed gustojs closed 2 years ago

gustojs commented 2 years ago

Thanks for working on this project! Here's the first result of trying it out.

Iles 0.3.2, Windows 10, Node 16.11.1. New project created with iles-create.

Provided following index page:

<template>
  <hello-world client:load />
</template>

and following HelloWorld.vue:

<template>
  <button @click="click">click me</button>
  <div>counter is now {{ counter }}</div>
</template>

<script setup lang="ts">
import { ref } from "vue";
const counter = ref(0);
function click() {
  counter.value++;
}
</script>

The button works but there are following console warnings:

Loading failed for the module with source “d:/my-project/src/components/HelloWorld.vue”.
Loading failed for the module with source “http://localhost:3000/@id/@islands/hydration”.
Loading failed for the module with source “http://localhost:3000/@id/@islands/hydration/vue”.

In case of client:idle or client:visible, the button doesn't work and the warnings are:

Loading failed for the module with source “d:/my=project/src/components/HelloWorld.vue”.
Uncaught (in promise) TypeError: error loading dynamically imported module
    component http://localhost:3000/
    resolveAndHydrate http://localhost:3000/@id/@islands/hydration:9
    hydrateWhenIdle http://localhost:3000/@id/@islands/hydration:14

All client:load, client:idle, and client:visible break during npm run build with the same error:

build error:
 TypeError: Cannot read properties of undefined (reading 'imports')
    at renderRoute (D:\my-project\node_modules\iles\dist\node\chunk-CGP66JQW.js:5250:17)  
    at D:\my-project\node_modules\iles\dist\node\chunk-CGP66JQW.js:5239:63
    at Array.map (<anonymous>)
    at bundleIslands (D:\my-project\node_modules\iles\dist\node\chunk-CGP66JQW.js:5239:36)
    at async D:\my-project\node_modules\iles\dist\node\chunk-4VENJ5VU.js:31:92
    at async withSpinner (D:\my-project\node_modules\iles\dist\node\chunk-U43AXZ2V.js:9:20)
    at async build (D:\my-project\node_modules\iles\dist\node\chunk-4VENJ5VU.js:31:5)

Without the client prop everything builds but of course there's no button handler.

ElMassimo commented 2 years ago

Hi Darek!

I was not able to replicate using a similar example. Would you provide a reproduction?

It might be Windows-related. Something that caught my eye is: “d:/my=project. That = sign is not present in the other paths?

gustojs commented 2 years ago

I'll write a repro. The my-project was actually me shortening the real path after copypasting the error messages.

gustojs commented 2 years ago

https://github.com/gustojs/iles-repro

It might as well be a Windows only issue, like you said.

ElMassimo commented 2 years ago

Yeah, it seems to be working in Mac at least.

Screen Shot 2021-10-20 at 10 26 55Screen Shot 2021-10-20 at 10 29 06

The error is probably happening here when bundling islands.

It's likely that the manifest entry names are different in windows in a way that relative does not account for.

Would you provide the contents of dist/manifest.json? You might need to kill the process as soon as it says "bundling islands".

gustojs commented 2 years ago
{
  "src/components/HelloWorld.vue": {
    "file": "assets/HelloWorld.c806902d.js",
    "src": "src/components/HelloWorld.vue",
    "isEntry": true,
    "imports": [
      "_vendor-vue.97aa0a3b.js"
    ]
  },
  "\u0000virtual:__ile-1": {
    "file": "assets/_virtual___ile-1.80d4b72e.js",
    "src": "\u0000virtual:__ile-1",
    "isEntry": true,
    "imports": [
      "_iles.505e6f11.js",
      "src/components/HelloWorld.vue",
      "_vendor-vue.97aa0a3b.js"
    ]
  },
  "_iles.505e6f11.js": {
    "file": "assets/iles.505e6f11.js",
    "imports": [
      "_vendor-vue.97aa0a3b.js"
    ]
  },
  "_vendor-vue.97aa0a3b.js": {
    "file": "assets/vendor-vue.97aa0a3b.js"
  }
}
gustojs commented 2 years ago

This line looks highly suspicious

  "\u0000virtual:__ile-1": {
ElMassimo commented 2 years ago

Thanks for sharing the manifest! Same output here, so at least that's good news.

Adding the following in node_modules\iles\dist\node\chunk-CGP66JQW.js:5250:17:

      // After: const entry = manifest[`\0virtual:${_pathe.relative.call(void 0, config.root, island.entryFilename)}`];
      console.log({
        root: config.root,
        entryFilename: island.entryFilename,
        manifestPath: `\0virtual:${_pathe.relative.call(void 0, config.root, island.entryFilename)}`,
        entry,
      })

I get the following output:

{
  root: 'iles-repro',
  entryFilename: '__ile-1',
  manifestPath: '\x00virtual:__ile-1',
  entry: {
    file: 'assets/_virtual___ile-1.80d4b72e.js',
    src: '\x00virtual:__ile-1',
    isEntry: true,
    imports: [
      '_iles.505e6f11.js',
      'src/components/HelloWorld.vue',
      '_vendor-vue.97aa0a3b.js'
    ]
  }
}

In Windows, it seems that the entry is undefined.

Sorry to bother you again, but if you could share the output in that line, we could confirm whether manifestPath is a match, or if that's where the difference occurs.

If it matches, then it's probably related to that \x00 or \u0000 char that seem to be equivalent in Mac, but not in Windows? It seems to be an implementation detail of @rollup/plugin-virtual.

gustojs commented 2 years ago
{ 
  root: 'D:\\github\\iles-repro',
  entryFilename: '__ile-1',
  manifestPath: '\x00virtual:../../../__ile-1',
  entry: undefined
}
ElMassimo commented 2 years ago

So it's not related with \x00. I'll do a prerelease patch so that you can test it. Thanks for all of your help!

ElMassimo commented 2 years ago

Released iles@0.3.4, which should fix this incompatibility on Windows. Thanks again for your help! 😃

gustojs commented 2 years ago

Thanks, it's working now!

✔ building islands bundle
  done in 501ms

build complete in 2.35s.