Django版『フロントエンドエンジニアのための「俺の最近のRailsのJS開発環境」を考察する』

#「俺の最近のDjangoのJS開発環境」 for フロントエンドエンジニア

## TL;DR

-「片手間のJS」ならdjango-compressorで大丈夫
-「本気でJS書く」なら単一Appとして切り出す（e.g. SPA, etc.）
- 迷えるフロントエンドエンジニアに愛の手を:pray::pray::pray:

※ 個人の見解です

## はじめに

**怒られたら消します**

本職は受験生，片手間にRailsエンジニア，そのさらに片手間にDjangoエンジニアやってる人間の戯言です．

内容自体は至って真面目なことを書いているつもり。

## Django版「俺の最近のRailsのJS開発環境を教えてやる」

### バニラDjangoの場合

デフォルトだと何も入っていないので生JS/CSSを書くことになる。`django.contrib.admin`に行くとつらそうなコードがたくさん見られる。Djangoの公式Appなので、外部ライブラリに依存することはできないっぽい。

Railsならscriptタグなども`layout/application.html.erb`などにデフォルトで挿入されているが、djangoだと手動。ファイル数が増えてくるとしにたくなる。

あと、ファイルの結合、圧縮の仕組みが無い(たぶん)。

### django-compressorを使ってみた。

django-compressorをインストールしたあと、`INSTALLED_APPS`とか`STATICFILES_FINDERS`とかに追加してから、以下の用な設定を追加する。

```settings.py
COMPRESS_PRECOMPILERS = (                                                                                                                                     
    ('text/es6+javascript', 'babel -o {outfile} {infile}'),                                                                                                   
)
```

これで準備は完了で、あとは`type`属性を指定する以外は、通常のjsの用に書けば適当に変換してくれる。

インラインに書くのも、外部ファイルを指定するのも自由。

`django-compressor`という名前の通り、結合・圧縮もできる（というかそっちがメイン?）。デフォルトだと`DEBUG=False`の時のみ圧縮される。

```html+django
{% load compress %}
{% compress js %}
<script type='text/es6+javascript' src='src.js'></script>
<script type='text/es6+javascript'>
  // hogehoge
</script>
{% endcompress %}
```

## なにが足りない?

### ビルドプロセスが貧弱

コマンドを指定するだけなので、複雑なことはやりにくい。コマンド指定する以外にもいろいろ細かくできるけど、かなり面倒。

これは決して悪というわけではなく、簡単なcoffeeやlessなどを使うときには非常に便利。

### JSのテストどうするよ

テストをes6で書きたい場合など、django-compressorは一切面倒を見てくれない。

## ならどうするか: JSの世界でJSを書く

Djangoの静的ファイルの機構にビルド処理を挟みこむことを諦める。

### webpackを導入する。

適当に`webpack.config.js`を作ります。

しかし、普通にやるとAppを跨いだ参照が非常に面倒なので、各Appのstaticをrootに指定してやるのが良い(手動でやるの面倒なので誰かsettings.pyを解析してrootに追加するライブラリ作って)

公開しないAppの場合は、`static/src`以下にビルド前のソースを置いて、出力ファイル自体はリポジトリから除外してしまって良い。公開するAppの場合は、使用する人にWebpackを使うことを強制することになってしまうので、出力ファイルもリポジトリに含めるべき。

```webpack.config.js
var webpack = require('webpack');

module.exports = {
  entry: './app/static/src/app.js',
  output: {
    path: './app/static/'),
    filename: 'bundle.js',
  },
  resolve: {
    root: [
      './app1/static/src',
      './app2/static/src',
    ],
  },
```

Karmaとか入れたいときもwebpackと同様に、ディレクトリにだけ注意して設定ファイルを書く。

### フロントエンドのコードを他のAppから分離させる

ここまでの手順を踏んでも、JSのコードは各Appに分散するので、フロントエンドエンジニア的には辛いと感じるかもしれない。

そういう場合は、新たにfrontendというAppを作り、そこに分離する。そして、Appを単一のプロジェクトとみなして、frontend以下にpackage.jsonなどを置く

こうすることで、バックエンドとフロントエンドをほぼ完全に分離でき、それぞれの担当が幸せになれる。

もちろん、フロントエンド側のプロジェクトもDjangoの仕組みに乗っているので、Angular用の部分テンプレートをサーバーサイドでレンダリングする、なんてことも簡単にできる。

注意するべきは、ビルドファイルの出力先をstaticにすること。それ以外はかなり自由になんでもできる。

# 結論

結局冒頭に書いた考え方でいいように思う

> -「片手間のJS」ならdjango-compressorで大丈夫
> -「本気でJS書く」なら単一Appとして切り出す（e.g. SPA, etc.）
> - 迷えるフロントエンドエンジニアに愛の手を:pray::pray::pray:

DjangoはRailsよりも自由度がかなり高いフレームワークなので、もっといろんなやり方があるかもしれません。

私自身、Python/Django界隈との交流があまりないので、ここに書いたことはRails界隈(というより@izumin5210)のノウハウが多く取り入れられています。

たくさんの突っ込みをいただければ幸いです。

# Special Thanks

- [フロントエンドエンジニアのための「俺の最近のRailsのJS開発環境」を考察する - Qiita](http://qiita.com/izumin5210/items/c642ae75f916d301456a)
- [俺の最近のRailsのJS開発環境を教えてやる - Qiita](http://qiita.com/kozo002/items/a276569e85395fce801e)

# References

- [Django Compressor — Django Compressor 1.5 documentation](http://django-compressor.readthedocs.org/en/latest/)