Automattic / node-canvas

Node canvas is a Cairo backed Canvas implementation for NodeJS.
10.21k stars 1.17k forks source link

Error: Cannot find module '../build/Release/canvas.node' #2135

Closed gilles-hemmerle closed 11 months ago

gilles-hemmerle commented 2 years ago

Issue

I have a project (nestjs) which works perfectly with canvas I added nest-commander (which allows to create a cli command for my nest application).

When running the following command, the script fails:

Command:

npx ts-node src/commands.ts

Error:

Error: Cannot find module '../build/Release/canvas.node'
Require stack:
- /home/gillesh/Documents/development/projects.iabsis.com/tulip/tulip-api/node_modules/canvas/lib/bindings.js
- /home/gillesh/Documents/development/projects.iabsis.com/tulip/tulip-api/node_modules/canvas/lib/canvas.js
- /home/gillesh/Documents/development/projects.iabsis.com/tulip/tulip-api/node_modules/canvas/index.js
- /home/gillesh/Documents/development/projects.iabsis.com/tulip/tulip-api/src/files/files.service.ts
- /home/gillesh/Documents/development/projects.iabsis.com/tulip/tulip-api/src/tulips/tulips.controller.ts
- /home/gillesh/Documents/development/projects.iabsis.com/tulip/tulip-api/src/tulips/tulips.module.ts
- /home/gillesh/Documents/development/projects.iabsis.com/tulip/tulip-api/src/app.module.ts
- /home/gillesh/Documents/development/projects.iabsis.com/tulip/tulip-api/src/commands.ts
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:902:15)
    at Function.Module._resolveFilename.sharedData.moduleResolveFilenameHook.installedValue [as _resolveFilename] (/home/gillesh/Documents/development/projects.iabsis.com/tulip/tulip-api/node_modules/@cspotcode/source-map-support/source-map-support.js:811:30)
    at Function.Module._load (internal/modules/cjs/loader.js:746:27)
    at Module.require (internal/modules/cjs/loader.js:974:19)
    at require (internal/modules/cjs/helpers.js:93:18)
    at Object.<anonymous> (/home/gillesh/Documents/development/projects.iabsis.com/tulip/tulip-api/node_modules/canvas/lib/bindings.js:3:18)
    at Module._compile (internal/modules/cjs/loader.js:1085:14)
    at Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
    at Object.require.extensions.<computed> [as .js] (/home/gillesh/Documents/development/projects.iabsis.com/tulip/tulip-api/node_modules/ts-node/src/index.ts:1587:43)
    at Module.load (internal/modules/cjs/loader.js:950:32) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/home/gillesh/Documents/development/projects.iabsis.com/tulip/tulip-api/node_modules/canvas/lib/bindings.js',
    '/home/gillesh/Documents/development/projects.iabsis.com/tulip/tulip-api/node_modules/canvas/lib/canvas.js',
    '/home/gillesh/Documents/development/projects.iabsis.com/tulip/tulip-api/node_modules/canvas/index.js',
    '/home/gillesh/Documents/development/projects.iabsis.com/tulip/tulip-api/src/files/files.service.ts',
    '/home/gillesh/Documents/development/projects.iabsis.com/tulip/tulip-api/src/tulips/tulips.controller.ts',
    '/home/gillesh/Documents/development/projects.iabsis.com/tulip/tulip-api/src/tulips/tulips.module.ts',
    '/home/gillesh/Documents/development/projects.iabsis.com/tulip/tulip-api/src/app.module.ts',
    '/home/gillesh/Documents/development/projects.iabsis.com/tulip/tulip-api/src/commands.ts'
  ]
}

tsconfig.json file:

{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "target": "es2017",
    "sourceMap": true,
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": true,
    "skipLibCheck": true,
    "strictNullChecks": false,
    "noImplicitAny": false,
    "strictBindCallApply": false,
    "forceConsistentCasingInFileNames": false,
    "noFallthroughCasesInSwitch": false,
    "resolveJsonModule": true,
    "esModuleInterop": true
  }
}

It seems that when building with ts-node, it is unable to find the file '../build/Release/canvas.node' for any reason. If i remove the import { Canvas, Image } from 'canvas'; line, script build with all other npm dependencies working.

Your Environment

arbassic commented 2 years ago

Related to:

https://github.com/Automattic/node-canvas/issues/1221

for me reinstallation helped, even if canvas package is a sub-dependency

yarn add -D canvas

previously rm node_modules/canvas

