Node-serial port as external module in webpack - module not found - javascript

I'm trying to get node-serialport to work with electron and webpack.
I'm importing serialports as external module:
# webpack.config.js
externals: {
serialport: "serialport"
}
This is the code in my app:
// read NMEA data from serial port
const SerialPort = require('serialport');
console.log(SerialPort.list());
const Readline = SerialPort.parsers.Readline;
const port = new SerialPort('/dev/tty.Redmi-ShareGPS', { baudRate: 4800 });
const parser = port.pipe(new Readline({ delimiter: '\r\n' }));
// Open errors will be emitted as an error event
port.on('error', function(err) {
console.log(err.message);
})
// send NMEA data to GPS.js
parser.on('data', function(data) {
// gps.update(data);
});
Trouble is in first line: const SerialPort = require('serialport');
Webpack compiles everything without error, but I have a browser console error:
Uncaught ReferenceError: serialport is not defined
at Object.<anonymous> (bundle.js:65651)
at __webpack_require__ (bundle.js:20)
at Object.<anonymous> (bundle.js:65630)
at __webpack_require__ (bundle.js:20)
at Object.<anonymous> (bundle.js:31520)
at __webpack_require__ (bundle.js:20)
at Object.<anonymous> (bundle.js:25595)
at __webpack_require__ (bundle.js:20)
at _ol_ (bundle.js:63)
at bundle.js:66
Which origins at this in webpack generated bundle.js:
/* 315 */
/***/ (function(module, exports, __webpack_require__) {
// read NMEA data from serial port
const SerialPort = __webpack_require__(316);
console.log(serialport.list());
const Readline = SerialPort.parsers.Readline;
const port = new SerialPort('/dev/tty.Redmi-ShareGPS', { baudRate: 4800 });
const parser = port.pipe(new Readline({ delimiter: '\r\n' }));
// Open errors will be emitted as an error event
port.on('error', function (err) {
console.log(err.message);
});
// send NMEA data to GPS.js
parser.on('data', function (data) {
// gps.update(data);
});
/***/ }),
/* 316 */
/***/ (function(module, exports) {
module.exports = serialport;
/***/ })
/******/ ]);
The error line is exactly module.exports = serialport;
According to webpack docs on externals, I suppose I somehow need to include serialport as a global variable, but the example is for jQuery which is a js file, and serialport is node module.
How to make it work?

After many hours of frustration, I moved
const SerialPort = require('serialport');
from javascript file which is supposed to be bundled by webpack to index.html:
<script>
const SerialPort = require('serialport');
</script>
<script src="dist/bundle.js"></script>
SerialPort is now recognized.
Also, it seems like webpack-dev-server doesn't work very well with Electron and serialport. I have to launch full electron app.

Try remote.
You might also want to try using remote:
const SerialPort = require( "electron" ).remote.require( "serialport" );

use eval
const serialport = eval(`require('serialport')`)

Related

Serial Port With Electron-Vue.js

I tried to do serial port to listen my COMports with electron-vue.js.
When I try to code this below.
const SerialPort = require("serialport");
const Readline = SerialPort.parsers.Readline;
const port = new SerialPort("COM3", {
baudRate: 9600,
});
const parser = new Readline();
port.pipe(parser);
//Read Data
parser.on("data", (line) => {
console.log(line);
});
//Send Data
parser.write("Sended Data !");
I got this below error in console.
TypeError: Cannot read property 'modules' of undefined
at Object.eval (bindings.js?dfc1:29)
at eval (bindings.js:223)
at Object../node_modules/bindings/bindings.js (0.js:231)
at webpack_require (app.js:854)
at fn (app.js:151)
at eval (linux.js?88eb:2)
at Object../node_modules/#serialport/bindings/lib/linux.js (0.js:65)
at webpack_require (app.js:854)
at fn (app.js:151)
at Object.eval (index.js?c888:14)
How can I solve this problem ?
By the way, When I try to run this code in node.js, it runs. But when I try to run this code in Vue.js, it did not run.
Thanks
serialport uses physical resource so can't be webpacked as client package. you need to mark serialport as external for the builder.
// vue.config.js
module.exports = {
pluginOptions: {
electronBuilder: {
externals: ["serialport"],
},
},
},

Load local dll with node-ffi: No such file

I try to load a local .dll according the examples on stackoverflow and node-ffi documentation.
But I get the error ENOENT: no such file or directory, open '../test/user32.dll.so'. The file is there (no exception).
The extension '.so' is added automatically. Any idea what I'm doing wrong? Is this code plattform dependent? I'm on Debian.
const path = require('path');
const fs = require('fs');
const ffi = require('ffi');
function setCursor() {
const dllFile = path.join('../test', 'user32.dll');
if (!fs.existsSync(dllFile)) {
throw (new Error('dll does not exist'));
}
const user32 = ffi.Library(dllFile, {
"SetCursorPos": [
"bool", ["int32", "int32"]
]
});
console.log(user32.SetCursorPos(0, 0));
}
setCursor();
It looks like path doesn't recognize ../test as being the parent folder. I think path.join(__dirname, '..', 'test', 'user32.dll'); should get you to the right place.

fs.readFileSync is not a function when importing an object

