GitHubじゃ!Pythonじゃ!

GitHubからPython関係の優良リポジトリを探したかったのじゃー、でも英語は出来ないから日本語で読むのじゃー、英語社会世知辛いのじゃー

markfinger

python-react – Reactコンポーネントのサーバーサイドレンダリング

投稿日:

Reactコンポーネントのサーバーサイドレンダリング

python-react

Pythonシステムからのデータを使ったReactコンポーネントのサーバーサイドレンダリング

from react.render import render_component

rendered = render_component(
    '/path/to/component.jsx',
    {
        'foo': 'bar',
        'woz': [1,2,3],
    }
)

print(rendered)

クライアント側の統合については、 ドキュメントを参照してください。

ドキュメンテーション

インストール

pip install react

基本的な使用法

python-reactは、あなたのpythonプロセスからのデータでReactコンポーネントをレンダリングすることができるレンダリングサーバへのインタフェースを提供します。

レンダリング要求は、ReactコンポーネントをエクスポートするJSファイルへのパスを提供する必要があります。 コンポーネントにデータを渡したい場合は、オプションで、コンポーネントのpropsプロパティとして使用される2番目の引数を指定できます。

from react.render import render_component

rendered = render_component('path/to/component.jsx', {'foo': 'bar'})

print(rendered)

返されるオブジェクトには2つのプロパティがあります。

  • markup – レンダリングされたマークアップ
  • props – JSON連載小道具
  • data – レンダリングサーバから返されるデータ

オブジェクトが文字列に変換されると、 markup属性の値が出力されます。

レンダリングサーバの設定

レンダーサーバーは通常、Pythonプロセスと並んでネットワーク要求に応答するNode.jsプロセスです。

プロジェクトにレンダリングサーバーを追加するには、ほとんどのケースをカバーする単純なサーバーの基本的なレンダリングの例を参照してください。 レンダリングサーバーのキーファイルは次のとおりです。

フロントエンドでのリアクションの使用

ReactをPythonシステムのフロントエンドに統合するには、いくつかの方法があります。 典型的なセットアップには、ビルドツールとそれを統合できるpythonパッケージが含まれます。

2つの最も一般的なビルドツールは次のとおりです。

  • Webpack – ファイルをブラウザ実行可能コードにコンパイルし、複雑なワークフローを簡素化するさまざまなツールとプロセスを提供します。
  • Browserifywebpackには多くのクロスオーバーがあります。 argurablyは2つの中で最も使いやすいものですが、機能的にwebpackの後ろにいる傾向があります。

Reactプロジェクトの場合は、webpackが通常の推奨事項であることがわかります。 Webpackのホットモジュールの置き換え、コード分割、豊富なローダーは、典型的には置き換えられないものとして挙げられている機能です。 反応ホットローダーは、コンポーネントの変更をブラウザーにライブストリーミングできるため、特に便利なツールです。

Webpackの出力をPythonシステムに統合したい場合は、パスをハードコードするか、Pythonシステムがコンパイラの状態をイントロスペクトする方法を提供するマニフェストプラグインを使用できます。

最も一般的なマニフェストツールはowais / django-webpack-loaderです。 Owaisはたくさんのドキュメントとサンプルを提供していますので、Webpackをプロジェクトに統合するのが最良の方法です。

Djangoシステムを実行していない場合や、デカップリングとデプロイメントが可能な移植可能なマニフェストが必要な場合は、 markfinger / python-webpack-manifestがあなたのニーズに合っているかもしれません。

また、 markfinger / python-webpackもありますが、これはもう少し重く抽象的で、PythonとJavaScriptの世界の間に本当に緊密な結合が必要な場合にのみ使用されます。

render_component

コンポーネントを最初のHTMLにレンダリングします。 このメソッドを使用すると、サーバー上でHTMLを生成し、最初のリクエストでマークアップを送信してページの読み込みを高速化したり、検索エンジンがSEO目的でページをクロールできるようにすることができます。

使用法

from react.render import render_component

render_component(
    # A path to a file which exports your React component
    path='...',

    # An optional dictionary of data that will be passed to the renderer
    # and can be reused on the client-side.
    props={
        'foo': 'bar'
    },

    # An optional boolean indicating that React's `renderToStaticMarkup` method
    # should be used, rather than `renderToString`
    to_static_markup=False,

    # An optional object which will be used instead of the default renderer
    renderer=None,

    # An optional dictionary of request header information (such as `Accept-Language`)
    # to pass along with the request to the render server
    request_headers={
        'Accept-Language': 'da, en-gb;q=0.8, en;q=0.7'
    },

    # An optional timeout that is used when handling communications with the render server.
    # Can be an integer, a float, or a tuple containing two numeric values (the two values
    # represent the individual timeouts on the send & receive phases of the request).
    # Note that if not defined, this value will default to (5, 5)
    timeout=None
)

Djangoプロジェクトでpython-reactを使用している場合、コンポーネントへの相対パスはDjangoの静的ファイル検索ツールを介して解決されます。

デフォルトでは、render_componentは、 リアクションレンダーのAPIと互換性のあるエンドポイントを公開するレンダリングサーバーへのアクセスに依存します 別のレンダラーを使用する場合は、オブジェクトをrenderer argとして渡しrenderer オブジェクトは、 pathdatato_static_markup 、およびrequest_headers引数を受け入れるrenderメソッドを公開する必要があります。

レンダリングサーバー

以前のバージョンのこのライブラリでは、レンダリングサーバーをサブプロセスとして実行するため、開発が容易になりましたが、不安定で不透明な動作が発生しました。 これらの問題を避けるために、python-reactは外部管理されたプロセスに依存しています。 余分なプロセスを管理することで、最初はオーバーヘッドが増えることがありますが、トラックの痛みを避けることができます。

