rive-app / rive-wasm

Wasm/JS runtime for Rive
MIT License
669 stars 46 forks source link

Issue loading the .riv file when configured using webpack. #298

Open vigsub opened 1 year ago

vigsub commented 1 year ago

I'm using webpack 5 for bundling and trying to load a rive file into my React app. I'm getting the following error.

Screenshot 2023-03-18 at 12 03 46 AM

These are the rules in the webpack config file.

module.exports = {
  experiments: {
    asyncWebAssembly: true
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
      {
        test: /\.scss$/,
        use: ['style-loader', 'css-loader', 'sass-loader']
      },
      {
        test: /\.(js|jsx)$/,
        use: ['babel-loader']
      },
      {
        test: /\.(ts|tsx)$/,
        exclude: /node_modules/,
        use: ['babel-loader']
      },
      {
        test: /\.(gif|jpg|png|woff|ttf|eot)$/,
        loader: 'file-loader'
      },
      {
        test: /\.svg$/,
        loader: 'svg-react-loader'
      },
      {
        test: /\.wasm$/,
        type: 'javascript/auto',
        use: ['url-loader']
      }
    ]
  }
};

As suggested in one of the resolved issues in this repo, I'm using the following approach.

function TestRive({ asset, className, animation, fit, alignment }) {
  const canvas = useRef(null);
  const animationContainer = useRef(null);
  const rive = useRef(null);

  // Start the animation
  useEffect(() => {
    rive.current = new Rive({
      src:'https://cdn.rive.app/animations/vehicles.riv',
      canvas: canvas.current,
      layout: new Layout({ fit: 'cover', alignment: 'center' }),
      autoplay: true
    });
    return () => rive.current.stop();
  }, [asset, fit, alignment]);

  return (
    <div ref={animationContainer} className={className}>
      <canvas ref={canvas} width="500" height="500" />
    </div>
  );
}

Also tried multiple ways of loading the rive component.

function TestRive() {
  const { rive, RiveComponent } = useRive({
    src: 'https://cdn.rive.app/animations/vehicles.riv',
    autoplay: true
  });
  return (
    <div>
      <RiveComponent />
    </div>
  );
}

P.S: It is working fine in any sample app created with create-react-app. But in the app where I use webpack to manually configure, it's not working as expected and throws the binding error message. What are the loaders I'm missing? Or is it something else that I'm missing?

vigsub commented 1 year ago

@zplata Can you help with this? I'm kinda stuck here..

zplata commented 1 year ago

Hi @vigsub - The error comes from Emscripten which does the binding of underlying C++ code to JS. In this case, there's an underlying function that thinks it's taking in an enum and you're passing string values in your Layout options. You'll want to import Fit and Alignment as named imports and use Fit.Cover and Alignment.Center.

import {Fit, Alignment} from '@rive-app/canvas';

// or

import {Fit, Alignment} from '@rive-app/react-canvas'
zplata commented 1 year ago

@vigsub wonder if this helped solve your issue?

vigsub commented 1 year ago

Oops. Sorry.. Missed this thread. Will check this and respond. Thanks :)

vigsub commented 1 year ago

Nope.. Not working :( .. If providing Fit.Cover and Alignment is a problem, in the second example mentioned, I don't use them. Still it's not rendering. @zplata I suppose this has something to do with the loaders in webpack?? Please assist..

zplata commented 1 year ago

@vigsub sorry to hear - I don't imagine it should be an issue with Webpack as you're not trying to import WASM or Rive files in your JS/TS files, but not to say that it couldn't be the issue! In case I'm missing context here, do you have a repro project that you can post here so that we can debug further and run in isolation?