I am developing in vuejs, focused on IPTV service. The problem I am having is that when I want to do the following
const {channels} = require('../lib/utils/index.js');
in the file actions.js it shows me the following error
index.js?c45a:26 Uncaught TypeError: fs.readFileSync is not a function
at Module.eval (index.js?c45a:26)
at eval (index.js:64)
at Module../src/lib/utils/index.js (app.js:958)
at __webpack_require__ (app.js:786)
at fn (app.js:151)
at eval (actions.js?63e0:2)
at Module../src/store/actions.js (app.js:1005)
at __webpack_require__ (app.js:786)
at fn (app.js:151)
at eval (index.js?4360:1)
Is there any way to solve this problem?
../lib/utils/index.js
const fs = require('fs');
const fetch = require('node-fetch');
const parser = require('iptv-playlist-parser');
const USM3U = require('./urls/us.m3u');
/***
* #async
* #method GM3U
* #param {empty}
* #Summary Generate US m3u file
* #Description THIS FUNCTION SHOULD NOT BE USED.
***/
const GM3U = async() =>{
const res = await fetch(`${USM3U}`);
const data = await res.text();
fs.writeFile('us.m3u' , data , (err) =>{
if(err){
console.log(err);
}else{
console.log('The file us.m3u was saved!');
}
})
};
const usPlaylist = fs.readFileSync('us.m3u' , {encoding: 'utf8'});
const channels = parser.parse(usPlaylist);
module.exports = {
channels
};
actions.js
When I try to make the import I get the error Uncaught TypeError: fs.readFileSync is not a function
const {channels} = require('../lib/utils/index.js');
You can't use fs package with Vue.js framework .Because fs is not frontend technology . Instead of that try to use AJAX call to solve your issue .

Metadata of ffmpeg is undefined in electron app

I correctly installed ffmpeg I'm able to check it by writing ffmpeg in cmd which give me this result
Now in my electron app in my index.html I'm geting input from user and sending custom event to electron side of app which lays in index.js entry point
index.html
<script>
const electron = require('electron');
const { ipcRenderer } = electron;
document.querySelector('form').addEventListener('submit', (e) => {
e.preventDefault();
const { path } = document.querySelector('input').files[0];
ipcRenderer.send('video:submit', path);
});
</script>
and using ffmpeg.ffprobe I'm trying to get metadata of video updated to input in electron side like so:
const electron = require('electron');
const ffmpeg = require('fluent-ffmpeg');
const { app, BrowserWindow, ipcMain } = electron;
app.on('ready', () => {
const mainWindow = new BrowserWindow({});
mainWindow.loadURL(`file://${__dirname}/index.html`);
});
ipcMain.on('video:submit', (event, path) => {
ffmpeg.ffprobe(path, (err, metadata) => {
console.log(metadata);
//console.log(metadata.format.duration);
});
});
And it console that metadata is undefined, when I uncomment console.log(metadata.format.duration) it says
typeError: cannot read property
'format' of undefined
What I'm doing wrong?
So I set two new environment variables and now other error occure when I console.log(error):
{ Error: spawn C:\Users\Borys\Documents\videoinfo\ffmpeg\bin ENOENT
at exports._errnoException (util.js:1024:11)
at Process.ChildProcess._handle.onexit (internal/child_process.js:192:19)
at onErrorNT (internal/child_process.js:374:16)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickCallback (internal/process/next_tick.js:180:9)
code: 'ENOENT',
errno: 'ENOENT',
syscall: 'spawn C:\\Users\\Borys\\Documents\\videoinfo\\ffmpeg\\bin',
path: 'C:\\Users\\Borys\\Documents\\videoinfo\\ffmpeg\\bin',
spawnargs:
[ '-show_streams',
'-show_format',
'C:\\Users\\Borys\\Documents\\portfolio\\img\\header_video.mp4' ] }`
( I had to paste it as code because it was saying that my post containt code that is not properly formatted)
Alright thanks to #Alexander Leithner and this question I figured it out. So error was my environment variables which should be:
FFMPEG_PATH with value of path to ffmeg.exe
FFPROBE_PATH with value of path to ffprobe.exe
PATH with value of C:.......\ffmpeg\bin

SyntaxError: Unexpected token using async and babel in koa

I have this simple app made using the last alpha version of Koa. In order to use `async/wait Babel.Js is required.
'use strict';
// babel registration (runtime transpilation for node)
require('./server.babel');
const Koa = require('koa');
const app = new Koa();
// define logger - this will be always executed
const logger = async (context, next) => {
const start = new Date;
await next();
const ms = new Date - start;
console.log(`${context.method} ${context.url} - ${ms}ms`);
}
const index = (context) => {
context.body = 'Hello World';
}
app.use(logger);
app.use(index);
app.listen(3000);
console.info(`The app is listening on port 3000`);
This is the hook to activate the transpiling.
const fs = require('fs');
let config;
try {
config = JSON.parse(fs.readFileSync('./.babelrc'));
} catch (error) {
console.error('==> ERROR: Error parsing your .babelrc.');
console.error(error);
}
require('babel-core/register')(config);
and this is the config file:
{
"plugins": ["transform-async-to-generator"]
}
Unfortunately when I try to run the project I get the following error:
const logger = async (context, next) => {
^
SyntaxError: Unexpected token (
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:404:25)
at Object.Module._extensions..js (module.js:432:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:313:12)
at Function.Module.runMain (module.js:457:10)
at startup (node.js:138:18)
at node.js:974:3
I have no idea why I get this error. I'm using the last Node.Js version 5.1.0 and Babel 6.2.1
You are getting the SyntaxError. That happens because your code is being parsed before Babel can intercept it and convert.
If you want to make async functions work in your first file, you should require this entire file after have registered its hook.
Create a new file start.js with the following
require('babel-register');
require('./index');
Your code in index.js can use async functions, but you can't do it in the start.js.
Also note, that you don't need to read .babelrc by yourself. Babel will do it for you by default.
Contents of .babelrc looks like this
{
"presets": [
"es2015",
"stage-3"
],
"plugins": [
[
"transform-runtime",
{
"polyfill": false,
"regenerator": true
}
]
]
}
Reference links
Async Functions with Babel
babel's require hook
upgrade nodejs version to v7.6.0 or higher

Categories