ElectronJS build doesn't include needed folder - node.js

I'm working on a ElectronJS and ExpressJS project to build an application that runs an API in background and show a system tray with some features to control and monitor that API.
"electron": "^4.0.4",
"electron-builder": "^20.38.5",
I use electron-builder to generate an installer for macOS, and Windows (.exe with nsis and .dmg) packages containing my express API built app as it is.
That's mean, I build it separately and call it's entry point build/index.js in my electron's main.js, Despite, that hook and everything else is fine in development env. But when i run the build, it show me that error:
A JavaScript error occurred in the main process
Uncaught Exception:
Error: Cannot find module 'express'
at Module._resolveFilename (internal/modules/cjs/loader.js:584:15)
at Function.Module._resolveFilename (/Users/username/WebstormProjects/my-api-monitor/release/mac/API monitor.app/Contents/Resources/electron.asar/common/reset-search-paths.js:43:12)
at Function.Module._load (internal/modules/cjs/loader.js:510:25)
at Module.require (internal/modules/cjs/loader.js:640:17)
at require (internal/modules/cjs/helpers.js:20:18)
at Object.<anonymous> (/Users/username/WebstormProjects/my-api-monitor/release/mac/API monitor.app/Contents/Resources/app/api/build/index.js:19:16)
at Object.<anonymous> (/Users/username/WebstormProjects/my-api-monitor/release/mac/API monitor.app/Contents/Resources/app/api/build/index.js:208:3)
at Module._compile (internal/modules/cjs/loader.js:693:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:704:10)
at Module.load (internal/modules/cjs/loader.js:602:32)
I guess the problem is that the node_modules of my API in /build folder isn't packaged in the app, and i can't achieve that with the normal way documented in electron-builder readme.
For more details, here is my files tree.
Also, my electron-builder config. :
"asar": false,
"files": [
"main.js",
"api/**/*",
"resources/**/*"
],
"directories": {
"buildResources": "resources",
"output": "release"
}
Same issue with or without asar, i jsut keep it false to check if folders and files are included right.
Any idea will be helpful.

Related

NestJS microservices "Cannot find module"

So, I'm trying to create my first microservice using NestJS, but the moment I try to run it, the service stops with this error:
[13:39:21] Found 0 errors. Watching for file changes.
Error: Cannot find module 'C:\Users\voryi\IdeaProjects\YWA\des_server\services\learning-service\dist\main'
at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
at Function.Module._load (node:internal/modules/cjs/loader:778:27)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12)
at node:internal/main/run_main_module:17:47
there's no main.js file in the first level of your dist directory. You can define the entry file by adding this to your nest-cli.json:
"entryFile": "learning-service/src/main"
the default is main
try npm run build and then restart your service
I use monorepo setup and this issue happens whenever I start the nestjs server from non-root folder by mistake.
Usually, removing the dist folder and restarting the nestjs server works for me.
In my case, the main.js file was inside src folder so I had to change the script to:
"start:prod": "node dist/src/main"
maybe simply use this inside the project,
npm i #nestjs/microservices

I have ERR_PACKAGE_PATH_NOT_EXPORTED error in a NestJS project if MikroORM upgraded to v5.1 and built with WebPack

