How to include Node.js native modules while compiling to .exe - node.js

I'm using pkg to compile my Node.js project into an executable.
The project includes a native module called "node-printer".
Pkg has problems compiling this module, because when i run the executable i get this error:
pkg/prelude/bootstrap.js:1359
throw error;
^
.....
(internal/modules/cjs/loader.js:1218:10),Module.load (internal/modules/cjs/loader.js:1047:32)] {
code: 'MODULE_NOT_FOUND',
requireStack: [
'C:\\snapshot\\ckiosk\\node_modules\\printer\\lib\\printer.js',
'C:\\snapshot\\ckiosk\\controllers\\receiptController.js',
'C:\\snapshot\\ckiosk\\api\\ajax.js',
'C:\\snapshot\\ckiosk\\webApp.js',
'C:\\snapshot\\ckiosk\\main.js'
]
This is from the pkg readme:
Native addons (.node files) use is supported. When pkg encounters a .node file in a require call, it
will package this like an asset. In some cases (like with the bindings package), the module path is
generated dynamicaly and pkg won't be able to detect it. In this case, you should add the .node file
directly in the assets field in package.json.
Here is the pkg in my package.json file
"pkg": {
"scripts": [
"config/*.js"
],
"assets": [
"views/*",
"views/**/*",
"config/*",
"public/assets/**/*",
"node_modules/printer/lib/node_printer.node"
],
"targets": [
"node14-win"
]},
As you can see, i've included the node printer .node file in the assets, but the result is still the same.
What am i missing?

Turns out i have been using the wrong command to build.
I used this
pkg "main.js" -t node14-win -o build/ckiosk.exe
But to make use of the configuration in package.json we have to use
pkg .

Related

How to compile Node.js with figlet module from pkg?

After compiling via pkg and running the .exe, I got the error:
(node:17672) UnhandledPromiseRejectionWarning: Error: File 'C:\**\mytestapp\node_modules\figlet\fonts\Ghost.flf' was not included into executable at compilation stage. Please recompile adding it as asset or script.
my index.js and package.json: https://pastebin.com/vL4nZcZW
I tried to add the entire figlet module to the asset, reinstall it and pkg, but this did not work. I tried to compile with only one require. What am I doing wrong?

Intellisense for module-alias Package

I am using this npm module (module-alias)
https://www.npmjs.com/package/module-alias in my Node project.
To make use of this package you have to set path aliases in the package.json file.
However, using this package comes with the disadvantage, that intellisense doesn't work anymore.
My question is how to enable intellisense with those path aliases?
The problem is that you did not register those aliases anywhere with your linter. I would gerenally suggest to use ESLint here (even if you use TypeScript as TSLint will be discontinued in favour of ESLint). My examples will include the TypeScript endings as well. If you definately want to make it work for JavaScript only you can skip the .ts .tsx extentensions in the eslint) So to make intellisense work do this in
.eslintrc.js
settings: {
"import/resolver": {
alias : {
map: [
["#","./src"]
],
extensions: [".js", ".jsx", ".ts", ".tsx"],
},
}
},
Note that in this case you will need the import Plugin for ESLint. If you don't already have it install it.
If you are using TypeScript you will also have to make that alias known to your compiler. So add this to your
tsconfig.json
"compilerOptions": {
"baseUrl": ".",
"paths": [
"#/*" : [
"src/*"
]
]
}

How to bundle node project into one file

Is there any WORKING way how to bundle node project into one single file (including dependencies) and how?
I am using babel (.babelrc)
{
"presets": ["#babel/preset-env"],
"plugins": [
[
"module-resolver",
{
"root": [
"./src"
],
"alias": {
"test": "./test",
"underscore": "lodash"
}
}
]
]
}
the answer is no. babel can not do what you want by itself. It is a tool for transforming one dialect of Javascript into another, based on rules defined in your .babelrc file. It is a compiler, not a linker (to borrow terms from the C world).
Using babel-plugin-module-resolver will not cause babel to transpile dependencies as if they were source files. It is simply a babel rule which modifies the paths passed to require() or import.
To include dependencies as well as source files you need to use both a compiler like babel and a bundler such as webpack or rollup.

Package Node-Red using zeit/pkg

