Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MQTT v5 Feedbacks #1639

Closed
robertsLando opened this issue Jul 19, 2023 · 60 comments · Fixed by #1677
Closed

MQTT v5 Feedbacks #1639

robertsLando opened this issue Jul 19, 2023 · 60 comments · Fixed by #1677

Comments

@robertsLando
Copy link
Member

Use this issue to report your feedback about MQTTv5 version. Positive feedbacks are welcome too so we know everything is working as expected 😄

@robertsLando robertsLando pinned this issue Jul 19, 2023
This was referenced Jul 19, 2023
@dvkam
Copy link

dvkam commented Aug 2, 2023

Hey @robertsLando may I show you my approach how to resolve the Buffer, process etc is not defined?
This does not require to install aditionall plugins like rollup-plugin-polyfill-node.
My Vite config and the steps:

  1. Run npm install buffer stream-browserify util events process //depending on what you need of course

  2. Then create a new file nodeSpecific.ts in the src folder of the project and add:

import { Buffer } from 'buffer'

globalThis.Buffer = Buffer
  1. Then open the index.html file and add the following script in the body.
    It should look like this:
<body>
  <div id="root"></div>
   <script type="module" src="/src/nodeSpecific.ts"></script> //add this line
   <script type="module" src="/src/main.tsx"></script>
</body>
  1. Finally open the vite.config.ts file and add the resolve part:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'

// https://vitejs.dev/config/
export default defineConfig({
  define: {
    global: {},
  },
  plugins: [react()],
  resolve: {
    alias: {
      buffer: 'buffer',
      stream: 'stream-browserify',
      os: 'os-browserify/browser',
      util: 'util',
      process: 'process/browser',
    },
  },
})

Also if there are other/better solutions, I am curious to see them.
I did not test thoroughly with MQTT yet but usually this works for me.

@VirensCn
Copy link

VirensCn commented Aug 3, 2023

Non urgent issues

If you use Uniapp (vue3+vite) and package it into a WeChat mini program, it will cause a call to requireBrowser, resulting in an error exception. The main reason is the process variable, which is determined to be a call to this function by the browser environment

image

@robertsLando
Copy link
Member Author

Hey @robertsLando may I show you my approach how to resolve the Buffer, process etc is not defined?

That's exactly what rollup polifilly module does

@chendahao
Copy link

@Eddy-Ko @VirensCn I have fixed vite setup docs: https://github.com/mqttjs/MQTT.js#vite
And also created a vite example here: https://github.com/mqttjs/MQTT.js/tree/main/examples/vite-example
Please check them out and let me know.

After trying the Vite setup in the documentation, I encountered a warning:

Module "url" has been externalized for browser compatibility. Cannot access "url.parse" in client code. See http://vitejs.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.

This resulted in an error:

Uncaught TypeError: url_1.default.parse is not a function

Then I found the solution in this article.

My Final Solution

Install these package:

yarn add --dev @esbuild-plugins/node-globals-polyfill
yarn add --dev @esbuild-plugins/node-modules-polyfill
yarn add --dev rollup-plugin-polyfill-node

In vite.config.js:

import { NodeGlobalsPolyfillPlugin } from "@esbuild-plugins/node-globals-polyfill";
import { NodeModulesPolyfillPlugin } from "@esbuild-plugins/node-modules-polyfill";
import nodePolyfills from "rollup-plugin-polyfill-node";

export default defineConfig({
  // Other rules...
  resolve: {
    alias: {
      url: "rollup-plugin-node-polyfills/polyfills/url",
      util: "rollup-plugin-node-polyfills/polyfills/util",
      querystring: "rollup-plugin-node-polyfills/polyfills/qs",
    },
  },
  optimizeDeps: {
    esbuildOptions: {
      // Node.js global to browser globalThis
      define: {
        global: "globalThis",
      },
      // Enable esbuild polyfill plugins
      plugins: [
        NodeGlobalsPolyfillPlugin({
          buffer: true,
        }),
        NodeModulesPolyfillPlugin(),
      ],
    },
  },
  build: {
    rollupOptions: {
      // Enable rollup polyfills plugin
      // used during production bundling
      plugins: [nodePolyfills()],
    },
  },
});

useful for me ,mqtt5.0.2 vite4.3.9

@kood-2008
Copy link

@Eddy-Ko @VirensCn I have fixed vite setup docs: 我有固定的 vite 安装文档: https://github.com/mqttjs/MQTT.js#viteHttps://github.com/mqttjs/mqtt.js#vite
And also created a vite example here:
并且在这里创造了一个生动的例子: https://github.com/mqttjs/MQTT.js/tree/main/examples/vite-exampleHttps://github.com/mqttjs/mqtt.js/tree/main/examples/vite-example
Please check them out and let me know.
请检查一下,然后告诉我。

After trying the Vite setup in the documentation, I encountered a warning:在尝试了文档中的 Vite 设置之后,我遇到了一个警告:

Module "url" has been externalized for browser compatibility. Cannot access "url.parse" in client code. See http://vitejs.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.

This resulted in an error:这导致了一个错误:

Uncaught TypeError: url_1.default.parse is not a function

Then I found the solution in this article.然后我在这篇文章中找到了解决方案。

My Final Solution### 我的最终解决方案

Install these package:安装以下软件包:

yarn add --dev @esbuild-plugins/node-globals-polyfill
yarn add --dev @esbuild-plugins/node-modules-polyfill
yarn add --dev rollup-plugin-polyfill-node

In vite.config.js:在 vite.config.js 中:

import { NodeGlobalsPolyfillPlugin } from "@esbuild-plugins/node-globals-polyfill";
import { NodeModulesPolyfillPlugin } from "@esbuild-plugins/node-modules-polyfill";
import nodePolyfills from "rollup-plugin-polyfill-node";

export default defineConfig({
  // Other rules...
  resolve: {
    alias: {
      url: "rollup-plugin-node-polyfills/polyfills/url",
      util: "rollup-plugin-node-polyfills/polyfills/util",
      querystring: "rollup-plugin-node-polyfills/polyfills/qs",
    },
  },
  optimizeDeps: {
    esbuildOptions: {
      // Node.js global to browser globalThis
      define: {
        global: "globalThis",
      },
      // Enable esbuild polyfill plugins
      plugins: [
        NodeGlobalsPolyfillPlugin({
          buffer: true,
        }),
        NodeModulesPolyfillPlugin(),
      ],
    },
  },
  build: {
    rollupOptions: {
      // Enable rollup polyfills plugin
      // used during production bundling
      plugins: [nodePolyfills()],
    },
  },
});

useful for me ,mqtt5.0.2 vite4.3.9

对我很有用,mqtt5.0.2 vite4.3.9

when i yarn build, This resulted in an error:,
error during build:
RollupError: "toASCII" is not exported by "__vite-browser-external", imported by "node_modules/rollup-plugin-node-polyfills/polyfills/url.js

it seemlike this code in vite.coinfig.ts:
alias: {
'@': pathResolve('./src'),
url: "rollup-plugin-node-polyfills/polyfills/url", // here
util: "rollup-plugin-node-polyfills/polyfills/util",
querystring: "rollup-plugin-node-polyfills/polyfills/qs",
}
What should I do

@robertsLando
Copy link
Member Author

@kood-2008 Refer to this: https://github.com/mqttjs/MQTT.js/blob/main/examples/vite-example/vite.config.js

@kood-2008
Copy link

@kood-2008 Refer to this: https://github.com/mqttjs/MQTT.js/blob/main/examples/vite-example/vite.config.js

@ kood-2008参考此 https://github.com/mqttjs/mqtt.js/blob/main/examples/vite-example/vite.config.js :

Hello, I successfully used mqtt for the Yarn dev project after using the vite.config.ts code you provided. However, the project will report an error after Yarn build And deploy it to run on the server, so I git clone your project and install example project(Folder vite-example). unfortunate, npm run dev succeeded, but npm run build failed after deploy it to run on the server

error Code: UR.default.parse is not a functionat Object.Up [as connect]
click in:
...
function Up(t, e) {
if (cc("connecting to an MQTT broker..."),
typeof t == "object" && !e && (e = t,
t = ""),
e = e || {},
t && typeof t == "string") {
const i = UR.default.parse(t, !0); // <------------------------------------ error code Looks like it's from here
if (i.port != null && (i.port = Number(i.port)),
e = Object.assign(Object.assign({}, i), e),
e.protocol === null)
throw new Error("Missing protocol");
e.protocol = e.protocol.replace(/:$/, "")
}
if (HR(e),
.....

@robertsLando
Copy link
Member Author

robertsLando commented Aug 17, 2023

Try adding the url polifilly:

import { NodeGlobalsPolyfillPlugin } from "@esbuild-plugins/node-globals-polyfill";
import { NodeModulesPolyfillPlugin } from "@esbuild-plugins/node-modules-polyfill";
import nodePolyfills from "rollup-plugin-polyfill-node";

export default defineConfig({
  // Other rules...
  resolve: {
    alias: {
      url: "rollup-plugin-node-polyfills/polyfills/url", <-------- THIS
      util: "rollup-plugin-node-polyfills/polyfills/util",
      querystring: "rollup-plugin-node-polyfills/polyfills/qs",
    },
  },
  optimizeDeps: {
    esbuildOptions: {
      // Node.js global to browser globalThis
      define: {
        global: "globalThis",
      },
      // Enable esbuild polyfill plugins
      plugins: [
        NodeGlobalsPolyfillPlugin({
          buffer: true,
        }),
        NodeModulesPolyfillPlugin(),
      ],
    },
  },
  build: {
    rollupOptions: {
      // Enable rollup polyfills plugin
      // used during production bundling
      plugins: [nodePolyfills()],
    },
  },
});

@vagreargnatry
Copy link
Contributor

@robertsLando Hello! I have a request for the exports of package.json. Please read below.

This method cannot work in MQTT.js v5 but works in MQTT.js v4.3.7.

In MQTT.js v5 the error is [vite] Internal server error: Failed to resolve import "mqtt/dist/mqtt.min" from "{{ component name }}". Does the file exist?. I think the reason is it cannot find this file because of the exports of package.json.

Then I add "./dist/*": "./dist/*.js", to the next line here, then it works.

I don't want to install @esbuild-plugins/node-globals-polyfill and @esbuild-plugins/node-modules-polyfill and rollup-plugin-polyfill-node. Please add "./dist/*": "./dist/*.js" or some what to package.json.

Please correct me if I am wrong. Thanks for reading!

@robertsLando
Copy link
Member Author

@vagreargnatry would you like to submit a PR please?

@xukaishan
Copy link

You also need to pay attention to the browser environment:
import * as mqtt from 'mqtt/dist/mqtt.min'

@robertsLando
Copy link
Member Author

robertsLando commented Sep 26, 2023

For anyone using mqttjs in browser, just use

import * as mqtt from 'mqtt/dist/mqtt'

there is no need of any configuration both in vite/webpack then

@function1983
Copy link

For anyone using mqttjs in browser, just use

import * as mqtt from 'mqtt/dist/mqtt.min'

there is no need of any configuration both in vite/webpack then

Thank you @robertsLando for the instruction. I just want to report my findings:
Environment: @sveltejs/kit 1.25.1 + vite 4.4.11 + mqtt 5.1.0.
vite.config.js just as yours

DOESN'T WORK: import * as mqtt from 'mqtt/dist/mqtt.min'

Errors in terminal:
npm run dev: ws does not work in the browser. Browser clients must use the native WebSocket object
npm run build: mqtt.connect is not a function

WORKS: import * as mqtt from 'mqtt'

Both dev and build will work in browser

@robertsLando
Copy link
Member Author

robertsLando commented Oct 10, 2023

@function1983 Remove the .min, I corrected my answer above. If you use that you don't need all those polifilly on vite config

@function1983
Copy link

@function1983 Remove the .min, I corrected my answer above. If you use that you don't need all those polifilly on vite config

My thought was exactly the same. But in reality I still do need polyfilling as mentioned in your vite config.
Without polyfilling, npm run build would complete normally but when deployed it will return this error message:

Uncaught (in promise) ReferenceError: process is not defined

Other than that quirk, mqttjs runs flawlessly and very stable for me.

@robertsLando
Copy link
Member Author

robertsLando commented Oct 10, 2023

My thought was exactly the same. But in reality I still do need polyfilling as mentioned in your vite config.
Without polyfilling, npm run build would complete normally but when deployed it will return this error message:

There must be something else that requires them because in my example I'm able to run it and build too without any polifilly, the dist/mqtt version is already polifilled. What I can suggest is to add --force flag to vite command to clear its cache

@tukusejssirs
Copy link

I have just upgrade to v5, I don’t know how to set setMaxListeners.

In v4, I used client.setMaxListeners(number), however, the property seems not to exist anymore.

Was it moved somewhere else? Was it removed? Does it still needs to be implemented? 🤔 🙏

@robertsLando
Copy link
Member Author

robertsLando commented Oct 19, 2023

@tukusejssirs setMaxListeners should be an EventEmitter method so it should be present as MqttClient extends it, are you using mqtt on nodejs or browser? how do you import and use it in your code?

@tukusejssirs
Copy link

tukusejssirs commented Oct 19, 2023

@robertsLando, I have installed mqtt using npm and uae it in Nest. Both my IDE (WebStorm) and TS compiler (v5.8 5.2.2) raises the error of an non-existent property.

I import and use it like tgis:

import {connect} from 'mqtt'

const client = connect(options)

client.setMaxListeners(number)  // This fails

@robertsLando
Copy link
Member Author

robertsLando commented Oct 19, 2023

Ok this seems an issue, I will fix it asap. In the meanwhile I suggest to try this:

// @ts-expect-error
client.setMaxListeners(number) 

When you will install a version of mqttjs that fixes that the ts compiler will warn you that the @ts-expect-error is not needed anymore

@robertsLando
Copy link
Member Author

@tukusejssirs 5.1.3 fixes your issue

@robertsLando
Copy link
Member Author

I'm closing this as now mqtt v5 is out

@robertsLando robertsLando unpinned this issue Oct 24, 2023
@robertsLando
Copy link
Member Author

robertsLando commented Nov 10, 2023

FYI starting from 5.2.1 you can now import mqtt in browser using:

import mqtt from 'mqtt'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.