node-serialport icon indicating copy to clipboard operation
node-serialport copied to clipboard

Error when importing serialport (Svelte + electron Project)

Open hamyyy opened this issue 3 years ago • 8 comments

SerialPort Version

10.3.0

Node Version

v16.13.1

Electron Version

15.3.0

Platform

Microsoft Windows NT 10.0.22000.0 x64 (Windows 11)

Architecture

x64

Hardware or chipset of serialport

NA

What steps will reproduce the bug?

I'm using Svelte + Electron (scroll to bottom for more info).

My file contains

import { SerialPort } from "serialport"

The error seems to appear when importing anything from "@serialport/*".

Serialport is imported into a .svelte file (Svelte component) using normal Svelte syntax as shown.

<script lang="ts">
    import { SerialPort } from "serialport"
</script>

What happens?

Error in browser:

TypeError: Class extends value undefined is not a constructor or null
    at node_modules/@serialport/parser-byte-length/dist/index.js (index.js:10)
    at __require2 (chunk-FH3PLF5R.js?v=b87c477a:48)
    at node_modules/serialport/dist/index.js (index.js:13)
    at __require2 (chunk-FH3PLF5R.js?v=b87c477a:48)
    at dep:serialport:1

What should have happened?

serialport imports correctly

Additional information

As mentioned, I am using Svelte + Electron.

Project created using this npx command (when creating choose svelte and typescript).

A quick google search tells me that the error is related to circular dependencies. I don't know how to fix it, but I'm hoping someone might be able to help.

hamyyy avatar Mar 01 '22 06:03 hamyyy

Though I am not experienced with Svelte, I would hazard to guess that require("stream"); isn't doing what it's expected to in your context since evidently Stream.Transform is showing up as undefined and things are unraveling from there.

A big clue should be that you said "in browser". Make sure you're resolving through Electron's node API and not the renderer process.

Part where error is showing up
$ cat -n node_modules/@serialport/parser-byte-length/dist/index.js
     1  "use strict";
     2  Object.defineProperty(exports, "__esModule", { value: true });
     3  exports.ByteLengthParser = void 0;
     4  const stream_1 = require("stream");
     5  /**
     6   * Emit data every number of bytes
     7   *
     8   * A transform stream that emits data as a buffer after a specific number of bytes are received. Runs in O(n) time.
     9   */
    10  class ByteLengthParser extends stream_1.Transform {
    11      constructor(options) {
    12          super(options);
    13          if (typeof options.length !== 'number') {
    14              throw new TypeError('"length" is not a number');
    15          }
    16          if (options.length < 1) {
    17              throw new TypeError('"length" is not greater than 0');
    18          }
    19          this.length = options.length;
    20          this.position = 0;
    21          this.buffer = Buffer.alloc(this.length);
    22      }
    23      _transform(chunk, _encoding, cb) {
    24          let cursor = 0;
    25          while (cursor < chunk.length) {
    26              this.buffer[this.position] = chunk[cursor];
    27              cursor++;
    28              this.position++;
    29              if (this.position === this.length) {
    30                  this.push(this.buffer);
    31                  this.buffer = Buffer.alloc(this.length);
    32                  this.position = 0;
    33              }
    34          }
    35          cb();
    36      }
    37      _flush(cb) {
    38          this.push(this.buffer.slice(0, this.position));
    39          this.buffer = Buffer.alloc(this.length);
    40          cb();
    41      }
    42  }
    43  exports.ByteLengthParser = ByteLengthParser;

jacobq avatar Mar 07 '22 15:03 jacobq

I just ran into this problem. I think this may have something to do with ESM loading and typescript, but I get very lost when it comes to module loading.

I was able to reproduce this exact error using Electron, Typescript, VueJS, and Quasar. I tried to reproduce the problem with https://github.com/serialport/electron-serialport, but that project worked fine.

I think the crux of the problem is when you introduce Typescript.

I found that if I take this project: https://github.com/electron/electron-quick-start-typescript and add import { SerialPort } from 'serialport', it fails. I don't get the same failure, but it is a starting point.

If you want to have a look at this exact failure, I can point you to my project.

BryanHunt avatar Dec 17 '22 01:12 BryanHunt

I just found root cause of my problem. I was trying to import serialport inside the VueJS code and vite doesn't allow you to use native NodeJS code. The solution is to wrap the serial port code in electron-preload.ts which then makes it available through the window global.

BryanHunt avatar Dec 18 '22 03:12 BryanHunt

@BryanHunt can you post your final code? I have a similar problem, my solution was to use require instead of import, inside the main process. Even in the main process, I was unable to use import. Getting this error :

App threw an error during load
Error: No native build was found for platform=darwin arch=arm64 runtime=electron abi=116 uv=1 armv=8 libc=glibc node=18.15.0 electron=25.2.0
    loaded from: /Users/maduhaime/_dev/typescript/quiz-machine/electron

    at f.resolve.f.path (/Users/maduhaime/_dev/typescript/quiz-machine/electron/dist/main.js:6:12575)
    at f (/Users/maduhaime/_dev/typescript/quiz-machine/electron/dist/main.js:6:11914)
    at Object.<anonymous> (/Users/maduhaime/_dev/typescript/quiz-machine/electron/dist/main.js:8:2345)
    at Module._compile (node:internal/modules/cjs/loader:1269:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1324:10)
    at Module.load (node:internal/modules/cjs/loader:1124:32)
    at Module._load (node:internal/modules/cjs/loader:965:12)
    at f._load (node:electron/js2c/asar_bundle:2:13330)
    at loadApplicationPackage (/Users/maduhaime/_dev/typescript/quiz-machine/node_modules/electron/dist/Electron.app/Contents/Resources/default_app.asar/main.js:121:16)
    at Object.<anonymous> (/Users/maduhaime/_dev/typescript/quiz-machine/node_modules/electron/dist/Electron.app/Contents/Resources/default_app.asar/main.js:233:9)

maduhaime avatar Jun 24 '23 19:06 maduhaime

@maduhaime https://gitlab.com/springfield-ham-radio/app/ham-radio-ui/-/blob/main/src-electron/electron-preload.ts

BryanHunt avatar Jun 26 '23 15:06 BryanHunt