🤯

React Konva導入が意外と大変だった🥺

2024/03/12に公開

React Konvaというライブラリの検証をしたかっただけなのに、サンプルを表示するまでに思いのほか苦労したので記録を残します💥
ライブラリ自体の使用感について書かれている記事はちらほらあるけど、導入についてまとめられているものが少なそうだったので!

環境

M1Mac
Node.js => 20.11.1
React => 18
Next.js(Approuter) => 14.0.4

※まずReact 17の環境(最新版は18<対応)にて、ライブラリのバージョンを下げて検証しようとし、依存関係やらES ModulesやらCommonJSやらのエラーに当たりMPを削られる💔が、ここは割愛

気を取り直してReact 18環境へ!

さっそく入れてみる

React Konvaは<canvas>をReactで宣言的に書けるライブラリとのこと☺️
まずは公式の指示に従ってnpm installする!ワクワク🙌
npm install react-konva konva --save

⛔️
Module not found: Can't resolve 'canvas' in ***
Did you mean './canvas'?

調べてみると、依存関係の問題で別途canvasのインストールがいるっぽい
Chart.jsなど他のcanvas系のライブラリでも同じな模様
ということでnpm install canvas

npm install canvasでめっちゃ怒られた

⛔️
gyp ERR! find Python ...以下略

はじめて見るエラー😭
gyp ERR!〜の行が羅列され、なにやらPythonのことですごく怒られている
思わずゲッとなってしまう量ですががんばって読みます・・・

結局はこのgithub issueが役に立った!
Pythonのバージョンを上げるなどして、エラー内容が変わった

⛔️
node-pre-gyp ERR! install response status 404 Not Found on
Package pixman-1 was not found in the pkg-config search path.

必要な依存関係をインストールする
brew install pkg-config cairo pango libpng jpeg giflib librsvg

canvasを入れられた!

canvasを入れたら入れたで怒られる

⛔️
./node_modules/canvas/build/Release/canvas.node
Module parse failed: Unexpected character '�' (1:2)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
(Source code omitted for this binary file)

webpack loaderを入れろと言ってくる・・・
調べていると同じ事象に当たっていた方がいた!
ありがたくnext.config.jsを調整

next.config.js
    webpack: (config, { webpack }) => {
    config.experiments = {
      ...config.experiments,
      topLevelAwait: true,
    }
    config.externals.push({
      canvas: 'commonjs canvas',
    })
    config.plugins.push(
      new webpack.ProvidePlugin({
        Buffer: ['buffer', 'Buffer'],
        process: 'process/browser',
      })
    )
    return config
  }

できた!

無事公式のサンプルが表示されました😭

index.js
import React from 'react';
import { createRoot } from 'react-dom/client';
import { Stage, Layer, Rect, Text, Circle, Line } from 'react-konva';

const App = () => {
  return (
    <Stage width={window.innerWidth} height={window.innerHeight}>
      <Layer>
        <Text text="Some text on canvas" fontSize={15} />
        <Rect
          x={20}
          y={50}
          width={100}
          height={100}
          fill="red"
          shadowBlur={10}
        />
        <Circle x={200} y={100} radius={50} fill="green" />
        <Line
          x={20}
          y={200}
          points={[0, 0, 100, 0, 100, 100]}
          tension={0.5}
          closed
          stroke="black"
          fillLinearGradientStartPoint={{ x: -50, y: -50 }}
          fillLinearGradientEndPoint={{ x: 50, y: 50 }}
          fillLinearGradientColorStops={[0, 'red', 1, 'yellow']}
        />
      </Layer>
    </Stage>
  );
};

const container = document.getElementById('root');
const root = createRoot(container);
root.render(<App />);

これでやっと使用感の検証に入れます🥺

Discussion