I had a default NestJS project with MikroORM 4, build with WebPack.
The project has been created with:
nest new <project>
WebPack was activated when I added a library to the project - it's the default behavior of NestJS.
Then I migrated my project into MikroORM from 4.5 to 5.1 and now I have this error during start:
webpack 5.71.0 compiled successfully in 1338 ms
Type-checking in progress...
Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './typings' is not defined by "exports" in D:\a\_NEST8_MIKRO5\nest-mikro-test\node_modules\#mikro-orm\core\package.json
at throwExportsNotFound (internal/modules/esm/resolve.js:285:9)
at packageExportsResolve (internal/modules/esm/resolve.js:508:3)
at resolveExports (internal/modules/cjs/loader.js:450:36)
at Function.Module._findPath (internal/modules/cjs/loader.js:490:31)
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:888:27)
at Function.Module._load (internal/modules/cjs/loader.js:746:27)
at Module.require (internal/modules/cjs/loader.js:974:19)
at require (internal/modules/cjs/helpers.js:92:18)
at Object.#mikro-orm/core/typings (D:\a\_NEST8_MIKRO5\nest-mikro-test\dist\main.js:967:18)
at __webpack_require__ (D:\a\_NEST8_MIKRO5\nest-mikro-test\dist\main.js:1051:42)
No errors found.
WebPack was NOT added manually, it was provided by NestJS-CLI if you configure it in nest-cli.json:
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "#nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"webpack": true <<<<<<<<<<<<<<< WebPack enabled here
}
}
Project can be built successfully. This error comes during the startup.
The problem is related to WebPack. If it's disabled (in nest-cli.json) then it can run properly.
An option would be customizing somehow WebPack build but I don't know how to customize WebPack configured by NestJS-CLI (if it's possible would keep NestJS-CLI configured WebPack).
Is it possible to add custom WebPack config to NestJS-CLI?
You can download the project from here: https://github.com/tferi99/nest-mikro-test
You should not use deep imports for anything from MikroORM packages. If you need some symbol that is not exported, feel free to send a PR adding it to public exports.
Checking your reproduction, I found this place, where you import from #mikro-orm/core/typings instead of just #mikro-orm/core. The symbol is definitely exported EntityData from the root of the package.
https://github.com/tferi99/nest-mikro-test/blob/main/src/person/model/person.entity.ts#L2

Typescript build "Cannot find module", but only on a ubuntu server

I'm working on a node script and writing it in typescript. I've had no problems with running builds on my laptop (mac) or from my raspberry pi running raspbian.
I've gotten to the point where I want to set the codebase up on a digital ocean server that's running ubuntu. I moved the codebase up and ran my build script. The build completes successfully, but when I launch the node process I get the error:
node dist/server/source-server/index.js
internal/modules/cjs/loader.js:883
throw err;
^
Error: Cannot find module 'express'
Require stack:
- /var/www/binary-operations-presentation/multi-player-server/dist/server/source-server/index.js
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:880:15)
at Function.Module._load (internal/modules/cjs/loader.js:725:27)
at Module.require (internal/modules/cjs/loader.js:952:19)
at require (internal/modules/cjs/helpers.js:88:18)
at Object.<anonymous> (/var/www/binary-operations-presentation/multi-player-server/dist/server/source-server/index.js:6:35)
at Module._compile (internal/modules/cjs/loader.js:1063:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
at Module.load (internal/modules/cjs/loader.js:928:32)
at Function.Module._load (internal/modules/cjs/loader.js:769:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12) {
code: 'MODULE_NOT_FOUND',
requireStack: [
'/var/www/binary-operations-presentation/multi-player-server/dist/server/source-server/index.js'
]
}
It's weird. I've run this codebase on multiple servers and none have had this issue. I did some searching around, but all of the answers I've found are saying "run npm install express" or "run npm install #types/express", both of which I have:
Plus, if I didn't have them installed, the typescript compiler build would have failed.
I compared the file structure on the ubuntu server to my raspberry pi server and aside from the files that are generated when the codebase actually runs, the directories are the same:
Both servers have the same tsconfig.json file:
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"sourceMap": true,
"outDir": "../dist/server",
"rootDirs": ["./", "../project-common/"],
"strict": true,
"moduleResolution": "node",
"esModuleInterop": true,
"skipLibCheck": true,
"resolveJsonModule": true
}
}
And both have the same dependency versions:
// from package.json
{
...
"devDependencies": {
"#types/uuid": "^8.3.0",
"#types/ws": "^7.4.0",
"killport": "^1.0.1",
"nodemon": "^2.0.7",
"tsc-watch": "^4.2.9",
"tslint": "^6.1.3",
"typescript": "^4.1.3"
},
"dependencies": {
"#types/express": "^4.17.11",
"#types/lodash.clonedeep": "^4.5.6",
"#types/websocket": "^1.0.1",
"express": "^4.17.1",
"lodash.clonedeep": "^4.5.0",
"uuid": "^8.3.2",
"ws": "^7.4.2"
}
}
Neither of the dist folders have the node_modules folder, and when I look at the transpiled index.js file for the server they both import express the same way:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = __importDefault(require("express"));
const http_1 = __importDefault(require("http"));
and both of the index.js.map files refer to the same relative source directory:
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../source-server/index.ts"]
So I'm not sure why one server would be able to refer back to the node_modules folder but the other one wouldn't.
The only big difference (aside from the OS version, the server is running Ubuntu 20.04) that I see is that my raspberry pi is running node 15.x and the ubuntu is running node 14.x, though I don't know that that would necessarily cause this problem.
Any ideas?
UPDATE: same version of node
I tried making the version of node the same. I installed nvm on my raspberry pi, pulled in 14.6.0 (same version as the digital ocean server), rebuilt the project, and launched the server -> works fine.
so the node version doesn't seem to be a factor :/
So here's the snag and solution:
The gist is that the compiled version of the index file is firing a regular node require() function to pull in modules:
Which means it goes through a number of steps to find the modules. When it comes to possible node_modules modules, it looks for the node_modules folder in the current directory. If node doesn't find it, node will step up to the parent directory and look there, continuing to step back to the root directory if node_modules directories aren't found.
In my case, I previously had all of the server and client code at the same directory level (the directory where the new subfolders now live). When I separated the code into the subfolders, I forgot to blow away the old node_modules folder locally, which is why the dist folder still found the node_modules folder that now resided at the parent directory of dist. When I did a git pull on my raspberry pi, the folders updated, but because node_modules is part of my .gitignore, that folder at the parent level wasn't blown away.
But, in newer clones of the repository of course wouldn't have node_modules at that parent directory, or any other parent directory so they bombed out.
While talking with #cefn I realized that I did want to have the dist be a "everything needed to run this project" directory, so I added a step to my npm build script:
"scripts": {
"build": "tsc --build tsconfig.json && npm run build:move-indexes && npm run build:move-node_modules",
"build:move-indexes": "rsync -avz indexes ../dist/server/source-server",
"build:move-node_modules": "rsync -avz node_modules ../dist/server/source-server",
This way, every time I rebuild the source code, the server will sync the node_modules in the dist directory with the node_modules in my source directory.
Tried it out, and it works :)

