bitcoinjs / tiny-secp256k1

A tiny secp256k1 native/JS wrapper
MIT License
90 stars 55 forks source link

wasm.memory is undefined #70

Closed taylorjdawson closed 2 years ago

taylorjdawson commented 2 years ago

TypeError: Cannot read properties of undefined (reading 'buffer').

const WASM_BUFFER = new Uint8Array(wasm.memory.buffer);

at src_ts/index.ts line 5

Running this in a create react app with webpack v5.65.0

webpack: {
    alias: {
      assert: "assert",
      buffer: "buffer",
      crypto: "crypto-browserify",
      http: "stream-http",
      https: "https-browserify",
      os: "os-browserify/browser",
      process: "process/browser",
      stream: "stream-browserify",
      util: "util",
    },
    plugins: {
      add: [
        new webpack.ProvidePlugin({
          process: "process/browser",
          Buffer: ["buffer", "Buffer"],
        }),
      ],
    },
    configure: {
      experiments: {
        asyncWebAssembly: true,
      },
    },
  },

Here is the repo. If you have a ledger you can repro. Let me know and I can outline steps

junderw commented 2 years ago

Please see our example react app: https://github.com/bitcoinjs/tiny-secp256k1/tree/v2.1.2/examples/react-app

taylorjdawson commented 2 years ago

@junderw As you can see I already have enabled:

experiments: {
  asyncWebAssembly: true
},

And the rest of the settings are essentially the same unless you see that I am missing something in the config.

junderw commented 2 years ago

Please ask on the react issues.

This issue tracker is a place to track issues for tiny-secp256k1, and wasm.memory is a well defined part of the WASM spec, and we have it working in an example react app.

Anything beyond this is an issue with React and your configuration/environment. Which we are not equipped to assist you with.

classic-k commented 2 years ago

@junderw As you can see I already have enabled:

experiments: {
  asyncWebAssembly: true
},

And the rest of the settings are essentially the same unless you see that I am missing something in the config.

Been on this for 2 days even topLevelAwait did not make wasm.memory defined. Kindly share if you have a workaround thank you

Janaka-Steph commented 2 years ago

@taylorjdawson @classic-k Using Create-React-App v5 I struggled quite a lot to find the right config so I share here my craco.config.js

@junderw Since most people uses React with CRA it would help to document it or add an example app.

const webpack = require('webpack');

module.exports = {
  webpack: {
    configure: (webpackConfig, { env, paths }) => {
      webpackConfig.module.rules = webpackConfig.module.rules.map((rule) => {
        if (rule.oneOf instanceof Array) {
          return {
            ...rule,
            oneOf: [{ test: /\.wasm$/, type: 'webassembly/async' }, ...rule.oneOf],
          };
        }
        return rule;
      });
      //
      const fallback = webpackConfig.resolve.fallback || {};
      Object.assign(fallback, {
        fs: false,
        buffer: require.resolve('buffer'),
        path: require.resolve('path-browserify'),
        stream: require.resolve('stream-browserify'),
      });
      webpackConfig.resolve.fallback = fallback;
      //
      webpackConfig.plugins = (webpackConfig.plugins || []).concat([
        new webpack.ProvidePlugin({
          Buffer: ['buffer', 'Buffer'],
        }),
      ]);
      //
      webpackConfig.experiments = {
        asyncWebAssembly: true,
      };
      return webpackConfig;
    },
  },
  plugins: [
    {
      plugin: {
        overrideWebpackConfig: ({ webpackConfig }) => {
          // Terser
          webpackConfig.optimization.minimizer[0].options.minimizer.options.mangle = {
            ...webpackConfig.optimization.minimizer[0].options.minimizer.options.mangle,
            reserved: ['Buffer'],
          };
          return webpackConfig;
        },
      },
    },
  ],
};

The most important bit is that I had to also add this rule { test: /\.wasm$/, type: 'webassembly/async' }. Also I had an issue with TerserPlugin in prod.

junderw commented 2 years ago

@junderw Since most people uses React with CRA it would help to document it or add an example app.

The react example in the repository currently is building fine.

If you'd like to add some extra tooling that you think is more widely used, pull requests are welcome.

zk1tty commented 2 years ago

@Janaka-Steph 's suggestion solved the issues of using react-srcipts v5.0.1 and react-app-rewired to polyfill Node core modules' functions as well.

The most important bit is that I had to also add this rule { test: /.wasm$/, type: 'webassembly/async' }. Also I had an issue with TerserPlugin in prod.

As long as I see webpack.js under react-srcipts v5.0.1, the resolution of wasm file type is not defined. Once I added the following part into config-override.js, wasm.memory is undefined error is solved.

module.exports = (config) => { 
  config.module.rules = config.module.rules.map((rule) => {
    if (rule.oneOf instanceof Array) {
      return {
        ...rule,
        oneOf: [{ test: /\.wasm$/, type: 'webassembly/async' }, ...rule.oneOf],
      };
    }
    return rule;
  });