Koromix / koffi

Fast and easy-to-use C FFI module for Node.js
https://koffi.dev/
MIT License
202 stars 4 forks source link

Unable to use koffi in web page #183

Closed Ame-ReIori closed 3 months ago

Ame-ReIori commented 3 months ago

Hi, I'm focusing on the situation where the web server provides a web page, including some libraries (.so, .dylib, .dll), and the client can download the libraries and load them in his browser without any communication.

I know that websocket is widely used but it doesn't meet my requirement. Since the client should load the library in the local browser, I wrote a module with koffi in nodejs and tried to import it in vue.

The code in nodejs works. I export the incremental function inc as follows:

import koffi from 'koffi'

var lib = koffi.load('test.dylib')

var inc = lib.func('int inc(int a)')

export { inc };

Then the following is my test code.

import { inc } from './test.js'

console.log(inc(1))

It works as expected. Then I want to combine it with vue and edit the file src/App.vue.

<script setup>
import HelloWorld from './components/HelloWorld.vue'
import TheWelcome from './components/TheWelcome.vue'
import { inc } from '../test.js'
</script>

<template>
  ......

  <button @click="inc(2)">Count</button>
</template>

......

My package.json is as follows and then I run npm run dev.

{
  "name": "vuetest",
  "version": "0.0.0",
  "private": true,
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "koffi": "^2.9.0",
    "vue": "^3.4.29"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^5.0.5",
    "vite": "^5.3.1"
  }
}

However, there are some errors like No loader is configured for ".node" files: node_modules/koffi/build/koffi/darwin_arm64/koffi.node.

I have searched it on Google but it seems that no one met the same problem. So, how can I use koffi in vue? Or is there any other apt methods to achieve my requirement?

I list the complete src/App.vue and errors as follows:

src/App.vue

<script setup>
import HelloWorld from './components/HelloWorld.vue'
import TheWelcome from './components/TheWelcome.vue'
import { inc } from '../test.js'
</script>

<template>
  <header>
    <img alt="Vue logo" class="logo" src="./assets/logo.svg" width="125" height="125" />

    <div class="wrapper">
      <HelloWorld msg="You did it!" />
    </div>
  </header>

  <main>
    <TheWelcome />
  </main>

  <button @click="inc(2)">Count</button>
</template>

<style scoped>
header {
  line-height: 1.5;
}

.logo {
  display: block;
  margin: 0 auto 2rem;
}

@media (min-width: 1024px) {
  header {
    display: flex;
    place-items: center;
    padding-right: calc(var(--section-gap) / 2);
  }

  .logo {
    margin: 0 2rem 0 0;
  }

  header .wrapper {
    display: flex;
    place-items: flex-start;
    flex-wrap: wrap;
  }
}
</style>

errors

> vuetest@0.0.0 dev
> vite

  VITE v5.4.2  ready in 199 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h + enter to show help
✘ [ERROR] No loader is configured for ".node" files: node_modules/koffi/build/koffi/darwin_arm64/koffi.node

    node_modules/koffi/index.js:504:26:
      504 │         native2 = require("./build/koffi/darwin_arm64/koffi.node");
          ╵                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

✘ [ERROR] No loader is configured for ".node" files: node_modules/koffi/build/koffi/freebsd_x64/koffi.node

    node_modules/koffi/index.js:519:26:
      519 │         native2 = require("./build/koffi/freebsd_x64/koffi.node");
          ╵                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

✘ [ERROR] No loader is configured for ".node" files: node_modules/koffi/build/koffi/win32_x64/koffi.node

    node_modules/koffi/index.js:544:26:
      544 │         native2 = require("./build/koffi/win32_x64/koffi.node");
          ╵                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

✘ [ERROR] No loader is configured for ".node" files: node_modules/koffi/build/koffi/darwin_x64/koffi.node

    node_modules/koffi/index.js:509:26:
      509 │         native2 = require("./build/koffi/darwin_x64/koffi.node");
          ╵                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

✘ [ERROR] No loader is configured for ".node" files: node_modules/koffi/build/koffi/win32_arm64/koffi.node

    node_modules/koffi/index.js:539:26:
      539 │         native2 = require("./build/koffi/win32_arm64/koffi.node");
          ╵                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

✘ [ERROR] No loader is configured for ".node" files: node_modules/koffi/build/koffi/freebsd_arm64/koffi.node

    node_modules/koffi/index.js:514:26:
      514 │         native2 = require("./build/koffi/freebsd_arm64/koffi.node");
          ╵                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

✘ [ERROR] No loader is configured for ".node" files: node_modules/koffi/build/koffi/openbsd_x64/koffi.node

    node_modules/koffi/index.js:534:26:
      534 │         native2 = require("./build/koffi/openbsd_x64/koffi.node");
          ╵                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

✘ [ERROR] No loader is configured for ".node" files: node_modules/koffi/build/koffi/linux_arm64/koffi.node

    node_modules/koffi/index.js:524:26:
      524 │         native2 = require("./build/koffi/linux_arm64/koffi.node");
          ╵                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

✘ [ERROR] No loader is configured for ".node" files: node_modules/koffi/build/koffi/linux_x64/koffi.node

    node_modules/koffi/index.js:529:26:
      529 │         native2 = require("./build/koffi/linux_x64/koffi.node");
          ╵                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Koromix commented 3 months ago

Hi, I'm sorry this is not possible.

Browsers do not provide a way to load a native shared library, this would be a massive security risk. If you want to run native code in the browser, you must target WASM build with the native code (with Emscripten, or wasi-sdk, or whatever else). The WASM build will have very limited access to the system in any case.

Alternatively, if the native code must run on the target system (because, for example, it interacts with specific hardware, or whatever) but you want to provide a web configuration page, you could ask your users to install something on their system that runs in the background, and configure it through a localhost HTTP server or something like that.