6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[React] Next.js 13の中でPythonを動かす

Posted at

人に話すとたまに驚かれますが、じつはNext.jsの中でPython環境を動かすことができます。

Pyodideという、WASMのおかげでブラウザ上で使えるPython環境があるのですが、それをReactの中で使いやすくなるhookなどが提供されるreact-pyというnpmパッケージも存在します。

前回の記事と同じように、クライアント側でしか動かない仕組みですが、今回はNext.js 13のクライアント コンポーネントという機能を使ってインポートなどをわかりやすくしようと思いました。

今日の流れはこのようになります:

  1. Next.js 13(TypeScript)のテンプレートから始める
  2. react-pyでPythonコードが入力・実行できるコンポーネントを用意
  3. Chakraを使って簡単に見た目を良くする

Next.js 13(TypeScript)のテンプレートから始める

現在、デフォルトでNext.js 13とTypeScriptが導入されます。

yarn create next-app

npmpnpm、別のツールを使うことももちろん可能です。この記事ではyarnで進めていきます。

また、色々と選択することになると思いますが、デフォルトと違った自分の選択肢を共有します:

  • Would you like to use Tailwind CSS with this project? › No
    Chakraを使う予定でしたので、Tailwindは不要だと思いました(Python環境の部分に影響ありません)
  • Would you like to customize the default import alias? › Yes
    What import alias would you like configured? … @/*
    プロジェクト内のコンポーネントがインポートしやすくなります(Python環境の部分に影響ありません)

react-pyでPythonコードが入力・実行できるコンポーネントを用意

まずはreact-pyをインストールしましょう。

yarn add react-py

ドキュメントではもはやNext.js 13のクライアント コンポーネントでの使い方しか紹介されませんが、Next.js 12ではnext/dynamicでインポートできます。既存のプロジェクトでreact-pyをそのまま使いたい場合はNext.js + p5.jsについて書いた記事を参照してください。やり方は同じになります。

今回はあえて最新のNext.js 13で使える、より簡単な方法を紹介したいと思います。先ほどドキュメントへのリンクを貼りましたが、まずはPython環境を使いたいコンポーネントかページの一行目に'use client'を付けてクライアント コンポーネントにしましょう。クライアント コンポーネントはサーバー側でのNext.jsによる生成の対象外になるのでnext/dynamicなどが不要になります。

PythonProviderを挿入する

Pythonようにクライアント コンポーネントにしたいページかコンポーネントの一番上をこのようにしましょう:

'use client'

import { PythonProvider } from 'react-py'

そのPythonProviderを本ページの出力に加えましょう。react-pyのhookを使うことになるコンポーネントを囲うようにしましょう:


export default function Home() {
  return (
    <PythonProvider>
      <main>
        <Codeblock />
      </main>
    </PythonProvider>
  )
}

Codeblockはこのチュートリアルの任意コンポーネントになります。

Codeblockコンポーネント

react-pyの使い道はいっぱいあると思いますが、この度はドキュメントの通り<textarea>にPythonコードを書いて実行できるコンポーネントにしましょう。

まずはusePython hookをインポートしましょう。クライアント コンポーネントにしますので、先ほどのPythonProviderと同じくそのままインポートできます:

'use client'

import { usePython } from 'react-py'

コンポーネントの定義の中でusePythonを使いましょう:

export default function Codeblock() {
  const { runPython, stdout, stderr, isLoading, isRunning } = usePython()

  return (
    <>
      ...
    </>
  )
}

取得するのは:

  • runPython: (code: string) => Promise<void>: Pythonコードを渡すと実行してくれる関数
  • stdout: string: Pythonの標準出力
  • stderr: string: Pythonの標準エラー出力
  • isLoading: boolean: Python環境を読み込み中かどうか(WASM自体がcdn.jsdelivr.netから読み込まれます)
  • isRunning: boolean: Python環境が処理中かどうか

usePythonからisReadyなど取得できる定数や関数が他にもありますので、必要に応じて使いたいと思います。

Chakraを使って簡単に見た目を良くする

最後に、本題ではないですがChakra UIで形にしたいと思います。Chakraを初めてNext.js 13で使ってみましたので勉強になったので、かるく共有したいと思います。

Pyodideと直接関係がないので、違うウェブコンポーネントを使う場合は下記読んでいただかなくても大丈夫だと思います。一応形にしなければならいないと思いましたので、割と簡単な方法で対応してみたまでです。

まずはChakraなどをインストールしましょう。

yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion

次に、react-pyPythonProviderがあるようにChakraにChakraProviderというのがあります。Chakraコンポーネントを使うところをこれで囲いたいです。

Next.js 13のlayout.tsxをこのようにしました:

import { ChakraProvider } from '@/tools/chakra-client-components'

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html>
      <head>
        <title>Next.js 13 + Chakra + react-py</title>
      </head>
      <body>
        <ChakraProvider>{children}</ChakraProvider>
      </body>
    </html>
  )
}

ChakraProviderは、クライアント コンポーネントではなくても使うことができますので、RootLayoutをクライアントコンポーネントにする必要がありません。サーバー側生成とChakraはちゃんと同時に使えます。

あとはChakraのドキュメントと完成したコンポーネントのコードを参照してください:

一番注意したいところは、HTML5のtextareaタグのdisabledプロパティは、ChakraのTextareaコンポーネントとなるとisDisabled: booleanを使わなければならないところです。

最後に

Next.jsで外部APIを使わずにPythonをブラウザ上で実行できました。また、Next.js 13の新しいクライアント コンポーネントを使ってブラウザ側でしか使えないコンポーネントやhookをスムーズにインポートできました。

任意のPythonパッケージのインストールなどPyodideが充実していますので、したいことが意外と可能だったりしますのでユーザーの生データを外部APIに送りたくない場面では積極的に考えたい選択肢だと思います。

サンプルリポもよかったらご参照ください。そしてご不明点、ご要望などありましたらコメントやツイッターでご連絡いただければ嬉しいです。

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?