UrielCh / opencv4nodejs

ESM Nodejs bindings to OpenCV 3/4
MIT License
234 stars 49 forks source link

Error: Cannot find module 'XXX/node_modules/.pnpm/@u4+opencv4nodejs@6.5.2/node_modules/@u4/opencv4nodejs/build/Release/opencv4nodejs' #122

Open junehunter opened 8 months ago

junehunter commented 8 months ago

/XXX/node_modules/.pnpm/@u4+opencv4nodejs@6.5.2/node_modules/@u4/opencv4nodejs/lib/cvloader.js:62 throw err; ^

Error: Cannot find module '/XXX/node_modules/.pnpm/@u4+opencv4nodejs@6.5.2/node_modules/@u4/opencv4nodejs/build/Release/opencv4nodejs' Require stack:

sollosollo4 commented 7 months ago

I have same issue after packaged application and install it on another PC

AbaoFromCUG commented 6 months ago

@junehunter Need to build build/Release/opencv4nodejs.node first via build-opencv command, read more in README.md

@sollosollo4 do you copy/bundle opencv4nodejs.node in your application?

sollosollo4 commented 6 months ago

@AbaoFromCUG what do u mean? I gues yes, but how I can check this. Im not copy, but this going up in app.asar.unpacked when building But in app.asar, I have links not to the folder inside builds, but to the folder in the full path C:/ on my PC. I think this is a mistake, but I don’t know how to tell the builder to specify asar relative paths instead of relative build paths.

sollosollo4 commented 6 months ago

if I have tme, I'll check what happends if I require library by next code

const libraryPath = path.join(__dirname, 'app.asar', 'absolute path to opencv4nodejs.node library inside app_asar folder');

const yourLibrary = require(libraryPath);
junehunter commented 6 months ago

@junehunter Need to build build/Release/opencv4nodejs.node first via build-opencv command, read more in README.md

@sollosollo4 do you copy/bundle opencv4nodejs.node in your application?

The Windows environment builds successfully, but Linux does not build the opencv4nodejs binary correctly.

AbaoFromCUG commented 6 months ago

@AbaoFromCUG what do u mean? I gues yes, but how I can check this. Im not copy, but this going up in app.asar.unpacked when building But in app.asar, I have links not to the folder inside builds, but to the folder in the full path C:/ on my PC. I think this is a mistake, but I don’t know how to tell the builder to specify asar relative paths instead of relative build paths.

This is the logic that should be implemented (but currently it is not)

Normally, Bundle (like webpack/vite) will copy opencv4nodejs.node to your outputPath(dist usually), like node-loader of webpack

The package maintainer should write code like require(`../bin/${process.platform}/{process.arch}/opencv4nodejs.node`) to load addon-bindings. The package folder like

- opencv4nodejs
----| bin
--------| win32
------------| x64
----------------|opencv4nodejs.node
----------------|opencv.dll
----| lib
--------| index.js

When we use the package in package.json and webpack+node-loader, the output Of our project should be

- myProject
----| dist
--------| bin
------------| win32
----------------| x64
--------------------|opencv4nodejs.node
--------------------|opencv.dll
--------| index.js

and the code in index.js will become

__webpack_require__("./node_modules/.pnpm/......\.node$")(`./${process.platform}/${process.arch}/opencv4nodejs.node`)

Just like onnxruntime-node did

https://github.com/microsoft/onnxruntime/blob/966fa74597affcaffe35968b5bae0bab5d782f7c/js/node/lib/binding.ts#L45-L52

What we can do?

modify the relevant source code, but it is hard…… You need hack the cvloader.js , these code may be useful, but not enough, you need copy dll/node file to bin/napi-v3/win32/64/ too……This is too troublesome

const cvloaderPath = "node_modules/@u4/opencv4nodejs/lib/cvloader.js"
// need copy node/binary to this folder……
const binaryDestPath = "node_modules/@u4/opencv4nodejs/bin/napi-v3"

const main = async()=> {
    const buf = await fs.readFile(cvloaderPath)
    let content = buf.toString()

    content = content.replace(/(function getOpenCV\(opt\))[.\s\S]*?(\s*\/\/ resolve haarcascade files)/, "$1{\n    const opencvBuild=require(`../bin/napi-v3/${process.platform}/${process.arch}/opencv4nodejs.node`)\n$2");

    await fs.writeFile(cvloaderPath, content)
    console.log("hack cvloader.js success")
}
main()

The simple step to copy dll/node to the side of app.asar?(I guess)