Electron cannot open shared object file from node_modules folder

On electron, the node module vosk needs to access some shared objects located in node_modules/vosk/lib/.
The issue I am having right now is that, when I do require('vosk') in my main.js and try to execute my AppImage file, I get:
A JavaScript error occurred in the main process
Uncaught Exception:
Error: Dynamic Linking Error: /tmp/.mount_CantooClaxGf/resources/app.asar/node_modules/vosk/lib/linux-x86_64/libvosk.so: Cannot open the shared object: It's not a folder
at new DynamicLibrary (/tmp/.mount_CantooClaxGf/resources/app.asar/node_modules/ffi-napi/lib/dynamic_library.js:75:11)
at Object.Library (/tmp/.mount_CantooClaxGf/resources/app.asar/node_modules/ffi-napi/lib/library.js:47:10)
at Object.<anonymous> (/tmp/.mount_CantooClaxGf/resources/app.asar/node_modules/vosk/index.js:24:21)
at Module._compile (internal/modules/cjs/loader.js:1145:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1166:10)
at Module.load (internal/modules/cjs/loader.js:981:32)
at Module._load (internal/modules/cjs/loader.js:881:14)
at Function.Module._load (electron/js2c/asar.js:769:28)
at Module.require (internal/modules/cjs/loader.js:1023:19)
at require (internal/modules/cjs/helpers.js:77:18)
I tried to add vosk to the files in the build:
"build": {
"files": [
"dist/**/*",
"src/assets/icons/*",
"electron.js",
"package.json",
"assets/models/*",
"node_modules/vosk/lib/*"
],
I can now see the files in the app.asar.unpacked/node_modules/vosk/lib/ folder, but when executing the app, I'm still having the same error.
I found this answer mentioning a hack, but it didn't solve my issue and I still have the exact same error.
How am I supposed to package the shared objects in a way that vosk will find them?
I could solve the issue with this config for electron, putting all the dependencies of vosk in the extraResources field:
"build": {
"extraResources": [
"node_modules/at-least-node/**/*",
"node_modules/builder-util-runtime/**/*",
"node_modules/debug/**/*",
"node_modules/ffi-napi/**/*",
"node_modules/fs-extra/**/*",
"node_modules/get-symbol-from-current-process-h/**/*",
"node_modules/get-uv-event-loop-napi-h/**/*",
"node_modules/graceful-fs/**/*",
"node_modules/jsonfile/**/*",
"node_modules/ms/**/*",
"node_modules/node-addon-api/**/*",
"node_modules/node-gyp-build/**/*",
"node_modules/ref-napi/**/*",
"node_modules/ref-struct-di/**/*",
"node_modules/sax/**/*",
"node_modules/universalify/**/*",
"assets/models/**/*"
],
"files": [
"dist/**/*",
"src/assets/icons/*",
"electron.js",
"package.json"
],
I also needed this lib.
It's now working as expected
I solved by updating my electron-builder configuration in package.json to be
{
"build": {
"asar": true,
"asarUnpack": [
"node_modules"
],
}
}
Then ensuring the unpacked path was used instead:
var dirPath = __dirname.includes('.asar') ? __dirname.replace('.asar', '.asar.unpacked') : __dirname;

How to get semantic/gulp/webpack to work in electron-react-boilerplate

I am trying to port a react app to electron using electron-react-boilerplate but I'm using semantic-ui which suggested being set up with gulp. electron-react-boilerplate uses webpack to handle all of its packaging and I can't get webpack +gulp to work so everything will package in the electron app.
I'm trying this link that explains how to pipe webpack configs through gulp tasks but I'm getting an "unexpected token import" error from the webpack config.
.babelrc
{
"presets": ["es2015", "stage-0", "react"],
"plugins": ["add-module-exports"],
"env": {
"production": {
"presets": ["react-optimize"],
"plugins": ["babel-plugin-dev-expression"]
},
"development": {
"plugins": ["tcomb"],
"presets": ["react-hmre"]
},
"test": {
"plugins": [
["webpack-loaders", { "config": "webpack.config.test.js", "verbose": false }]
]
}
}
}
simple gulpfile.js straight from the link above:
var gulp = require('gulp');
var webpack = require('webpack-stream');
gulp.task('default', function() {
return gulp.src('src/entry.js')
.pipe(webpack())
.pipe(gulp.dest('dist/'));
});
the webpack dev file is here,
note some of the names are changed between this boilerplate version and my project but otherwise it's the same.
the error:
Configurator>gulp
[09:52:40] Using gulpfile C:\git\Configurator\gulpfile.js
[09:52:40] Starting 'default'...
[09:52:40] 'default' errored after 8.28 ms
[09:52:40] C:\git\Configurator\webpack.config.development.js:7
import webpack from 'webpack';
^^^^^^
SyntaxError: Unexpected token import
at Object.exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:513:28)
at Object.Module._extensions..js (module.js:550:10)
at Module.load (module.js:458:32)
at tryModuleLoad (module.js:417:12)
at Function.Module._load (module.js:409:3)
at Module.require (module.js:468:17)
at require (internal/module.js:20:19)
at Gulp.<anonymous> (C:\git\Configurator\gulpfile.js:7:18)
at module.exports (C:\git\Configurator\node_modules\orchestrator\lib\runTask.js:34:7)
the internet tells me that getting rid of the import errors should be as simple as using the 'es2015' preset in .babelrc but it's there and it's not helping.
I can get the dev server to work in the electron app with the semantic-ui stuff after the initial gulp build for semantic, but for some reason it doesn't build into the electron package when I try to package an installer to deploy this thing.
When I run the electron app dev server through webpack it works fine though, except I get two errors:
cannot set property exports of undefined
and
locals[0] does not appear to be a module object with hot module replacement API enabled
the latter stacktrace goes back to some semantic imports in one of my react files.
I'm totally at a loss as to how to make all this stuff work together.

Resources