この記事は上記のリメイク記事です。同じ内容を取り扱っています。
はじめに
django では、デフォルトの場合フロントエンドのビルドに対するサポートがありません。
書いたファイルをそのまま使うのであれば問題ありません。しかし、sass や ts を使いたいときもありますし、minify 等も面倒を見てくれないため、ある程度以上の規模になると、何らかのビルド機構を導入することを考える必要が発生してきます。
本記事では、幾つかの規模ごとに、扱いやすい構成を考えます。
バニラ - staticfiles
django には staticfiles という app が存在し、これが静的ファイルの配信を司っています。
django-admin 等の公式の app はこの形式です。適当なプロジェクトを作成してみるとわかりますが、django-admin の css は全く圧縮されていません。普通にデプロイすれば、本番環境でも同様です。
django の static は、デフォルトではそのまま配信されるだけです。collectstatic といった static ファイルを集める仕組みはありますが、それだけです。ファイル名さえ一致していればデプロイ時に手動で圧縮することもできますが、個人的にはおすすめしません。
シンプル構成だがビルドはしたい - django_compressor
まずは django_compressor を導入することを検討しましょう。
django_compressor のメリットは、django の仕組みの上に簡単にビルドを構築できることです。テンプレートタグも提供してくれるため、staticfiles と変わらない感覚で使用できます。
使い方については Quickstart を読むのが早いです。INSTALL_APPS と STATICFILES_FINDERS に追加するだけです。
テンプレートの中で使用すると、いい感じに圧 minify してくれます。目的が minify だけの場合はこれで OK です。
{% load compress %}
{% compress css %}
<link rel="stylesheet" href="/static/css/one.css" type="text/css" charset="utf-8">
<style type="text/css">p { border:5px solid green;}</style>
<link rel="stylesheet" href="/static/css/two.css" type="text/css" charset="utf-8">
{% endcompress %}
更に、django_compressor には precompile の仕組みがあり、これを使うことで sass 等をビルドすることができます。
COMPRESS_PRECOMPILERS を設定することで、任意のコマンドを使用してビルドすることができるようになります。
詳しくは公式ドキュメントを読んでください。なお、稀に相性の悪いコマンドも存在する模様ですが、ラッパスクリプトを手動で書くことで解決可能です1。
django から解き放たれて - npm
django の仕組みの上に乗れる django_compressor は便利なのですが、規模が大きくなると複雑になりすぎます。たとえば、webpack を precompilers に指定することは可能ですが、その設定ファイルの置き場所など、いろいろと考える必要があります。
結論から言えば、sass の用に単一コマンドでビルドできる規模よりも大きくなると、django_compressor は適さないと考えます。ビルドするという行為をシンプルに扱えるというメリットが薄れ、設定が肥大化します。
最終的には、django とフロントエンドを疎結合にするべきです。フロントエンドのファイルは npm で管理し、ビルドした生成物のみを django が扱う形にします。
また、規模が大きくなってくと、フロントエンド専任のエンジニアが発生するかもしれません。そのような場合において、フロントエンド環境が django の上に乗っていることは、単純にコストです。フロントエンドのファイルは django の上ではなく npm 環境で扱えるほうが、フロントエンドエンジニアの負担は小さくなるでしょう。
Django REST Framework 等を使用して SPA にする場合でも、この形式は採用することができます。
手順は簡単です。フロントエンド専用の app を作成し、その中で npm init します。あとは、npm で build するときの出力先を、app の static ディレクトリと共有させます。そうすることで、npm で build したものが、django 側からは staticfile として認識されます。
npm の環境については、お好みのものを使用するのが良いでしょう。webpack でも良いですし、今から始めるなら parcel というのもアリです。
ただし、この環境では、ファイルを更新するたびに手動でビルドをしならない点に注意してください。npm 側で watch するコマンドを作っても良いですが、static ディレクトリに必ず出力しなければいけないということを忘れないでください。フロントエンドの場合、開発用サーバーはファイルの出力先が違うケースがあります。
互いを忘れる - swagger
さて、私が検証しているのはここまでになります。しかし、更にフロントエンドと django を疎結合にするケースについても触れておこうと思います。
これまでのケースでは、あくまでフロントエンドのファイルは django の上に乗っていました。しかし、大きな SPA 等になれば、もはや django の上に乗っている必要はありません。
規模が大きい SPA になった場合、互いを API でつなぎ、swagger 等でインターフェースを共有して、疎結合に、別サービスのような形で切り出してしまうのが良いでしょう。リポジトリから分離してしまっても良いかもしれません。
さいごに
django におけるフロントエンド環境のワークフローについて、一通りの考察をすることができました。もちろん、プロジェクトによって事情はいろいろですから、これをそのまま使うことができるとは限りません。
この記事がみなさまのより快適な開発環境の構築に役立てば幸いです。