Giter Site home page Giter Site logo

caxa's People

Contributors

leafac avatar maxb2 avatar rnreekez avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

caxa's Issues

stub--win32--ia32 is not supported

How can I build an app for windows x86?

build-err Stub not found (your operating system / architecture may be unsupported): β€˜C:\Workspace\hypercore-fox-helper\node_modules\caxa\stubs\stub--win32--ia32

Increase compression ratio

If I use pkg for my project, I get an executable with a file size of 85 MB, with caxa I get an executable with a file size of 32MB. So, the caxa result looks quite good. But when I 7-zip both with maximum compression level, the caxa binary is still at 30 MB while the pkg binary is at 17 MB.

When I start the executable created with caxa to get the extracted files in the tmp folder (80 MB) and then run 7-zip over the extracted files, I get a *.7z file of 17 MB again.

It looks like the compression used internally by caxa is not as efficient as 7-zip and cannot be improved by running 7-zip again (32 MB --> 30 MB).

Is it possible to use a more aggressive compression setting during the caxa run? 17 MB vs. 30 MB is nearly 50%, the smaller file size would be helpful when you need to download the executable with a slow/limited internet connection.

Customizable extraction directories?

Is there a reason that you rely strictly on leveraging mktemp or os.tempdir?

This poses issues when the /tmp mount is set to noexec, and it also has issues because of selinux policy issues with /tmp as well.

Is there a reason that this is default non modifiable behavior?

I would be more than happy to write a small update that allows customizable paths for extraction locations but I'm not sure if there's a reason you specifically do that before I spend time on it

macos executable can't be code-signed

I think all bundlers have gone through this.

An executable packaged with caxa on maOS with the following command:
caxa -i bundle -o myclitool -- "{{caxa}}/node_modules/.bin/node" "{{caxa}}/main.js"
while works as expected, can't be signed like so:
codesign --deep --force --options=runtime --entitlements ./entitlements.plist --sign [MASKED] --timestamp myclitool

An attempt to sign produces an error: myclitool: main executable failed strict validation

Similar error has haunted vercel/pkg but was fixed there with this PR, which might provide a hint on why this is happening.

Thanks in advance for any suggestions on how to work around this.

I am so confused - how to build for Linux Arm64?

Hey there, apologies for my comments but I find the API of this package to be very confusing.

I do not understand the syntax at all or how to build for a specific target.

I am on MacOS, Apple M1, trying to build for raspberry pi Arm64 arch.

Please advise what the correct CLI syntax is.

Please help and apologies again.

caxa 2.0.0 postinstall never run properly

postinstall never run: https://github.com/leafac/caxa/releases/download/v${package.version}/${stubName}
Does this repo have any release? and... for some reasons, github cannot be connected in some times in china.

Not working on windows with powershell

See my job: https://github.com/kkoomen/vim-doge/runs/2050697059?check_suite_focus=true

D:\a\vim-doge\vim-doge\node_modules\.bin\caxa:2
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
          ^^^^^^^

SyntaxError: missing ) after argument list
    at Module._compile (internal/modules/cjs/loader.js:723:23)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)
    at startup (internal/bootstrap/node.js:283:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:623:3)

My job basically calls npm run build:binary:windows (see here) and then this script is running ./scripts/build.ps1#L12.

EDIT: this is a weird bug and I guess it's not your problem though.

Permission denied at /tmp/caxa - Multi user problem in linux

Hi,
I just got this error when my CI tried to execute my binary:
2022/04/13 09:12:57 caxa stub: Failed to create the lock directory: mkdir /tmp/caxa/locks/myprogram/7qsvoyerli: permission denied

When I was trying my binary without CI, I used myuser, so caxa created a /tmp/caxa folder with drwxr-xr-x 4 myuser myuser permissions.

But when the CI user wanted to create the lock directory, it failed because the permissions of the caixa directory are not open enough for ciuser.

As a workaround I just chmod 777 -R /tmp/caxa/, but not sure if that could work for all caxa users, maybe some users want to scope the programs per user? Or a shared (with 777) for multi user programs?

`Error: Cannot find module` after using the binary normally

