Support `node-canvas`
node-canvas does not currently work with Bun as it relies on some v8-specific APIs in Node
We may eventually implement these: https://github.com/oven-sh/bun/issues/3110
Or perhaps it would be easier to upstream a fix
This also blocks jsdom
Related to https://github.com/oven-sh/bun/issues/3110
Original issue:
Hello! I've installed canvas on my project and seem to be getting errors whenever I use it. I created a repository with the bare code required to create the error.
Code:
import * as canvas from "canvas";
(async () => {
canvas.loadImage("https://static.bunnycdn.ru/i/cache/images/3/37/375e7fdc580766874948e5bf678e2a8a.jpg").then((image) => {
console.log("Loaded!");
const c = canvas.createCanvas(image.width, image.height);
const context = c.getContext('2d');
context.drawImage(image, 0, 0);
})
});
Error:
error: Cannot find module "../build/Release/canvas.node" from "/Users/eltik/Documents/Coding/Bun-canvas/node_modules/canvas/lib/bindings.js"
error: script "start" exited with code 1 (SIGHUP)
Repository: https://github.com/Eltik/Bun-canvas
Originally reported on Discord: Incompatibility with Canvas
Having the same issue in my Nuxt application, when I try to deserialise my imageDataUrl on the API server
I have been playing around with Bun since about 1.0.2 and node-canvas is a package I use extensively for generating server side charts through Chart.js. For modules that do not require canvas, Bun is great and I love being able to run Typescript modules directly without transpiling. But most of the projects are Chart.js based. I understand there are two issues with node-canvas support but the one I run into is the lack of support for the node_module_register API entry point. The other issues reported is related to the npm registry and a background update.
Any update on this? facing the same error
bun --watch index.ts
error: Cannot find module "../build/Release/canvas.node" from "/Users/harpreetsingh/Projects/imageoptimizer/node_modules/canvas/lib/bindings.js"
I have the same error with just installed canvas:
Are there any working alternatives in the mean time?
Facing same issue on Bun using ascii-art package
+1 here. support for canvas is the last holdout for us to adopt bun install in @faire's frontend monorepo.
FWIW there is canvaskit-wasm.
FWIW there is canvaskit-wasm.
some of our modules (including jsdom) try to link canvas without actually depending on it. is there a way to get them to link canvaskit-wasm instead of canvas? if not, I think we need to wait for support
@chriskrogh Would assigning the canvas api from canvis-kit onto globalThis work?
@chriskrogh Would assigning the canvas api from canvis-kit onto
globalThiswork?
I'm not sure when I would do that? this issue arises early on in the installation process and aborts bun install entirely (node_modules aren't generated)
When are we gonna have this?
I think I'm hitting the same thing, I have a project that works with node and when I try to use bun instead I get:
╰─(base) ⠠⠵ bun run src/scripts/process_scenes.ts --loop on master|✚2-29…5
bun: symbol lookup error: /home/arthur/dev/ai/manga/node_modules/opencv4nodejs/build/Release/opencv4nodejs.node: undefined symbol: node_module_register
Is this the correct issue to report this / follow, or should I file a separate issue ?
Thanks.
is this likely to be resolved soon?
and this error?
root@celestrox:~/celestrox/backend# bun run ./src/server.ts bun: symbol lookup error: /root/celestrox/backend/node_modules/cpu-features/build/Release/cpufeatures.node: undefined symbol: node_module_register
I got the same error trying to move to Bun. I have several projects with C Bidings libs, It would be awesome to have this support.
Bun recode of my API currently halted because of this issue :(
For anyone looking for an alternative, I was able to use @napi-rs/canvas. It was basically a drag and drop replacement other than a few lines.
Thank you, @ignSKRRRTT!
Got a puzzle game image generator that I could not continue work on until this was figured out.
This is blocked on #4290 or https://github.com/Automattic/node-canvas/pull/2235 (node-canvas 3.0), whichever happens first
As of node-canvas v2.11.2, here are the list of symbols we would need to implement in order to support this version:
-
Nan::ObjectWrap::WeakCallback(v8::WeakCallbackInfo<Nan::ObjectWrap> const&) -
node::Buffer::Copy(v8::Isolate*, char const*, unsigned long) -
node::Buffer::Data(v8::Local<v8::Object>) -
node::Buffer::HasInstance(v8::Local<v8::Value>) -
node::Buffer::Length(v8::Local<v8::Object>) -
node::Buffer::New(v8::Isolate*, char*, unsigned long, void (*)(char*, void*), void*) -
node::Buffer::New(v8::Isolate*, char*, unsigned long) -
node::EmitAsyncDestroy(v8::Isolate*, node::async_context) -
node::EmitAsyncInit(v8::Isolate*, v8::Local<v8::Object>, v8::Local<v8::String>, double) -
node::ErrnoException(v8::Isolate*, int, char const*, char const*, char const*) -
node::MakeCallback(v8::Isolate*, v8::Local<v8::Object>, v8::Local<v8::Function>, int, v8::Local<v8::Value>*, node::async_context) -
uv_default_loop -
uv_queue_work -
v8::api_internal::ClearWeak(unsigned long*) -
v8::api_internal::DisposeGlobal(unsigned long*) -
v8::api_internal::FromJustIsNothing() -
v8::api_internal::GlobalizeReference(v8::internal::Isolate*, unsigned long) -
v8::api_internal::MakeWeak(unsigned long*, void*, void (*)(v8::WeakCallbackInfo<void> const&), v8::WeakCallbackType) -
v8::api_internal::ToLocalEmpty() -
v8::Array::Length() const -
v8::Array::New(v8::Isolate*, int) -
v8::ArrayBuffer::GetBackingStore() -
v8::ArrayBuffer::New(v8::Isolate*, unsigned long) -
v8::ArrayBufferView::Buffer() -
v8::ArrayBufferView::ByteLength() -
v8::ArrayBufferView::ByteOffset() -
v8::BackingStore::Data() const -
v8::Context::GetIsolate() -
v8::Context::Global() -
v8::Date::ValueOf() const -
v8::EscapableHandleScopeBase::EscapableHandleScopeBase(v8::Isolate*) -
v8::EscapableHandleScopeBase::EscapeSlot(unsigned long*) -
v8::Exception::Error(v8::Local<v8::String>, v8::Local<v8::Value>) -
v8::Exception::RangeError(v8::Local<v8::String>, v8::Local<v8::Value>) -
v8::Exception::TypeError(v8::Local<v8::String>, v8::Local<v8::Value>) -
v8::External::New(v8::Isolate*, void*) -
v8::External::Value() const -
v8::Float64Array::New(v8::Local<v8::ArrayBuffer>, unsigned long, unsigned long) -
v8::Function::Call(v8::Local<v8::Context>, v8::Local<v8::Value>, int, v8::Local<v8::Value>*) -
v8::Function::New(v8::Local<v8::Context>, void (*)(v8::FunctionCallbackInfo<v8::Value> const&), v8::Local<v8::Value>, int, v8::ConstructorBehavior, v8::SideEffectType) -
v8::Function::NewInstance(v8::Local<v8::Context>, int, v8::Local<v8::Value>*) const -
v8::FunctionTemplate::GetFunction(v8::Local<v8::Context>) -
v8::FunctionTemplate::HasInstance(v8::Local<v8::Value>) -
v8::FunctionTemplate::InstanceTemplate() -
v8::FunctionTemplate::New(v8::Isolate*, void (*)(v8::FunctionCallbackInfo<v8::Value> const&), v8::Local<v8::Value>, v8::Local<v8::Signature>, int, v8::ConstructorBehavior, v8::SideEffectType, v8::CFunction const*, unsigned short, unsigned short, unsigned short) -
v8::FunctionTemplate::PrototypeTemplate() -
v8::FunctionTemplate::SetClassName(v8::Local<v8::String>) -
v8::HandleScope::~HandleScope() -
v8::HandleScope::~HandleScope() -
v8::HandleScope::CreateHandle(v8::internal::Isolate*, unsigned long) -
v8::HandleScope::HandleScope(v8::Isolate*) -
v8::Integer::New(v8::Isolate*, int) -
v8::Integer::NewFromUnsigned(v8::Isolate*, unsigned int) -
v8::internal::IsolateFromNeverReadOnlySpaceObject(unsigned long) -
v8::Isolate::AdjustAmountOfExternalAllocatedMemory(long long) -
v8::Isolate::GetCurrent() -
v8::Isolate::GetCurrentContext() -
v8::Isolate::ThrowException(v8::Local<v8::Value>) -
v8::Number::New(v8::Isolate*, double) -
v8::Object::Get(v8::Local<v8::Context>, unsigned int) -
v8::Object::Get(v8::Local<v8::Context>, v8::Local<v8::Value>) -
v8::Object::InternalFieldCount() const -
v8::Object::New(v8::Isolate*) -
v8::Object::Set(v8::Local<v8::Context>, v8::Local<v8::Value>, v8::Local<v8::Value>) -
v8::Object::SetAlignedPointerInInternalField(int, void*) -
v8::Object::SetInternalField(int, v8::Local<v8::Data>) -
v8::Object::SlowGetAlignedPointerFromInternalField(int) -
v8::Object::SlowGetInternalField(int) -
v8::ObjectTemplate::New(v8::Isolate*, v8::Local<v8::FunctionTemplate>) -
v8::ObjectTemplate::NewInstance(v8::Local<v8::Context>) -
v8::ObjectTemplate::SetAccessor(v8::Local<v8::Name>, void (*)(v8::Local<v8::Name>, v8::PropertyCallbackInfo<v8::Value> const&), void (*)(v8::Local<v8::Name>, v8::Local<v8::Value>, v8::PropertyCallbackInfo<void> const&), v8::Local<v8::Value>, v8::PropertyAttribute, v8::SideEffectType, v8::SideEffectType) -
v8::ObjectTemplate::SetInternalFieldCount(int) -
v8::Signature::New(v8::Isolate*, v8::Local<v8::FunctionTemplate>) -
v8::String::Length() const -
v8::String::NewFromUtf8(v8::Isolate*, char const*, v8::NewStringType, int) -
v8::String::WriteUtf8(v8::Isolate*, char*, int, int*, int) const -
v8::Template::Set(v8::Local<v8::Name>, v8::Local<v8::Data>, v8::PropertyAttribute) -
v8::TryCatch::~TryCatch() -
v8::TryCatch::HasCaught() const -
v8::TryCatch::ReThrow() -
v8::TryCatch::TryCatch(v8::Isolate*) -
v8::TypedArray::Length() -
v8::Uint16Array::New(v8::Local<v8::ArrayBuffer>, unsigned long, unsigned long) -
v8::Uint8ClampedArray::New(v8::Local<v8::ArrayBuffer>, unsigned long, unsigned long) -
v8::Value::BooleanValue(v8::Isolate*) const -
v8::Value::InstanceOf(v8::Local<v8::Context>, v8::Local<v8::Object>) -
v8::Value::Int32Value(v8::Local<v8::Context>) const -
v8::Value::IsArray() const -
v8::Value::IsArrayBufferView() const -
v8::Value::IsBoolean() const -
v8::Value::IsDate() const -
v8::Value::IsFunction() const -
v8::Value::IsNumber() const -
v8::Value::IsObject() const -
v8::Value::IsUint16Array() const -
v8::Value::IsUint32() const -
v8::Value::IsUint8ClampedArray() const -
v8::Value::NumberValue(v8::Local<v8::Context>) const -
v8::Value::StrictEquals(v8::Local<v8::Value>) const -
v8::Value::ToInt32(v8::Local<v8::Context>) const -
v8::Value::ToObject(v8::Local<v8::Context>) const -
v8::Value::ToString(v8::Local<v8::Context>) const -
v8::Value::ToUint32(v8::Local<v8::Context>) const -
v8::Value::Uint32Value(v8::Local<v8::Context>) const
It is gonna take a year to implement all these
I have the same error with just installed canvas:
got the same error, July 31st
error: Cannot find module "../build/Release/canvas.node" from "/home/farquaad/xxx/xxx/xxx/node_modules/canvas/lib/bindings.js"
Hi @robobun the module that you mean is canvas, not node-canvas, so it's not bun add node-canvas@next but bun add canvas@next
Hi @robobun the module that you mean is canvas, not node-canvas, so it's not
bun add node-canvas@nextbutbun add canvas@next
Thanks! It helps.
bun add canvas@next is successful, but when I bun ./server.js, I got error below:
error: Cannot find module '../build/Release/canvas.node' from 'E:\Projects\xxx\xxx\node_modules\canvas\lib\bindings.js'
Bun v1.2.19 (Windows x64)
And, yes, there is not any file in folder node_modules\canvas\build\Release.
