Mqtt doesn't load correctly in Svelte Kit.
What I've done so far
- Imported
'mqtt/dist/mqtt.min'instead of'mqtt'as suggested by this issue. - Use
import * as mqtt from 'mqtt/dist/mqtt.min';instead ofimport mqtt from 'mqtt/dist/mqtt.min'as suggested by the vite issue. - Lastly, as suggested in the Svelte Kit FAQ, I fiddled around with SSR settings, and I found that excluding mqtt.js from SSR made some more progress.
The problem
I am now getting the following error:
ReferenceError: WebSocket is not defined
at /home/nathan/Documents/code/crowdlight/frontend/node_modules/mqtt/dist/mqtt.min.js:1:26065
at Object.t.exports (/home/nathan/Documents/code/crowdlight/frontend/node_modules/mqtt/dist/mqtt.min.js:1:26122)
at v.streamBuilder (/home/nathan/Documents/code/crowdlight/frontend/node_modules/mqtt/dist/mqtt.min.js:1:32293)
at v._setupStream (/home/nathan/Documents/code/crowdlight/frontend/node_modules/mqtt/dist/mqtt.min.js:1:5476)
at new v (/home/nathan/Documents/code/crowdlight/frontend/node_modules/mqtt/dist/mqtt.min.js:1:4901)
at Proxy.u (/home/nathan/Documents/code/crowdlight/frontend/node_modules/mqtt/dist/mqtt.min.js:1:31896)
at test.svelte:4:29
at Object.$$render (/home/nathan/Documents/code/crowdlight/frontend/node_modules/svelte/internal/index.js:1677:22)
at Object.default (root.svelte:38:46)
at eval (/home/nathan/Documents/code/crowdlight/frontend/.svelte-kit/dev/components/layout.svelte:8:41)
Sample code
Here is a test svelte page I made to recreate this bug: src/routes/test.svelte
<script>
// import connect from 'mqtt/dist/mqtt.min';
import * as mqtt from 'mqtt/dist/mqtt.min';
let client = mqtt.connect('wss://test.mosquitto.org:8081')
client.on('connect', function () {
client.subscribe('presence', function (err) {
if (!err) {
client.publish('presence', 'Hello mqtt')
}
})
})
client.on('message', function (topic, message) {
// message is Buffer
console.log(message.toString())
client.end()
})
</script>
<h1>It loads!</h1>
And my Svelte Kit config: svelte.config.js
import adapter from '@sveltejs/adapter-static';
/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {
vite: {
ssr: {
external: ['mqtt/dist/mqtt.min']
}
},
// Static build
adapter: adapter({
pages: 'build',
assets: 'build',
fallback: null
}),
// hydrate the <div id="svelte"> element in src/app.html
// target: '#svelte'
}
};
export default config;
ngl, I've been battling this exact problem for a few days now, but I think I found the solution. As SvelteKit is using SSR, it's trying to execute the browser version of mqtt.connect, which uses the WebSockets object, a class that doesn't exist in Node.JS. There're several methods of forcing SvelteKit to load something on the browser but the one I used is to put the code that calls mqtt.connect inside the onMount function. Something a little bit like this:
import { onMount } from "svelte";
let client;
onMount(() => { client = mqtt.Client("ws://placeholder.net"); });
This is an automated message to let you know that this issue has gone 365 days without any activity. In order to ensure that we work on issues that still matter, this issue will be closed in 14 days.
If this issue is still important, you can simply comment with a "bump" to keep it open.
Thank you for your contribution.
I was contacted by someone who got it working. Here is an example repository: https://github.com/SilentEchoGM/mqtt-kit-example Here is the specific part that solves the import issue: svelte.config.js
SvelteKit has now transitioned to using a vite config file, so you would need to adapt the config, or for all I know (I've given up on using MQTT) the Svelte/MQTT devs may have fixed whatever issue causes this officially just from their high development paces.