I am having some issues using zeit/pkg on my node-red project. Here are the steps to replicate the issue:
git clone https://github.com/node-red/node-red.git
cd node-red
npm install
npm run build
After build command I added the following to my package.json file:
"pkg": {
"assets": [
"./red/**/*"
],
"scripts": [
"./red/**/*.js"
]
}
Run the command pkg .
After running pkg . I get the following errors:
C:\xampp\htdocs\node-red>pkg .
> pkg#4.3.4
> Targets not specified. Assuming:
node8-linux-x64, node8-macos-x64, node8-win-x64
> Warning Cannot resolve 'path.join(__dirname, '..', '..', 'package.json')'
C:\xampp\htdocs\node-red\red\runtime\index.js
Dynamic require may fail at run time, because the requested file
is unknown at compilation time and not included into executable.
Use a string literal as an argument for 'require', or leave it
as is and specify the resolved file name in 'scripts' option.
> Warning Cannot resolve ''./' + aSettings.storageModule'
C:\xampp\htdocs\node-red\red\runtime\storage\index.js
Dynamic require may fail at run time, because the requested file
is unknown at compilation time and not included into executable.
Use a string literal as an argument for 'require', or leave it
as is and specify the resolved file name in 'scripts' option.
> Warning Cannot resolve 'relPath'
C:\xampp\htdocs\node-red\red\runtime\nodes\registry\loader.js
Dynamic require may fail at run time, because the requested file
is unknown at compilation time and not included into executable.
Use a string literal as an argument for 'require', or leave it
as is and specify the resolved file name in 'scripts' option.
Running the exe after the pkg command gives me this error:
Node-RED has not been built. See README.md for details
Any help would be greatly appreciated. It seems like a simple path issue but I can't seem to get it working.

Bazel doesn't find tensorflow packages for C++ example code

I try to make this example work, but everytime I try to build the program with bazel I get this error message:
bazel build //code:label_image
ERROR: /home/jonas/tensorflow/code/BUILD:12:1: no such package 'tensorflow': BUILD file not found on package path and referenced by '//code:label_image'.
ERROR: /home/jonas/tensorflow/code/BUILD:12:1: no such package 'tensorflow': BUILD file not found on package path and referenced by '//code:label_image'.
ERROR: /home/jonas/tensorflow/code/BUILD:12:1: no such package 'tensorflow': BUILD file not found on package path and referenced by '//code:label_image'.
ERROR: /home/jonas/tensorflow/code/BUILD:12:1: no such package 'tensorflow': BUILD file not found on package path and referenced by '//code:label_image'.
ERROR: /home/jonas/tensorflow/code/BUILD:12:1: no such package 'tensorflow': BUILD file not found on package path and referenced by '//code:label_image'.
ERROR: Analysis of target '//code:label_image' failed; build aborted.
INFO: Elapsed time: 1.261s
I saved the exact source code from github in a directory called code. I installed tensorflow in an (active) virtual environment via pip: pip3 install --upgrade tensorflow. I use arch linux.
Why doesn't bazel find the proper packages? I'm quite new to bazel/tensorflow. Where are these packages saved? Do I have to specify them explicitely somewhere?
Typically, extracting a subfolder from a project that uses Bazel and building it separately does not work.
If you look into the BUILD file of the label_image folder, you will see this definition for a C++ binary:
cc_binary(
name = "label_image",
srcs = [
"main.cc",
],
linkopts = select({
"//tensorflow:android": [
"-pie",
"-landroid",
"-ljnigraphics",
"-llog",
"-lm",
"-z defs",
"-s",
"-Wl,--exclude-libs,ALL",
],
"//conditions:default": ["-lm"],
}),
deps = select({
"//tensorflow:android": [
# cc:cc_ops is used to include image ops (for label_image)
# Jpg, gif, and png related code won't be included
"//tensorflow/cc:cc_ops",
"//tensorflow/core:android_tensorflow_lib",
# cc:android_tensorflow_image_op is for including jpeg/gif/png
# decoder to enable real-image evaluation on Android
"//tensorflow/core/kernels:android_tensorflow_image_op",
],
"//conditions:default": [
"//tensorflow/cc:cc_ops",
"//tensorflow/core:core_cpu",
"//tensorflow/core:framework",
"//tensorflow/core:framework_internal",
"//tensorflow/core:lib",
"//tensorflow/core:protos_all_cc",
"//tensorflow/core:tensorflow",
],
}),
)
This rule tells Bazel what the label_image binary requires to be built. Notably, it has dependencies (deps) and link options (linkopts) that point to the root of the tensorflow workspace (//tensorflow, defined by the WORKSPACE file), which is missing from your extracted subfolder. This is the reason why Bazel is complaining that it cannot find the package tensorflow.
The easiest way to build the label_image binary is to build it from within the tensorflow project, since the paths are already set up.

Resources