I can use the binary normally after compiling it, but if I close it and open after some time (if I just reopen it will still work), it will show this error:

node:internal/modules/cjs/loader:936
  throw err;
  ^

Error: Cannot find module './xhr-sync-worker.js'
Require stack:
- C:\Users\Italo\AppData\Local\Temp\caxa\applications\trackfy-agent\kuyponmawv\0\node_modules\jsdom\lib\jsdom\living\xhr\XMLHttpRequest-impl.js
- C:\Users\Italo\AppData\Local\Temp\caxa\applications\trackfy-agent\kuyponmawv\0\node_modules\jsdom\lib\jsdom\living\generated\XMLHttpRequest.js
- C:\Users\Italo\AppData\Local\Temp\caxa\applications\trackfy-agent\kuyponmawv\0\node_modules\jsdom\lib\jsdom\living\interfaces.js
- C:\Users\Italo\AppData\Local\Temp\caxa\applications\trackfy-agent\kuyponmawv\0\node_modules\jsdom\lib\jsdom\browser\Window.js
- C:\Users\Italo\AppData\Local\Temp\caxa\applications\trackfy-agent\kuyponmawv\0\node_modules\jsdom\lib\api.js
- C:\Users\Italo\AppData\Local\Temp\caxa\applications\trackfy-agent\kuyponmawv\0\dist\src\bjShare\BjShare.js
- C:\Users\Italo\AppData\Local\Temp\caxa\applications\trackfy-agent\kuyponmawv\0\dist\src\queue\workers\lookForNewProspectsOnBjShare.worker.js
- C:\Users\Italo\AppData\Local\Temp\caxa\applications\trackfy-agent\kuyponmawv\0\dist\server\index.js
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.resolve (node:internal/modules/cjs/helpers:108:19)
    at Object.<anonymous> (C:\Users\Italo\AppData\Local\Temp\caxa\applications\trackfy-agent\kuyponmawv\0\node_modules\jsdom\lib\jsdom\living\xhr\XMLHttpRequest-impl.js:31:50)
    at Module._compile (node:internal/modules/cjs/loader:1101:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.<anonymous> (C:\Users\Italo\AppData\Local\Temp\caxa\applications\trackfy-agent\kuyponmawv\0\node_modules\jsdom\lib\jsdom\living\generated\XMLHttpRequest.js:655:14) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    'C:\\Users\\Italo\\AppData\\Local\\Temp\\caxa\\applications\\trackfy-agent\\kuyponmawv\\0\\node_modules\\jsdom\\lib\\jsdom\\living\\xhr\\XMLHttpRequest-impl.js',
    'C:\\Users\\Italo\\AppData\\Local\\Temp\\caxa\\applications\\trackfy-agent\\kuyponmawv\\0\\node_modules\\jsdom\\lib\\jsdom\\living\\generated\\XMLHttpRequest.js',
    'C:\\Users\\Italo\\AppData\\Local\\Temp\\caxa\\applications\\trackfy-agent\\kuyponmawv\\0\\node_modules\\jsdom\\lib\\jsdom\\living\\interfaces.js',
    'C:\\Users\\Italo\\AppData\\Local\\Temp\\caxa\\applications\\trackfy-agent\\kuyponmawv\\0\\node_modules\\jsdom\\lib\\jsdom\\browser\\Window.js',
    'C:\\Users\\Italo\\AppData\\Local\\Temp\\caxa\\applications\\trackfy-agent\\kuyponmawv\\0\\node_modules\\jsdom\\lib\\api.js',
    'C:\\Users\\Italo\\AppData\\Local\\Temp\\caxa\\applications\\trackfy-agent\\kuyponmawv\\0\\dist\\src\\bjShare\\BjShare.js',
    'C:\\Users\\Italo\\AppData\\Local\\Temp\\caxa\\applications\\trackfy-agent\\kuyponmawv\\0\\dist\\src\\queue\\workers\\lookForNewProspectsOnBjShare.worker.js',
    'C:\\Users\\Italo\\AppData\\Local\\Temp\\caxa\\applications\\trackfy-agent\\kuyponmawv\\0\\dist\\server\\index.js'
  ]
}

