MQTT.js icon indicating copy to clipboard operation
MQTT.js copied to clipboard

Mqtt doesn't load correctly in Svelte Kit.

Open TheTrueCoder opened this issue 4 years ago • 1 comments

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 of import 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;

TheTrueCoder avatar Oct 23 '21 22:10 TheTrueCoder

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"); });

rguzg avatar Dec 09 '21 01:12 rguzg

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.

github-actions[bot] avatar Dec 09 '22 02:12 github-actions[bot]

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.

TheTrueCoder avatar Dec 12 '22 03:12 TheTrueCoder