gigamesh commented 2 years ago

I think I've tried every suggestion in every thread on the internet about this issue but its still happening. I'm using pnpm, and the error happens when trying to run tests with vitest.

zbjornson commented 2 years ago

There's not enough info in the log to troubleshoot. What's your npm install canvas output, and what happens if you use node instead of npx ts-node?

gigamesh commented 2 years ago

I ended up getting around the problem by just replacing getContext with a no-op (using vitest):

  HTMLCanvasElement.prototype.getContext = vi.fn();
RUSHt commented 2 years ago

I was having similar issues with

'.../canvas' is not supported resolving ES modules

and

Cannot find module '.../canvas.node'

So...

import { createCanvas, loadImage, Image } from "canvas";

Was replaced with...

import { createRequire } from "module";
const require = createRequire(import.meta.url);
const { createCanvas, loadImage, Image } = require('canvas');

My dev environment (macOS) worked fine with the initial import statement, but production (AWS Linux) failed with the Can't find / not supporting ES5 modules errors.

DorkForce commented 2 years ago

We've got the same issue going on in CICD-only. We installed amCharts as a third-party library, and while setting up Jest testing for the charts, everything's working locally but the test job fails in Gitlab, it complains:

` npm run test

@dds/dv@2.0.0-beta.17 test npx jest FAIL src/components/area/chart.test.js ● Test suite failed to run Cannot find module '../build/Release/canvas.node' Require stack:

  • /builds/dao/dell-digital-design/design-language-system/systems/dls-2.0-data-vis/node_modules/canvas/lib/bindings.js`
HitkoDev commented 1 year ago

This has been going on for ages. The problem is that whenever a matching version of a dependency is found to be already installed (based on lockfile and contents of node_modules), no install script is triggered for that dependency. One solution is to run cd ./node_modules/canvas && npx node-pre-gyp install --fallback-to-build --update-binary or npm rebuild after installing new dependencies.

However, I have several dependencies that need to install binaries the same way, and I've only been noticing this problem for canvas, so there might be something else going on with the way canvas handles it.

lxfu1 commented 1 year ago

.npmrc

public-hoist-pattern[]=canvas
benstahl commented 1 year ago

I had this issue trying to use node-canvas via pnpm. What worked was to delete the node_modules folder and re-install the reps with pnpm install

wannabehero commented 1 year ago

I had npm install --ignore-scripts in my Dockerfile. Removing --ignore-scripts solved the issue.

vtereshyn commented 11 months ago

Still issue. Here is reproduction repository - https://github.com/vtereshyn/pnpm-jest-jsdom-canvas

It fails all my tests

vtereshyn commented 11 months ago

Not sure which side this issue should be fixed on, but I created similar in the PNPM repo - https://github.com/pnpm/pnpm/issues/7425

zbjornson commented 11 months ago

Recent versions of node-canvas include the --update-binary flag (#1982), which should fix this.

vtereshyn commented 11 months ago

@zbjornson recent version was released in April 2023, but the issue popped up at the end of 2023 and the beginning of 2024. I assume, that fix doesn't work

zbjornson commented 11 months ago

@vtereshyn I think your issue with pnpm is unrelated to the OP's issue. The comments in this issue are about a few different underlying problems, but --update-binary addresses the issue in https://github.com/Automattic/node-canvas/issues/2135#issuecomment-1400307682, which got the most upvotes.

popovidis commented 10 months ago

@vtereshyn I think your issue with pnpm is unrelated to the OP's issue. The comments in this issue are about a few different underlying problems, but --update-binary addresses the issue in #2135 (comment), which got the most upvotes.

tried to command with --update-binary and unfortunately it did not work.

I am trying to use canvas as part of server command in nextjs with node.

saddamhr commented 10 months ago

If you use Next.js or Next.js 14, you may need to add the following to your next.config.js:

module.exports = {
 webpack: (config) => {
   config.resolve.alias.canvas = false;

   return config;
 },
}

ref: https://www.npmjs.com/package/react-pdf this is work for me

borontion commented 9 months ago

I resolved this issue by explicitly deleting node_modules and then installing again.

I am on an apple arm chip and there is no prebuild release for macos arm, so I have to compile this during installation. Make sure the compilation requirement can be satisfied.

joshuanapoli commented 9 months ago

Check carefully the install output. The package build may fail because of "Package pixman-1 was not found in the pkg-config search path.". In this case, you need to install the dependency. See #1065