My solution then is to delete the temp folder C:\\Users\\Italo\\AppData\\Local\\Temp\\caxa\\applications\\trackfy-agent so I can use it once more. But the error repeats every time.

So it goes like this:

1 - I open the binary for the first time, use it normally.
2 - I then close it for the day.
3 - The next day, this error shows up.
4 - I delete the temp folder, and we go back to step 1.

Feature request: file for exclusions, configuration file

Hi,

because I cannot clean up my working directory (remove .git a.s.o.) I have rather many "-e" parameters.

It would be great, if caxa could support something like .caxaignore, in order to avoid those numerous "-e" parameters.

Also a configuration file would be nice, because command lines become rather long, if, say, you don't want to include node, don't want to dedupe, have prepare command and long special start commands.

Thanks

'Cannot find module' when module names start with @ sign

For example i have an application, that uses nestjs.
There are many imports like this: import { Logger } from '@nestjs/common'; with an starting @ sign in the module name.

If i run the (caxa-) executable, then i will become the error: Error: Cannot find module '@nestjs/common'

I've tried this with other modules but only get this error when the module names start with @ sign?!

devDependencies are part of the binary

@leafac
What a cool project! Thank you very much for your work on this. Once ARM support is ready it is a very interesting alternative to pkg although the source code is not hidden and must be evaluated first.

After some tests with my project on Linux I found out that all of my devDependencies are part of the resulting binary (file size is ca. 42 MB, ca. 160 MB after extraction). In the README you write:

You don’t need to npm prune --production and npm dedupe, because caxa will do that for you from within the build directory. (Otherwise, if you tried to npm prune --production you’d uninstall caxa, which should probably be in devDependencies.)

but this seems not to be the case for me. My current workaround:

  1. Install caxa globally with npm install -g caxa
  2. Delete the node_modules folder of my project, it seems to be unused by caxa
  3. Delete the devDependencies section in my package.json
  4. Run caxa as recommended, this seems to cause the installation of all remaining dependencies from package.json in the build directory of caxa.

Now, I get a working binary with file size of ca. 15 MB (ca. 39 MB after extraction). The result is impressive. Is there something wrong with this approach to avoid the devDependencies?

{{caxa}} resolves strangely on Windows

I am trying to get caxa working on Windows - using bb (babashka) instead of node (I think that isn't relevant here).

Creating my bundle with
npx caxa --input bundle --output orch.exe --no-include-node -- "{{caxa}}\bb.exe" "--config {{caxa}}\lovoonl-orch.edn"
I get File does not exist: --config D:\Users\T06057A\AppData\Local\Temp/caxa/applications/orch\jwegaatqat/0\lovoonl-orch.edn

Note the mix of path separators! It seems {{caxa}} is resolved strangely on Windows...

Hide console window

Is there any possible way to hide the console of an application compiled with caxa ,either a third party package or a feature built into caxa.

Brotli and/or zstd, too?

@leafac Thanks a bijillion for starting this project; the outline looks great and I trust that you in particular have spent some time thinking about the tradeoffs!

In vercel/pkg#837 (comment), you mention that the self-extracting archive uses gzip, which is great. It was unclear to me if this applies to the Node binary or the user assets or both, but either way, I would encourage offering brotli and/or zstd as configurable options for the compressor. Brotli in particular offers an extremely good compression ratio while still being very fast to decompress β€” the tradeoff is longer compression time, but this is the ideal tradeoff for an app release build: it takes longer on the GitHub Actions runner, but results in a significantly smaller binary that is still near-instant to decompress.

If you need more convincing, I can pull up some hard numbers. :)

And thanks again for starting caxa! I love the name and story, and please provide some pronunciation tips for non-Portuguese-speakers! ;)

Windows binary MODULE_NOT_FOUND

See dungeon-revealer/dungeon-revealer#1545.

Windows is periodically deleting individual files from the temporary directory that the caxa binary is extracted into.
This means that the extracted node binary tries to run in a broken project directory which throws MODULE_NOT_FOUND errors. The current workaround for our project is to delete the caxa temporary directory and rerun the initial extraction. This only works for us because we don't store the user data in the caxa temporary directory.

