vite-plugin-fable icon indicating copy to clipboard operation
vite-plugin-fable copied to clipboard

make Fable.Daemon as little as possible

Open jkone27 opened this issue 10 months ago • 4 comments

since we ship and deploy this assembly within the npm package, we should strive to make this executable as little as possible

https://github.com/fable-compiler/vite-plugin-fable/tree/master/Fable.Daemon

here is published in bin dir, currently ~ 69MB:

https://github.com/fable-compiler/vite-plugin-fable/blob/6ae523e85808fca16b278c95f7d72f6bb9798988/package.json#L11C5-L11C131

Image

now published as ready to run https://learn.microsoft.com/en-us/dotnet/core/deploying/ready-to-run

jkone27 avatar Mar 17 '25 15:03 jkone27

This is not the current situation.
The binaries are generated during post-installation and are optimized for the operating system.
There is no download cost for this at the moment. However, the trade-off is that the post-installation process can be slow or may fail.

To publish as ready to run, you need to specify the architecture and OS, which means you will have to find a way to download the single file for the appropriate OS from another location. This means you are essentially trading one problem for another.

The advantage of providing the source code of the daemon is that you can directly address potential issues within your project. This approach has proven particularly useful for troubleshooting cross-platform problems.

nojaf avatar Mar 17 '25 16:03 nojaf

ah i see so i mis-understood the installation process, so publish happens now on post install, as the sourcecode is shipped. so the only time cost is the speed of dotnet compilation. i understand, thanks. closing this issue , i thought the publish would happen at npm publish stage, thank you for explaining! 👍

jkone27 avatar Mar 17 '25 17:03 jkone27

One idea I originally considered was to download the Fable daemon binaries (or a single file) from a GitHub release artifact. This way, the post-install process could run a simple Node.js script that downloads the appropriate files based on the current architecture and OS.

While this approach would enhance the user experience, it is more challenging to implement.

nojaf avatar Mar 18 '25 07:03 nojaf

I just took a look at how the big players are solving this problem. Having the daemon as a single file is a reasonable approach when it comes to installing the project. The downside is that this file will vary for each combination of OS and architecture.

I noticed that the oxc-parser specifies many optional dependencies:

"optionalDependencies": {
  "@oxc-parser/binding-win32-x64-msvc": "0.61.0",
  "@oxc-parser/binding-win32-arm64-msvc": "0.61.0",
  "@oxc-parser/binding-linux-x64-gnu": "0.61.0",
  "@oxc-parser/binding-linux-x64-musl": "0.61.0",
  "@oxc-parser/binding-linux-arm64-gnu": "0.61.0",
  "@oxc-parser/binding-linux-arm64-musl": "0.61.0",
  "@oxc-parser/binding-linux-arm-gnueabihf": "0.61.0",
  "@oxc-parser/binding-darwin-x64": "0.61.0",
  "@oxc-parser/binding-darwin-arm64": "0.61.0",
  "@oxc-parser/binding-wasm32-wasi": "0.61.0"
},

NPM will attempt to install all of these but will silently fail if the OS and architecture do not match.

Here's what a Darwin configuration looks like:

{
  "name": "@oxc-parser/binding-darwin-arm64",
  "version": "0.61.0",
  "cpu": [
    "arm64"
  ],
  "main": "parser.darwin-arm64.node",
  "files": [
    "parser.darwin-arm64.node"
  ],
  "engines": {
    "node": ">=14.0.0"
  },
  "os": [
    "darwin"
  ]
}

In the main package, the correct NPM package is loaded via Node code:

else if (process.platform === 'darwin') {
    try {
        return require('./parser.darwin-universal.node');
    } catch (e) {
        loadErrors.push(e);
    }
    try {
        return require('@oxc-parser/binding-darwin-universal');
    } catch (e) {
        loadErrors.push(e);
    }

    if (process.arch === 'x64') {
        try {
            return require('./parser.darwin-x64.node');
        } catch (e) {
            loadErrors.push(e);
        }
    }

This is very clean, I must say. It requires more work, but it's very organized.

nojaf avatar Mar 21 '25 07:03 nojaf