boa-dev / boa

Boa is an embeddable and experimental Javascript engine written in Rust. Currently, it has support for some of the language.
MIT License
4.82k stars 385 forks source link

buffer Node.js polyfill for the browser breaks with Uncaught TypeError: not a callable function #2959

Open lastmjs opened 1 year ago

lastmjs commented 1 year ago

Describe the bug

I am trying to use the buffer polyfill to provide more capabilities to our project Azle. Unfortunately when trying to use the bitcoinjs-lib npm package which depends on Buffer, an error is thrown when trying to do the following import { address } from 'bitcoinjs-lib'; I've tracked it down to an issue in Buffer.

In the fromString function buf.write is what causes the error. I imagine there is some kind of bug in Boa in regards to prototypes or the order of initializing functions or something. When I move the definition of Buffer.write around I have been able to get past that error, but the error is thrown again in another part of the code. So I've given up and I'm writing this off as a bug in Boa that will hopefully resolve the other errors.

To Reproduce

If you just try to import { address } from 'bitcoinjs-lib'; you should immediately run into the issue. We have a build step before executing the code in Boa using swc and esbuild, I am not sure if the project can be executed in Boa without bundling of some kind. I also doubt it's a problem with these bundlers given the maturity of the bundlers relative to Boa, but I'm not sure.

Expected behavior

The libraries should load and execute without errors.

Build environment (please complete the following information):

Additional context

I often find bugs in Boa when trying to load npm packages, perhaps loading popular packages from npm would be a good way to increase test coverage.

jedel1043 commented 1 year ago

Probably related to the require calls? I tried to reproduce it by copying the whole index.js file, removing all functionality related to the required packages base64 and ieee754 and running a simple test:

let buf = new Buffer(255);

buf.write("hello!");

console.log(buf);

However, this correctly prints hello! and returns successfully. Let me see if bundling gives a different result.

jedel1043 commented 1 year ago

Note that Boa doesn't implement require, since that's a feature that is commonly implemented by the runtime.

jedel1043 commented 1 year ago

Hmm, tried to bundle it to see if anything changed but everything seems alright... My build script:

import { build } from "esbuild";
import { polyfillNode } from "esbuild-plugin-polyfill-node";

build({
    entryPoints: ["src/index.js"],
    bundle: true,
    outfile: "dist/bundle.js",
    plugins: [
        polyfillNode({
            // Options (optional)
        }),
    ],
});

Just required installing esbuild-plugin-polyfill-node and bitcoinjs-lib, and removing a line which referenced the navigator object, which is also only available in browsers.

lastmjs commented 1 year ago

I can give a more reproducible example, I've continued to run into this issue and I wonder if it is something in the bundler that is exposing a bug in Boa.