Example error:

D:\DnD\Dungeon Revealer>"D:\DnD\Dungeon Revealer\dungeon-revealer-windows.exe"
node:internal/modules/cjs/loader:930
  throw err;
  ^

Error: Cannot find module 'C:\Users\SCrid\AppData\Local\Temp\caxa\applications\dungeon-revealer-windows\3bn3q6shhl\0\server-build\index.js'
←[90m    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:927:15)←[39m
←[90m    at Function.Module._load (node:internal/modules/cjs/loader:772:27)←[39m
←[90m    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:79:12)←[39m
←[90m    at node:internal/main/run_main_module:17:47←[39m {
  code: ←[32m'MODULE_NOT_FOUND'←[39m,
  requireStack: []
}

Could caxa be generalized to package other binary projects + their project sources?

Caxa works very well for Node.js projects. I've packaged my ClojureScript interpreter (as a Node.js library) with it and it runs fine:

https://github.com/babashka/nbb/tree/main/doc/caxa

I have another Clojure interpreter project where the interpreter itself is already a binary:

https://github.com/babashka/babashka

The binary is called bb and you would call it with:

bb foo.clj

for example.

Perhaps caxa could support a more general approach than only packaging Node.js applications since the problem is very similar to if I would want to package babashka + some foo.clj script.

Source code protection

Any chance to have this feature? pkg works well with this but they don't support ESM yet!

FYI about ESM

Hi! I just read Caxa's readme, haven't tried the project yet, but if I'm not mistaken, I think Caxa might be the only Node packaging system capable of natively supporting ESM and import.meta! At least that's what I think based on reading the readme section about how it works.

Of course any packer can support ESM and import.meta when using a bundler before packing, so here I was only looking at native support.

I'm sharing this because I think you might want to add it to the Features section, as another selling point. If Caxa truly does support this, it's amazing news for packing vanilla Node projects using ESM.

Add support for custom icons

From the readme:

Features to Consider Implementing in the Future

If you’re interested in one of these features, please send a Pull Request if you can, or at least reach out to me and mention your interest, and I may get to them.

[...]

  1. Add support for custom icons [...]

Just reaching out to mention that I am very interested in the feature of custom icons.

No such thing as `npm dedupe --production` ?

caxa v1 would run npm prune --production followed by npm dedupe:

https://github.com/leafac/caxa/blob/v1.0.0/src/index.ts#L33-L34

  await execa("npm", ["prune", "--production"], { cwd: appDirectory });
  await execa("npm", ["dedupe"], { cwd: appDirectory });

caxa v2 changed it to npm dedupe --production, which I suspect may have been an accident / mistake -- was it?

https://github.com/leafac/caxa/blob/v2.0.0/src/index.ts#L67-L68

  if (dedupe)
    await execa("npm", ["dedupe", "--production"], { cwd: buildDirectory });

I gather that npm dedupe --production does not print any error messages, but perhaps the --production flag is silently ignored? In my use case (balena CLI), npm prune --production makes a big difference (prunes some 200MB of dev dependencies), while npm dedupe (with or without --production) only serves to "slightly break" the npm-shrinkwrap.json file (which can be fixed by subsequently running npm install).

If the intention was to run npm prune --production instead of npm dedupe --production, then a fix would be to replace dedupe with prune, but a complication is that caxa v2 also introduced a new --dedupe flag. Renaming it --prune would technically be a breaking change. An alternative would be to add yet another flag, --prune, and separate the prune and dedupe steps as was the case in caxa v1.

High vulnerability in `download` dependency

When installing caxa, it introduces a high vulnerability from the download dependency.

$ npm i
npm WARN deprecated [email protected]: request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142
npm WARN deprecated [email protected]: Please see https://github.com/lydell/urix#deprecated
npm WARN deprecated [email protected]: this library is no longer supported
npm WARN deprecated [email protected]: https://github.com/lydell/resolve-url#deprecated
npm WARN deprecated [email protected]: request has been deprecated, see https://github.com/request/request/issues/3142

> [email protected] postinstall
> node postinstall.js


> [email protected] prepare
> tsc


added 695 packages, and audited 696 packages in 8s

30 packages are looking for funding
  run `npm fund` for details

7 vulnerabilities (2 moderate, 5 high)

To address issues that do not require attention, run:
  npm audit fix

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

An issue has been raised in the official repo:
kevva/download#216

commander package tries to use additional flags

Maybe where is a nice trick, but I suppose the commander package is very ordinary and greedy. If I add flags for node.exe in the command, it tries to use them.

Example:
npx caxa --directory "." --command "{{caxa}}/node_modules/.bin/node.exe" "--experimental-json-modules" "{{caxa}}/src/index.mjs" --output "caxa-test.exe"
The Output (from commander) is:
error: unknown option '--experimental-json-modules'

Obviously, I'm not the first to have the problem and the behavior has probably changed several times: tj/commander.js#922
I would like to suggest switching to yargs, which is much more sophisticated and already deals with the problem: https://github.com/yargs/yargs/blob/HEAD/docs/tricks.md#quotes

libatomic.so.1: cannot open shared object file: No such file or directory

I don't think this a bug with caxa (it depends on one's point of view!), yet I think it is an issue that caxa users will come across. For one, I am still looking for a convenient solution (that didn't require me to compile Node.js from source).

I have created a caxa-based executable for my app, for ARM v7. Then, when trying to run it in a Docker container for the ARM platform, I got the following error regarding a missing shared library:

$ docker run -it --platform linux/arm/v7 -v ~/Downloads:/mnt/Downloads debian:10 /bin/bash

root@1f0afeb707aa:/# /mnt/Downloads/my-armv7-caxa-app
... node_modules/.bin/node: error while loading shared libraries: 
    libatomic.so.1: cannot open shared object file: No such file or directory

I believe that the problem is that, when creating the caxa executable, I was using a standard Node.js installation that uses shared / dynamically linked libraries. Then caxa bundled in the base Node.js executable, but not the shared libraries. For the libatomic.so.1 library in particular, the error above can be avoided if the end users of my app install the library before running the caxa-based executable:

apt-get update && apt-get install -y libatomic1

However, at least my use case for caxa is to simplify end users' life by avoiding pre-requisites like installing Node.js (#20), "just download this executable and run it", and if I had to ask end users to install shared libraries before running the caxa executable, it would spoil the experience.

I assume that the solution is to use a fully statically compiled version of Node.js (including libatomic.so.1) when creating the caxa executable. Where to find that though? For all architectures supported by caxa: x64, ARM v6, ARM v7, ARM 64. I gather that the standard Node.js builds offered for download are dynamically linked: https://nodejs.org/en/download/

integrate rcedit for windows exe modification

it would be amazing if you could integrate rcedit
it allows for modification of the windows exe, so display stuff like company name, version number, icon, etc...
the raw exe is located here - https://github.com/electron/rcedit
but they also have a nodejs module too - https://github.com/electron/node-rcedit
currently i have to run 2 seperare functions
npm run build to make my caxa file and then run npm run windows to modifiy the file to add extra info

Windows Binary Issues, and workflow improvements

Windows Binary issues

First of all, some AV engines don't like Caxa's stub binary without any extra data, as seen in these results. (Windows.exe from GitHub)
https://www.virustotal.com/gui/file/0754d487f128d0fa236f559c9bcbeff71bff3245ab518c0056a40d5ae25b97d1/detection

However, the main issue is with the final compiled binary and Windows Defender, as it detects Caxa binaries as malware due to the self-extracting nature of them.

The resulting exe will sometimes refuse to run, or be deleted completely. Checking the Defender logs revealed that Windows had detected the output file as both Program:Win32/Wacapew.C!ml and Trojan:Win32/Wacatac.B!ml on separate occasions.

This is nothing to do with my own code, as any code causes the AV to trip a false positive. WinRAR's self extracting archives on silent mode do the same thing.

Workflow improvements

My build workflow uses a script to copy node_modules, index.js and a custom native module into a folder, then runs Caxa in that folder, creating the binary. If I don't do this, then package.json, readme.md and other files are also included in the final build.

    "build": "node-gyp rebuild --verbose && copy build\\Release\\addon.node out\\addon.node && npm run buildfolder",
    "buildfolder": "(robocopy node_modules out\\node_modules /E) ^& IF %ERRORLEVEL% LEQ 1 exit 0",
    "postbuildfolder": "move index.js out",
    "postbuild": "npx caxa -d out --command {{caxa}}/node_modules/.bin/node {{caxa}}/index.js --output app.exe && move app.exe out"

Please make it so I can specify what files to include in the final exe from within package.json instead of relying on custom scripts and copying lots of files. PKG does this with the "files" section: maybe read from this section as most programs already have this filled in.

Overall, my experience with Caxa has been mostly positive as it finally allows for embedding files into my packaged executable, but it could definitely use some improvements.

Typescript 4.4 incompatibility

Hi, just a heads up. Since caxa requires execution of the prepare npm script as part of install, there are now errors being thrown at installation. This one a little tough too because I work exclusively on a mac and i've only encountered this on Windows boxes.

$ yarn install --frozen-lockfile
yarn install v1.22.11
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
$ tsc
Error: src/index.ts(329,27): error TS2571: Object is of type 'unknown'.
error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
Error: Process completed with exit code 1.

I ran into this on my own project and I believe it boils down to whether or not the workspace is leveraging Typescript 4.4.

Snippet throwing compile error: https://github.com/leafac/caxa/blob/main/source/index.ts#L317-L319
Change introduced with TS 4.4

If i'm not mistaken this is now the default behavior if your tsconfig file is set to "strict".

I'm thinking you'll either want to pin the version of typescript or go ahead and add the type check within the snippet.

Getting the location of the binary

My program requires a configuration file which is placed in the same directory as the executable, however the executable won't necessarily be executed from within that directory, it's intended to be a command-line utility placed in the PATH.

As a result, the cwd of the node environment will not be sufficient to be able to parse the config file.

This is possible with pkg through the use of process.execPath, this returns the path to the node.exe in the caxa temp directory in a caxa package, however.

I'm not certain how something along these lines would even be possible with caxa's design, but i've thought of the following two temporary solutions:

  • Add a shortcut like {{caxa}} which can be used to pass the path to the executable into the command
  • Add the ability to mark specific files as assets on build, symbolically linking them into the temp directory when the executable is launched

ARM architecture support

I have Raspberry pi 3 b+ board and I am trying to use caxa on it. I've compiled examples and it shows an error:
bash: ./echo-command-line-parameters: cannot execute binary file: Exec format error.
file ./echo-command-line-parameters gives an output:
ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=ALTTohZDVVCYbbGb20Qi/X-X6HXeYwbH84AVQlSaQ/0RzAyRSxhi0ygj4oAFbv/ywg9-ioLknP7q7VwDKv0, not stripped
Is it possible to create execurable for ARM instead of x86-64?

default export does not work as expected

In a *.js file (CommonJS)

const caxa = require('caxa')
caxa(...).catch(err => console.log(err.message))

results in: ERROR, caxa is not a function

The same is true for a *.mjs (ESM) file with import syntax.

Instead, this works for me:

const caxa = require('caxa').default
caxa(...).catch(err => console.log(err.message))

Building Executable On Windows Creates Extremely Large File

I have a very simple node app/ESM meant to be run from the command line with 1 entry point, index.js.

I am running caxa in the root folder of the project with the command caxa --input . --output build.exe -- "{{caxa}}/node_modules/.bin/node" "{{caxa}}/index.js"

This process takes several minutes and then produces a 14.6 GB executable. Running that executable from either the command line or by double-clicking causes Windows to show an error message: "This app can't be run on this version of Windows"

caxa version: 2.1.0
Windows 10
Node version: 17.3.0
NPM version: 8.5.0

[Feature] Run minimized

Hi,
Thanks for this great tool! It works perfektly with the serialport dependency πŸ˜ƒ

I have an idea for a cool feature (and I believe this could be implemented in the go part):
I'd like to not show the black terminal window to the user. Instead, I'd like to have a little tray icon in the taskbar which shows that the app is running.
Maybe it could habe a context menu with Quit and Show logs / output entries.

What do you think?

Static assets

How do I include static assets like a sample txt file and read it?

[Feature] Allow specifying alternative extraction / temporary directory

The Readme file reads:

To Where Are the Packages Uncompressed at Runtime?
It depends on the operating system. You may find the location on your system with:
$ node -p "require(\"os\").tmpdir()"
Look for a directory named caxa in there.

Temporary directories are, well, temporary, and may get deleted when the user logs out or reboots the machine, depending on system configuration. I'd like to avoid that, to avoid the occasional performance hit which would be bad UX for end users (and might be "mysterious" to them). My app has hundreds of megabytes in node_modules and the runtime extraction time is non trivial (in excess of 10 seconds in a fairly fast machine with a SSD disk, possibly 30+ seconds in a slow machine).

  • A flag of the caxa command line could allow specifying an alternative folder (other than "require(\"os\").tmpdir()"). Say, --extract-dir /usr/local/lib/myApp.
  • In addition, a {{PREFIX}} string could be replaced at runtime with the value of the PREFIX environment variable, with a default value specified as {{PREFIX=/default/prefix}}.

Examples:

$ caxa --extract-dir "C:\Program Files\myApp" ...
$ caxa --extract-dir "/opt/myApp" ...
$ caxa --extract-dir "{{PREFIX=/usr/local}}/lib/myApp" ...

In the last example above, at runtime, if the PREFIX environment variable was defined and set to '/usr', then the app would be extracted to /usr/lib/myApp. If the PREFIX environment variable was not defined, or if it was defined and set to /usr/local, then the app would be extracted to /usr/local/lib/myApp.

I appreciate that extracting to a folder like /usr/local would require superuser privileges / sudo. That's OK.


Rationale
I was thinking of using caxa as a sort of "installer" for my app. I would set the --command entrypoint to a short JavaScript module (part of the app) that would additionally create a symlink or file at, say, /usr/local/bin/myApp that would look like:

#!/usr/bin/env sh
/usr/local/lib/myApp/node_modules/.bin/node /usr/local/lib/myApp/bin/main.js

Or some variation of this. Then running myApp on a command prompt would execute /usr/local/bin/myApp, and in turn /usr/local/lib/myApp/node_modules/.bin/node .... One could even consider that caxa could provide a standard "installer mode" feature that would do just that, but this is probably for some other feature request. :-)

"If you just want caxa to extract / install the app, why not just use a traditional installer?" Well, that's what I'm currently doing on Windows (NSIS) and macOS (pkgbuild), but I am currently considering the options on Linux and every option I came across had some drawbacks, for example:

  • .AppImage (squashfs) depends on fuse which in turn requires a Docker container to run in privileged mode.
  • apt install myApp Γ  la Spotify requires setting up repository keys and is not available on some Linux distributions.
  • pkg has the complications listed in caxa's Readme and the latest versions have some bugs related to fs promises and native node modules. I have used pkg for years but found myself spending a lot of time chasing bugs because of the modifications that pkg makes to Node.js.
  • Plain shell scripts tend to snowball into large files full of corner cases depending on whether curl or wget or bash or POSIX sh or apt or apk are available, "unless it's Arch Linux or Fedora or"... And I'd rather code in JavaScript, like the rest of the app.
  • Snap and Flatpak depend on daemons / systemd / d-bus ...

At which point I came across caxa and thought, "this might just do the trick!" Simple enough and universal enough, especially with the upcoming ARM support in issue #4. :-)

API usage in ESM module: TypeError: caxa is not a function

In an ESM module file, say test.mjs,

import caxa from 'caxa'

caxa({
    input: '.',
    output: 'out.exe',
    command: ['node', 'index.js']
})

caxa cannot be called: node test.mjs shows "TypeError: caxa is not a function".

I would assume, it's related to how

export default async function caxa({...

is handled. Maybe you find a better way to be ESM compatible.

Use `yarn --production` instead of `npm dedupe --production`

Hi,

caxa looks great - thanks! It seems a bit slow to start the application (on Windows). I'm not sure why (may be Defender). But that's quite another story.

The ready-built package will contain a package-lock.json, which may collide with using yarn (apart from enlarging the package). Apparently the file is created by npm dedupe --production.

npm dedupe also recreates node_modules which are intentionally removed with yarn PNP.

So caxa could support another commandline option (like --yarn) to run yarn --production instead of npm dedupe --production.

Edit: so well, with yarn3 yarn --production should not be used as it seems - instead it's more complicated: https://yarnpkg.com/cli/workspaces/focus

Binary execution fails on local dependencies

I have been trying to package an application from our monorepo with caxa, but it's failing on all local/path dependencies.

We have a couple of dependencies declared like this:

"dependencies": {
  "@evl/auth": "file:../libs/js/auth",

The resulting namespace in node_modules is populated with symlinks:

> ls -la node_modules/@evl
lrwxrwxrwx   1 m0ar m0ar    21 28 jan 23.29 auth -> ../../../libs/js/auth

The resulting error when executing with ts-node:

/tmp/caxa/applications/evl-linux/lobj3j8zbp/0/node_modules/ts-node/src/index.ts:750
    return new TSError(diagnosticText, diagnosticCodes);
           ^
TSError: β¨― Unable to compile TypeScript:
../../../../../../tmp/caxa/applications/evl-linux/lobj3j8zbp/0/src/<file>.ts:1:38 - error TS2307: Cannot find module '@evl/auth' or its corresponding type declarations.

1 import { <function> } from '@evl/auth

I would suspect caxa does not follow symlinks when including bundling the dependencies.

  • Is this assumption correct?
  • Is there a workaround I can apply?
  • Is this fixable in caxa? If you can describe the fix at a high level, I can look at authoring a PR. :)

Support yarn zip dependencies

Yarn 2 and 3 let you replace node_modules with each dependency being a single zip file. It's much cleaner and makes for faster installation, fewer files, and less space used in development. You can also check them in to source control unlike node_modules. Since yarn is quite popular it would be good to support the use of these zip dependencies as an option.

Making exclude emulate include

For some projects it would be much easier to have an include option rather than exclude. Bigger projects tend to have a lot of files not required at runtime (see dungeon-revealer/dungeon-revealer#1115). This makes it infeasible to explicitly list every pattern to exclude. Here are my attempts to get the exclude option to emulate the include option at maxb2/caxa-exclude-example. N.B. some of these use GNU/Linux tools and aren't necessarily portable to other OSes.

No excludes

npx caxa -i . -o hello-no-exclude -- "{{caxa}}/node_modules/.bin/node" "{{caxa}}/app.js"

Archive contents:

app.js
.git/
node_modules/
package.json
package-lock.json
README.md

Hardcode the excludes

npx caxa -i . -o hello-exclude-names --exclude README.md .git -- "{{caxa}}/node_modules/.bin/node" "{{caxa}}/app.js"

app.js 
node_modules/
package.json
package-lock.json

Trying to emulate "include"

npx caxa -i . -o hello-exclude-glob --exclude * '!app.js' '!node_modules' '!package*' -- "{{caxa}}/node_modules/.bin/node" "{{caxa}}/app.js"

app.js
.git/
node_modules/
package.json
package-lock.json

Bash globbing doesn't include hidden files!

$ echo *
app.js node_modules package.json package-lock.json README.md

Explicitly exclude hidden files

npx caxa -i . -o hello-exclude-glob-dot --exclude * '\.*' '!app.js' '!node_modules' '!package*' -- "{{caxa}}/node_modules/.bin/node" "{{caxa}}/app.js"

app.js
node_modules/
package.json
package-lock.json

Use find to list the excludes.

EXCLUDE=$(find . -maxdepth 1 -not -path '.' -not -name 'node_modules' -not -name 'app.js' -not -name 'package*' -exec echo {} + | sed -e 's|\./||g') && npx caxa -i . -o hello-exclude-glob-find --exclude $EXCLUDE -- "{{caxa}}/node_modules/.bin/node" "{{caxa}}/app.js"

app.js
node_modules/
package.json
package-lock.json

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.