MQTT.js и Webpack — WS не конструктор

Я пытаюсь связать один из наших микросервисов, который использует MQTT.js, и борюсь с действительно странной проблемой.

Он отлично работает без комплектации, поэтому ws доступен в node_modules.

Вещи, которые я считаю важными:

ошибка:

    TypeError: WS is not a constructor
        at WebSocketStream (dist/index.js:159329:16)
        at createWebSocket (dist/index.js:147450:10)
        at Object.buildBuilderBrowser (dist/index.js:147476:10)
        at MqttClient.wrapper [as streamBuilder] (dist/index.js:147937:36)
        at MqttClient._setupStream (dist/index.js:146471:22)
        at new MqttClient (dist/index.js:146452:8)
        at Function.connect (dist/index.js:147940:10)

Конфигурация веб-пакета:

const path = require('path');
const nodeExternals = require('webpack-node-externals');

const { NODE_ENV = 'production' } = process.env;

module.exports = {
  entry: { index: './src/index.ts' },
  mode: NODE_ENV,
  target: 'node',
  watch: NODE_ENV === 'development',
  externals: [nodeExternals()],
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].js',
  },
  resolve: {
    extensions: ['.ts', '.js'],
  },
  node: {
    __dirname: false,
  },
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: [{ loader: 'ts-loader', options: { transpileOnly: true } }],
      },
      {
        test: /(\.md|\.map)$/,
        loader: 'null-loader',
      },
    ],
  },
};

Функция, где это происходит:

createMqttClient(): MqttClient {
    return mqtt.connect(this.mqttOptions.url, { ...this.mqttOptions.options });
  }

URL выглядит так: ssl://url-to-our-mqtt

Кто-нибудь может помочь, пожалуйста?


person Marek Urbanowicz    schedule 14.03.2019    source источник
comment
Я думаю, что первым шагом будет проверка того, действительно ли WS доступен в сгенерированном пакете. Если это не так, вы знаете, что столкнулись с проблемой сборки, когда модуль по какой-то причине исключен из сборки.   -  person enf0rcer    schedule 14.03.2019
comment
Попробуйте запустить webpack без минификации. Как в режиме разработки. Если работает, то проблема в минификации вебпака. Вот почему это крах. Подробнее читайте здесь webpack.js.org/guides/production/#minification webpack.js.org/concepts/mode/#mode-production   -  person Grynets    schedule 14.03.2019
comment
@Grynets Работает без минификации. Если бы он был минимизирован, я бы не смог отследить эту проблему.   -  person Marek Urbanowicz    schedule 14.03.2019
comment
Не могли бы вы показать, как и куда вы импортируете ws?   -  person Grynets    schedule 14.03.2019


Ответы (2)


Я также столкнулся с той же проблемой. Проблема для меня заключалась в том, что я использовал

 plugins: [
   new webpack.NormalModuleReplacementPlugin(/^mqtt$/, "mqtt/dist/mqtt.js"),
 ],

в webpack.config.js, чтобы исправить ошибку shebang, которая возникает с mqtt.js, поскольку это инструмент CLI. Тогда вместо этого я использовал

  {
    test: [
      /node_modules[/\\]mqtt[/\\]mqtt.js/,
      /node_modules[/\\]mqtt[/\\]bin[/\\]sub.js/,
      /node_modules[/\\]mqtt[/\\]bin[/\\]pub.js/,
    ],
    loader: 'shebang-loader'
  },

И моя проблема была исправлена. Вы также используете mqtt/dist/mqtt.js вместо mqtt в своем импорте, или если вы делаете что-то похожее на мое, правило shebang-loader, которое я опубликовал выше, может решить вашу проблему.

person KlaatuSama    schedule 11.06.2019

Я испытал то же самое с Amazon aws-iot-device-sdk-js и Microsoft azure-iot-device-mqtt, которые включают mqtt.

Первоначальной проблемой является ошибка сборки:

ERROR in ./node_modules/mqtt/mqtt.js Module parse failed: Unexpected character '#' (1:0)

Эта ошибка вызвана пакетом mqtt. Три файла (mqtt.js, pub.js и sub.js) содержат строку shebang

#!/usr/bin/env node 

Решение с использованием замены модуля предложило некоторые места

plugins: [
   new webpack.NormalModuleReplacementPlugin(/^mqtt$/, "mqtt/dist/mqtt.js"),
 ],

к сожалению, изменяет ошибку сборки с ошибкой времени выполнения

TypeError: WS is not a constructor

Как упоминалось в других ответах, веб-пакет можно настроить (https://webpack.js.org/concepts/loaders/), чтобы использовать загрузчик shebang (https://www.npmjs.com/package/shebang-loader)

TL;DR

Установить shebang-загрузчик

npm install shebang-loader --save

В webpack.config.js используйте загрузчик

module.exports = {
...
    module: {
        rules: [
            {
                test:
                    [
                        /.*mqtt\.js$/,
                        /.*sub\.js$/,
                        /.*pub\.js$/
                    ],
                use: 'shebang-loader'
            }
        ]
    }
}
person Kim Nyholm    schedule 02.06.2020