特定の環境でのみレンダリングサーバーを実行する場合は、 RENDER設定をFalseに変更しRENDER RENDERがFalseの場合、レンダリングサーバーは直接使用されませんが、ラッパーはmarkup属性を持つ同様のオブジェクトを空の文字列として返します。

開発における使用法

開発環境では、 RENDER設定をFalseに設定するのが最も簡単です。 これは、レンダリングサーバーが使用されないようにするため、あなたはあなたのpythonプロセスを管理する必要があります。

例や他の場所で提供されているレンダーサーバーは、Node.jsのモジュールシステムに依存していることに注意してください。モジュールシステムは、Pythonと同様に、すべてのモジュールをインポートするとすぐにキャッシュします。 開発環境でレンダリングサーバーを使用すると、コードがキャッシュされ、レンダリングサーバーをリセットするまで、変更はレンダリングされたマークアップに影響しません

プロダクションでの使用

本番環境では、 RENDERがTrueに設定されていることを確認する必要がありRENDER

任意のスーパバイザプロセスが必要な場合は、レンダリングサーバーを実行することをお勧めします。 設定に応じて、環境を反映するためにRENDER_URL設定を変更する必要があります。

レンダリングサーバーは、 NODE_ENV=production node render_server.js 、環境変数NODE_ENVproductionに設定して実行する必要があります。 Reactはデフォルトを開発モードにし、 NODE_ENV変数を使用してレンダリングを遅くするdev指向のコード(型と制約のチェック)を無効にします。 この変数を定義することで、コードがはるかに高速にレンダリングされます。

負荷に応じて、ワーカーを使用してレンダリングを処理することができます。 ノードのクラスタモジュールは、プロセスをフォークし、単一のネットワークアドレスから複数のインスタンスを提供する簡単な方法を提供します。

ワーカーファームに代わる方法は、レンダリングサーバーの前にキャッシュを置くことです。 レンダーサーバーの要求はPOST要求として送信され、ほとんどのリバースプロキシはPOST要求のキャッシュに問題があることに注意してください。

レンダリングサーバーラッパーがJSプロセスに接続すると、urlに?hash=...パラメーターが追加されます。 ハッシュ・パラメータは、要求の本体で送信される直列化されたデータのSHA-1ハッシュであり、レイヤーをキャッシュすることによって消費されることを意図しています。

もう1つの選択肢は、呼び出しをレンダリングサーバーにキャッシングシステムに配線することです。 renderer kwargをオーバーライドすると、サーバーに呼び出しをラップして、データがローカルで使用可能かどうか最初にチェックし、レンダリングされたマークアップでキャッシュにデータを取り込むようにフォールバックすることができます。

レンダラーのオーバーライド

デフォルトのレンダラーをオーバーライドする場合、 renderer引数をrender_component一貫して定義できるように、ラッパー関数を作成する方法がありrenderer 例えば:

from react.render import render_component

class MyRenderer(object):
    def render(self, path, props=None, to_static_markup=False, request_headers=None, timeout=None):
        # ...

def my_render_function(*args, **kwargs):
    kwargs['renderer'] = MyRenderer()
    return render_component(*args, **kwargs)

設定

非djangoプロジェクトでpython-reactを使用している場合は、定義する設定に一致するキーワード引数を指定してreact.conf.settings.configureを呼び出すことで設定を定義できます。 例えば:

from react.conf import settings

DEBUG = True

settings.configure(
    RENDER=not DEBUG,
    RENDER_URL='http://127.0.0.1:9009/render',
)

Djangoプロジェクトでpython-reactを使用している場合は、 INSTALLED_APPS 'react'を追加し、 REACT辞書に設定を定義します。

INSTALLED_APPS = (
    # ...
    'react',
)

REACT = {
    'RENDER': not DEBUG,
    'RENDER_URL': 'http://127.0.0.1:8001/render',
}

レンダリング

レンダーサーバーを使用する必要があることを示すフラグです。 Falseに設定すると、レンダラーは空の文字列を持つオブジェクトをmarkup属性として返します。

コンポーネントの事前レンダリングは、マークアップのサービスがすばやく必要とされる環境向けにのみ設計されています。 実際の開発環境では、複数のプロセスを実行すると設定が複雑になり、レンダリングサーバーのファイルキャッシュによって不可解な動作が発生する可能性があります。 これをFalse設定すると、Pythonサーバーの隣にあるレンダリングサーバーを実行する必要がなくなります。

デフォルト: True

RENDER_URL

反応レンダーのAPIに準拠するPOST要求を受け付けるエンドポイントへの完全なURL。

デフォルト: 'http://127.0.0.1:9009/render'

よくある質問

レンダリングサーバーから余分なデータを返すにはどうすればよいですか?

レンダーサーバーのコードを編集し、返されたペイロードに任意のデータを注釈を付けることができます。 レンダーサーバーによって提供されるペイロードは、応答オブジェクトのdata属性の下で使用できます。

例えば:

from react.render import render_component

rendered = render_component('path/to/component.js')

print(rendered.data)

Python-reactはDjangoと統合できますか?

python-reactはDjangoの設定と統合することができ、レンダラーの統合はdjangoの静的ファイル検索ツールを使ってコンポーネントへの相対パスを解決することができます。

Djangoの翻訳とgettextをReactコンポーネントで扱うにはどうしたらいいですか?

sillygodはこの問題#69でこれについて議論しました。

python-reactはWeb2Pyと統合できますか?

Anima-t3d#70の経験を書き上げています。

子コンポーネントをルートコンポーネントに渡すにはどうすればよいですか?

Anima-t3dは、問題#71でこれについて議論しました。

テストの実行

pip install -r requirements.txt
npm install
python runtests.py







-markfinger
-

執筆者: