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

ReferenceError: Buffer is not defined ReactJS

Open yaminagile opened this issue 3 years ago • 20 comments

I have react app which is created by create-react-app and follow the rules that provides here https://github.com/mqttjs/MQTT.js#react

But when I start my app I am getting following error

constants.js:46 Uncaught ReferenceError: Buffer is not defined
    at Object../node_modules/mqtt/node_modules/mqtt-packet/constants.js (constants.js:46:1)
    at Object.options.factory (react refresh:6:1)
    at __webpack_require__ (bootstrap:24:1)
    at fn (hot module replacement:61:1)
    at Object../node_modules/mqtt/node_modules/mqtt-packet/parser.js (parser.js:4:1)
    at Object.options.factory (react refresh:6:1)
    at __webpack_require__ (bootstrap:24:1)
    at fn (hot module replacement:61:1)
    at Object../node_modules/mqtt/node_modules/mqtt-packet/mqtt.js (mqtt.js:1:1)

I have look around similar to this issue but it didn't help me.

I am using react version 17.0.2 and react-scripts version 5.0.0

I am gone through this issue https://github.com/mqttjs/MQTT.js/issues/1294

But it didn't help me because I don't have any webpack config file on my react app.

yaminagile avatar Feb 04 '22 17:02 yaminagile

I have the same probelm as you, and have submitted a PR.

flyfishzy avatar Feb 09 '22 08:02 flyfishzy

@flyfishzy I see the PR is merged in mqtt-packet. is the problem in our dependency version in mqtt.js?

YoDaMa avatar Feb 10 '22 16:02 YoDaMa

@YoDaMa Yes, we need to upgrade the mqtt-packet version. But there are other similar problems, I'm trying to continue to fix them.

flyfishzy avatar Feb 14 '22 03:02 flyfishzy

Is there a workaround for this for time being?

Pavanct avatar Feb 17 '22 12:02 Pavanct

The release 4.3.6 still does not solve the issue for React. I am using react 17.0.2, react-scripts 5.0.0, and to build the MQTT js - webpack version 5.6.9. Also, I have tried downgrading the global version of webpack to 4.4, 4.6 - still getting the same error.

Pavanct avatar Feb 18 '22 11:02 Pavanct

Using a workaround for React js -

Using Node js 14, Mqtt 4.0.1, react-scripts 4.0.3. This configuration build works even with the webpack latest version 5.6.9.

Pavanct avatar Feb 18 '22 11:02 Pavanct

This works for me https://www.npmjs.com/package/paho-mqtt which is compatible with all the latest version of react and react-scripts You don't have to downgrade react, react-script or webpack for that.

yaminagile avatar Feb 18 '22 11:02 yaminagile

This works for me https://www.npmjs.com/package/paho-mqtt which is compatible with all the latest version of react and react-scripts You don't have to downgrade react, react-script or webpack for that.

Thank you, But I have tried it. Unable to set TLS certificates for SSL connection to a secure broker.

Pavanct avatar Feb 18 '22 11:02 Pavanct

I was able to build mqtt for React following these steps:

inside of node_modules/mqtt create webpack.config.js:

const webpack = require('webpack')

module.exports = {

    entry: "./lib/connect/index.js",

    //mode: "development",

    output: {
        library:  {
            type: "commonjs2"
        },
        filename: "mqtt.browser.js"
    },
    
    plugins: [
        // fix "process is not defined" error:
        // (do "npm install process" before running the build)
        new webpack.ProvidePlugin({
          process: 'process/browser',
        }),
        new webpack.ProvidePlugin({
            Buffer: [ 'buffer', 'Buffer' ],
        }),
    ],

    resolve: {
        fallback: {
            assert: require.resolve('assert'),
            buffer: require.resolve('buffer'),
            console: require.resolve('console-browserify'),
            constants: require.resolve('constants-browserify'),
            crypto: require.resolve('crypto-browserify'),
            domain: require.resolve('domain-browser'),
            events: require.resolve('events'),
            http: require.resolve('stream-http'),
            https: require.resolve('https-browserify'),
            os: require.resolve('os-browserify/browser'),
            path: require.resolve('path-browserify'),
            punycode: require.resolve('punycode'),
            process: require.resolve('process/browser'),
            querystring: require.resolve('querystring-es3'),
            stream: require.resolve('stream-browserify'),
            string_decoder: require.resolve('string_decoder'),
            sys: require.resolve('util'),
            timers: require.resolve('timers-browserify'),
            tty: require.resolve('tty-browserify'),
            url: require.resolve('url'),
            util: require.resolve('util'),
            vm: require.resolve('vm-browserify'),
            zlib: require.resolve('browserify-zlib'),
        }
    }
}

inside of node_modules/mqtt/package.json

  1. add "type": "commonjs" (not sure if this is necessary)
  2. under "browser" change ./mqtt.js": "./lib/connect/index.js" to "./mqtt.js": "./dist/mqtt.browser.js"

result:

{
  ...
  "type": "commonjs",
  "browser": {
    "./mqtt.js": "./dist/mqtt.browser.js"
    ...
  }
  ...
}

inside of node_modules/mqtt execute

npm i 
npm i buffer process
npm i webpack webpack-cli
npx webpack

important!!! clean npm cache

delete node_modules/.cache folder

rebuild you app

note: you can consume mqtt this way:

import { connect } from 'mqtt';

ambienthack avatar Feb 21 '22 00:02 ambienthack

I have similar problem for Ionic 6 Angular 13 app. I do not have webpack.config.js. My temporary fix: (window as any)['global'] = window; global.Buffer = global.Buffer || require('buffer').Buffer;

4refr0nt avatar Feb 26 '22 10:02 4refr0nt

if anyone here wants to offer a PR to fix this, it will be welcome.

YoDaMa avatar Mar 01 '22 17:03 YoDaMa

I was able to build mqtt for React following these steps:

inside of node_modules/mqtt create webpack.config.js:

const webpack = require('webpack')

module.exports = {

    entry: "./lib/connect/index.js",

    //mode: "development",

    output: {
        library:  {
            type: "commonjs2"
        },
        filename: "mqtt.browser.js"
    },
    
    plugins: [
        // fix "process is not defined" error:
        // (do "npm install process" before running the build)
        new webpack.ProvidePlugin({
          process: 'process/browser',
        }),
        new webpack.ProvidePlugin({
            Buffer: [ 'buffer', 'Buffer' ],
        }),
    ],

    resolve: {
        fallback: {
            assert: require.resolve('assert'),
            buffer: require.resolve('buffer'),
            console: require.resolve('console-browserify'),
            constants: require.resolve('constants-browserify'),
            crypto: require.resolve('crypto-browserify'),
            domain: require.resolve('domain-browser'),
            events: require.resolve('events'),
            http: require.resolve('stream-http'),
            https: require.resolve('https-browserify'),
            os: require.resolve('os-browserify/browser'),
            path: require.resolve('path-browserify'),
            punycode: require.resolve('punycode'),
            process: require.resolve('process/browser'),
            querystring: require.resolve('querystring-es3'),
            stream: require.resolve('stream-browserify'),
            string_decoder: require.resolve('string_decoder'),
            sys: require.resolve('util'),
            timers: require.resolve('timers-browserify'),
            tty: require.resolve('tty-browserify'),
            url: require.resolve('url'),
            util: require.resolve('util'),
            vm: require.resolve('vm-browserify'),
            zlib: require.resolve('browserify-zlib'),
        }
    }
}

inside of node_modules/mqtt/package.json

  1. add "type": "commonjs" (not sure if this is necessary)
  2. under "browser" change ./mqtt.js": "./lib/connect/index.js" to "./mqtt.js": "./dist/mqtt.browser.js"

result:

{
  ...
  "type": "commonjs",
  "browser": {
    "./mqtt.js": "./dist/mqtt.browser.js"
    ...
  }
  ...
}

inside of node_modules/mqtt execute

npm i 
npm i buffer process
npm i webpack webpack-cli
npx webpack

important!!! clean npm cache

delete node_modules/.cache folder

rebuild you app

note: you can consume mqtt this way:

import { connect } from 'mqtt';

After crawling the web for 5 6 hours i didnt find any working solution you saved me man. God bless you

ashiqdey avatar Apr 02 '22 17:04 ashiqdey

I was able to build mqtt for React following these steps:

inside of node_modules/mqtt create webpack.config.js:

const webpack = require('webpack')

module.exports = {

    entry: "./lib/connect/index.js",

    //mode: "development",

    output: {
        library:  {
            type: "commonjs2"
        },
        filename: "mqtt.browser.js"
    },
    
    plugins: [
        // fix "process is not defined" error:
        // (do "npm install process" before running the build)
        new webpack.ProvidePlugin({
          process: 'process/browser',
        }),
        new webpack.ProvidePlugin({
            Buffer: [ 'buffer', 'Buffer' ],
        }),
    ],

    resolve: {
        fallback: {
            assert: require.resolve('assert'),
            buffer: require.resolve('buffer'),
            console: require.resolve('console-browserify'),
            constants: require.resolve('constants-browserify'),
            crypto: require.resolve('crypto-browserify'),
            domain: require.resolve('domain-browser'),
            events: require.resolve('events'),
            http: require.resolve('stream-http'),
            https: require.resolve('https-browserify'),
            os: require.resolve('os-browserify/browser'),
            path: require.resolve('path-browserify'),
            punycode: require.resolve('punycode'),
            process: require.resolve('process/browser'),
            querystring: require.resolve('querystring-es3'),
            stream: require.resolve('stream-browserify'),
            string_decoder: require.resolve('string_decoder'),
            sys: require.resolve('util'),
            timers: require.resolve('timers-browserify'),
            tty: require.resolve('tty-browserify'),
            url: require.resolve('url'),
            util: require.resolve('util'),
            vm: require.resolve('vm-browserify'),
            zlib: require.resolve('browserify-zlib'),
        }
    }
}

inside of node_modules/mqtt/package.json

  1. add "type": "commonjs" (not sure if this is necessary)
  2. under "browser" change ./mqtt.js": "./lib/connect/index.js" to "./mqtt.js": "./dist/mqtt.browser.js"

result:

{
  ...
  "type": "commonjs",
  "browser": {
    "./mqtt.js": "./dist/mqtt.browser.js"
    ...
  }
  ...
}

inside of node_modules/mqtt execute

npm i 
npm i buffer process
npm i webpack webpack-cli
npx webpack

important!!! clean npm cache

delete node_modules/.cache folder

rebuild you app

note: you can consume mqtt this way:

import { connect } from 'mqtt';

This worked for me( ty ), I got error because there was no mqtt.browser.js file , instead there was "./dist/mqtt.js" so I configure package.json like "./mqtt.js": "./dist/mqtt.js" and at the end ./dist/mqtt.browser.js was created so I changed my package.json back to "./dist/mqtt.browser.js" and it worked.

ozgurSULUM avatar Apr 17 '22 19:04 ozgurSULUM

I would suggest to use this package instead No need to compile just install and use, Its a build version of [email protected]. can be used with react and other frontend libraries

ashiqdey avatar Apr 22 '22 13:04 ashiqdey

Hey, I also have this issue. Does anyone have a solution that does not require webpack changes?

rem4ik4ever avatar Jul 22 '22 01:07 rem4ik4ever

I would suggest to use this package instead No need to compile just install and use, Its a build version of [email protected]. can be used with react and other frontend libraries

This package is lacking type definitions and doesn't work well in typescript project.

rem4ik4ever avatar Jul 22 '22 01:07 rem4ik4ever

I was able to build mqtt for React following these steps:

inside of node_modules/mqtt create webpack.config.js:

const webpack = require('webpack')

module.exports = {

    entry: "./lib/connect/index.js",

    //mode: "development",

    output: {
        library:  {
            type: "commonjs2"
        },
        filename: "mqtt.browser.js"
    },
    
    plugins: [
        // fix "process is not defined" error:
        // (do "npm install process" before running the build)
        new webpack.ProvidePlugin({
          process: 'process/browser',
        }),
        new webpack.ProvidePlugin({
            Buffer: [ 'buffer', 'Buffer' ],
        }),
    ],

    resolve: {
        fallback: {
            assert: require.resolve('assert'),
            buffer: require.resolve('buffer'),
            console: require.resolve('console-browserify'),
            constants: require.resolve('constants-browserify'),
            crypto: require.resolve('crypto-browserify'),
            domain: require.resolve('domain-browser'),
            events: require.resolve('events'),
            http: require.resolve('stream-http'),
            https: require.resolve('https-browserify'),
            os: require.resolve('os-browserify/browser'),
            path: require.resolve('path-browserify'),
            punycode: require.resolve('punycode'),
            process: require.resolve('process/browser'),
            querystring: require.resolve('querystring-es3'),
            stream: require.resolve('stream-browserify'),
            string_decoder: require.resolve('string_decoder'),
            sys: require.resolve('util'),
            timers: require.resolve('timers-browserify'),
            tty: require.resolve('tty-browserify'),
            url: require.resolve('url'),
            util: require.resolve('util'),
            vm: require.resolve('vm-browserify'),
            zlib: require.resolve('browserify-zlib'),
        }
    }
}

inside of node_modules/mqtt/package.json

  1. add "type": "commonjs" (not sure if this is necessary)
  2. under "browser" change ./mqtt.js": "./lib/connect/index.js" to "./mqtt.js": "./dist/mqtt.browser.js"

result:

{
  ...
  "type": "commonjs",
  "browser": {
    "./mqtt.js": "./dist/mqtt.browser.js"
    ...
  }
  ...
}

inside of node_modules/mqtt execute

npm i 
npm i buffer process
npm i webpack webpack-cli
npx webpack

important!!! clean npm cache

delete node_modules/.cache folder

rebuild you app

note: you can consume mqtt this way:

import { connect } from 'mqtt';

Hello you saved my PhD I love you thanks

kesler20 avatar Jul 24 '22 16:07 kesler20

So if you're using MQTT for the web(mostly react). Your import should be like below

import mqtt from "mqtt/dist/mqtt";

And if you're using typescript, you need to add the below in a global type's definition or create an mqtt.d.ts and add the below

declare module "mqtt/dist/mqtt" {
    import MQTT from "mqtt"
    export = MQTT
}

remember to include the types file in include array of your tsconfig.json

doc-han avatar Jul 24 '22 17:07 doc-han

Hey, I also have this issue. Does anyone have a solution that does not require webpack changes?

Check the solution I just provided whether it works for you. Works for my team! we built with create-react-app and didn't want to eject. Hence, don't want to mess up with webpack configurations

doc-han avatar Jul 24 '22 17:07 doc-han

So if you're using MQTT for the web(mostly react). Your import should be like below

import mqtt from "mqtt/dist/mqtt";

And if you're using typescript, you need to add the below in a global type's definition or create an mqtt.d.ts and add the below

declare module "mqtt/dist/mqtt" {
    import MQTT from "mqtt"
    export = MQTT
}

remember to include the types file in include array of your tsconfig.json

Works perfectly ! Thanks !

ouedyan avatar Aug 01 '22 12:08 ouedyan

I got the webpack technique to work but then it later broke. It's like they really don't want us to use mqtt in a browser so they don't fix it. I use precompiled-mqtt now (https://www.npmjs.com/package/precompiled-mqtt)

awootton avatar Oct 30 '22 08:10 awootton

👍🏻 Importing from mqtt/dist/mqtt incl. type definitions is by far the best solution for my case (see https://github.com/mqttjs/MQTT.js/issues/1412#issuecomment-1193363330).

  • No additional package to be loaded.
  • No messing around in node_modules, that may not be repeatable easily.
  • No need to "rewire" create-react-app.
  • When used as a library, the fix is applied

fabiradi avatar Jan 11 '23 13:01 fabiradi

Thank you, you save me, I had a react app, that was using: "react-scripts": "^4.0.3" and "mqtt": "^4.1.0", after updating to "react-scripts": "^5.0.1" and "mqtt": "^4.3.7", I was receiving this error, I fixed just by changing the import of the dependencies as you suggested! import mqtt from "mqtt/dist/mqtt"; instead of import mqtt from "mqtt"; Now it work :)

FerrariAndrea avatar Feb 09 '23 12:02 FerrariAndrea

Another quick hack, without any deep config changes. Just add this to your index.html:

<script type="module">
  import { Buffer } from 'buffer';
  window.Buffer = Buffer;
</script>

ccvca avatar Mar 29 '23 06:03 ccvca

checkout this solution need to install precompiled-mqtt which is a wrapper of mqtt base package where you don't need to perform bundle related extra works

https://stackoverflow.com/a/75979346/8243241

mainak-shil avatar Apr 10 '23 17:04 mainak-shil

Could be fixed by https://github.com/mqttjs/MQTT.js/pull/1571

robertsLando avatar Jun 23 '23 14:06 robertsLando

MQTT 5.0.0 BETA is now available! Try it out and give us feedback: npm i mqtt@beta. It may fix your issues

robertsLando avatar Jul 21 '23 14:07 robertsLando

I have fixed Browser docs by adding webpack and vite setup. Check them out

robertsLando avatar Jul 31 '23 15:07 robertsLando