How to get dev env Hot Module Reload working?

What's the normal process for HMR? I tried yarn dev but it opens in a browser window and I therefor can't login as gamemaster because I'm already logged in to the main app on that account. I created a second user also with gamemaster privs and that then seems to enable HMR in the browser, but not in the Desktop App. Is this behaviour correct and as expected or is there a way to make the desktop app respond to HMR?
10 Replies
Unknown User
Unknown User17mo ago
Message Not Public
Sign In & Join Server To View
TyphonJS (Michael)
The Electron app is not going to point to the dev server automatically. It is going to go to the port that it is configured to which by default is 30000. The ideal recommended setup for development is to configure your IDE to open a debugger browser instance to http://localhost:30001 after starting the Foundry server and the Vite dev server. This is a lot easier and hassle free with WebStorm to setup. To stop the Vite dev server from automatically opening a browser set server.open to false in the Vite config. Refer the Vite config documentation for more information.
Solidor
Solidor17mo ago
I launch foundry through node using command prompt and then do everything on Edge
geoidesic
geoidesic16mo ago
I've also noticed that dynamic imports don't work on the electron app. Does that mean that my system will not work in the electron app if someone installs it? E.g. this component:
<script>
export let chatTemplate = "";
import { onMount } from "svelte";
console.log("SurgeRoll template: " + chatTemplate);
let Template;

onMount(async () => {
Template = (await import(`./${chatTemplate}.svelte`)).default;
});
</script>

<svelte:component this={Template} {...$$props} />
<script>
export let chatTemplate = "";
import { onMount } from "svelte";
console.log("SurgeRoll template: " + chatTemplate);
let Template;

onMount(async () => {
Template = (await import(`./${chatTemplate}.svelte`)).default;
});
</script>

<svelte:component this={Template} {...$$props} />
That works in the browser via dev server. However in electron it yields:
Uncaught (in promise) TypeError: undefined. Failed to fetch dynamically imported module: http://localhost:30000/systems/surge/SubAttributeRollChat.svelte
[Detected 1 package: system:surge]
Uncaught (in promise) TypeError: undefined. Failed to fetch dynamically imported module: http://localhost:30000/systems/surge/SubAttributeRollChat.svelte
[Detected 1 package: system:surge]
TyphonJS (Michael)
I suppose this can be chalked up to a misunderstanding of what Svelte is... Svelte is a compile time library. You can't load / import a .svelte file dynamically at runtime. That this works w/ the dev server is a curious side effect. If you have various Svelte components that you want to load from a prop, chatTemplate, you need to create a way to connect that reference to compiled components. You could export a Map or object from a JS file that organizes compiled components that are handled at build time. Pseudo-code ahead (JS file):
import Component1 from './Component1.svelte';
import Component2 from './Component2.svelte';

const chatLookupMap = new Map([['component1', Component1], ['component2', Component2]]);

export chatLookupMap;
import Component1 from './Component1.svelte';
import Component2 from './Component2.svelte';

const chatLookupMap = new Map([['component1', Component1], ['component2', Component2]]);

export chatLookupMap;
In Svelte component that handles displaying a chat message:
<script>
import { chatLookupMap } from './chatLookupMap.js';

export let chatTemplate = "";
</script>

<svelte:component this={chatLookupMap.get(chatTemplate)} {...$$props} />
<script>
import { chatLookupMap } from './chatLookupMap.js';

export let chatTemplate = "";
</script>

<svelte:component this={chatLookupMap.get(chatTemplate)} {...$$props} />
I'm sure this can be improved for better error checking... Just pseudo-code I typed out.
geoidesic
geoidesic16mo ago
So much for my clever-bollocks way of avoiding typing out all the imports!
TyphonJS (Michael)
I create index.js files in directories that contains a lot of Svelte components like this: index.js in some folder
export { default as Component1 } from './Component1.svelte';
export { default as Component2 } from './Component2.svelte';
export { default as Component3 } from './Component3.svelte';
export { default as Component1 } from './Component1.svelte';
export { default as Component2 } from './Component2.svelte';
export { default as Component3 } from './Component3.svelte';
import {
Component1,
Component2,
Component3 } from '../components';

// etc etc..
import {
Component1,
Component2,
Component3 } from '../components';

// etc etc..
In your case you could do this (again all pseudo-code, but should work):
<script>
import * as ChatComponents from '../whereever/chat/components/are';

export let chatTemplate = "";
</script>

<svelte:component this={ChatComponents[chatTemplate]} {...$$props} />
<script>
import * as ChatComponents from '../whereever/chat/components/are';

export let chatTemplate = "";
</script>

<svelte:component this={ChatComponents[chatTemplate]} {...$$props} />
This is mostly fundamental ES Modules related import / export handling and a good reason to buff up on how ESM works in general.
geoidesic
geoidesic16mo ago
What a mission but thank you for that, it works! The componentMap idea worked for me. The latter idea errored with
EISDIR: illegal operation on a directory, read
EISDIR: illegal operation on a directory, read
TyphonJS (Michael)
Could be import * as ChatComponents from '../whereever/chat/components/are/'; Again pseudo-code above...
geoidesic
geoidesic16mo ago
I was just missing the index.js for that 🤦🏻‍♂️