Node-canvas doesn't work

Question:
If I try to run a program that requires node-canvas, it fails with this error:

node:internal/modules/cjs/loader:1340
  return process.dlopen(module, path.toNamespacedPath(filename));
                 ^

Error: libuuid.so.1: cannot open shared object file: No such file or directory
    at Module._extensions..node (node:internal/modules/cjs/loader:1340:18)
    at Module.load (node:internal/modules/cjs/loader:1119:32)
    at Module._load (node:internal/modules/cjs/loader:960:12)
    at Module.require (node:internal/modules/cjs/loader:1143:19)
    at require (node:internal/modules/cjs/helpers:110:18)
    at Object.<anonymous> (/home/runner/fast3dloop/node_modules/canvas/lib/bindings.js:3:18)
    at Module._compile (node:internal/modules/cjs/loader:1256:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)
    at Module.load (node:internal/modules/cjs/loader:1119:32)
    at Module._load (node:internal/modules/cjs/loader:960:12) {
  code: 'ERR_DLOPEN_FAILED'
}

Node.js v18.16.1

Other answers mention a replit.nix file, which doesn’t exist.

Repl link:
https://replit.com/@JasonRoman/fast3dloop
(see “test.js” and “error.txt” files)

The replit.nix does exist, you just have to enable the hidden files by clicking on the 3 dot option uptop (right beside the “File”).

image

You can edit the replit.nix to include the library:

{ pkgs }: {
  deps = [
    pkgs.python310
    pkgs.libuuid
  ];
}

I just tried that. Unfortunately, the error is still there, and prefixed with:

I looked at your file and you include a ’ , ’ there.
There is no ’ , '.

1 Like

I removed the comma. However the error still seems to be there…

node:internal/modules/cjs/loader:1340
  return process.dlopen(module, path.toNamespacedPath(filename));
                 ^

Error: libuuid.so.1: cannot open shared object file: No such file or directory
    at Module._extensions..node (node:internal/modules/cjs/loader:1340:18)
    at Module.load (node:internal/modules/cjs/loader:1119:32)
    at Module._load (node:internal/modules/cjs/loader:960:12)
    at Module.require (node:internal/modules/cjs/loader:1143:19)
    at require (node:internal/modules/cjs/helpers:110:18)
    at Object.<anonymous> (/home/runner/fast3dloop/node_modules/canvas/lib/bindings.js:3:18)
    at Module._compile (node:internal/modules/cjs/loader:1256:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)
    at Module.load (node:internal/modules/cjs/loader:1119:32)
    at Module._load (node:internal/modules/cjs/loader:960:12) {
  code: 'ERR_DLOPEN_FAILED'
}

Node.js v18.16.1

Is there something I need to refresh to update the packages or something?

1 Like

You have to install the module libuuid, I think I could be wrong but try.

npm install libuuid (which is the same command the Replit packager uses) fails with a 400-line error.
I’m not sure I should paste it out in full here, but you can see it in the file “error.txt” in the repl.

1 Like

sudo apt-get install uuid-dev?

You don't need sudo in replit, all files that can be modified already have the correct permissions and you can install new software using Nix.

Then apt-get fails because it doesn’t have root permissions.

2 Likes

Oh yeah, I forgot about that.

Try to change to:

{ pkgs }: {
  deps = [
    pkgs.python310
    pkgs.libuuid.dev
  ];
}

If that doens’t work try to find the library in shell.

find /nix/store -name libuuid.so.1

It looks like there are lib32 and lib64 versions…

This is taking a really long time…

You have to link the library now

ln -s /nix/store/q4rkr4pm85gfzf1idb37v5jzdjkdazja-vial-0.4.1-fhs/usr/lib64/libuuid.so.1 /usr/lib/

ln: failed to create symbolic link '/usr/lib/libuuid.so.1': Read-only file system

Try to set the library path into the env, execute this in the shell.

export LD_LIBRARY_PATH=/nix/store/q4rkr4pm85gfzf1idb37v5jzdjkdazja-vial-0.4.1-fhs/usr/lib64:$LD_LIBRARY_PATH
node index.js

And I’m out of solutions if this doesn’t work.

Can I copy/paste the node-canvas source code like I did with three.js?

Is there any alternative to node-canvas I can use? All I really want is to transform an array of pixels into an image I can save on the filesystem.
I modified the repl so pressing “Run” prints out the pixel array to the console. But it is a 500x500 image, so it takes a while and some parts are cut off.

Add a system library array before the final } in replit.nix, like this:

  env = {
    LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath [
      pkgs.libuuid
    ];
  };

If this breaks other programs, try and configure your repl such that libuuid is only added to the library path where needed.
Look out for when Automatically Installing Python System Dependencies is ported to node.js so you can request to list libuuid as needed for node-canvas.

2 Likes

This is the actual solution to the question.

2 Likes