serialport / node-serialport

Access serial ports with JavaScript. Linux, OSX and Windows. Welcome your robotic JavaScript overlords. Better yet, program them!
https://serialport.io
MIT License
5.79k stars 1.01k forks source link

Error when importing serialport (Svelte + electron Project) #2440

Open hamyyy opened 2 years ago

hamyyy commented 2 years ago

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.

jacobq commented 2 years ago

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; ```
BryanHunt commented 1 year ago

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 commented 1 year ago

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.

maduhaime commented 1 year ago

@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)
BryanHunt commented 1 year ago

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

ProGamer2711 commented 5 months ago

I get the same error. I use react and vite. what can i do

flyweights commented 2 months ago

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

Good. It does. It's just a little redundant.

SimBuckeye commented 1 month ago

@BryanHunt

vite doesn't allow you to use native NodeJS code.

How did you find this out? Do you have a reference that talks about it? I'm running into this with vite & ASP.NET and trying to come up with another workaround, but I don't think I understand exactly what's not allowed.