django-webpack-loader のセットアップ

# django-webpack-loader

- django: 2.2
- webpack: 4.30.0
- django-webpack-loader: 0.6.0

djangoでwebpackを使いたいとき。django-webpack-loaderがおすすめ。

[GitHub - owais/django-webpack-loader: Transparently use webpack with django](https://github.com/owais/django-webpack-loader)

過去にもdjango-webpack-loaderについて触れた記事を書いた。
- [Django + Webpack を使ってVueを動かす](https://qiita.com/ynakahira/items/a81825aeb67c32232fb5)
- [webpackをつかってdjangoでbootstrap4をはじめる](https://qiita.com/ynakahira/items/bd8580397fc2615b9dd8)

今回は最新の情報で、簡潔に。

## セットアップ

プロジェクトフォルダを作成。例として「PROJECTNAME」。そしてフォルダ内に移動。`npm init`する

```shell
mkdir PROJECT_NAME
cd PROJECT_NAME
npm init -y
```


npmで必要なモジュールをインストール

```shell
npm install --save-dev webpack webpack-cli webpack-bundle-tracker
```

webpack-bundle-trackerはwebpackのバンドル情報をwebpack-stats.jsonというファイルに吐き出す。django-webpack-loaderはこのwebpack-stats.jsonを使っている。

[GitHub - owais/webpack-bundle-tracker: Spits out some stats about webpack compilation process to a file](https://github.com/owais/webpack-bundle-tracker)

webpackの設定ファイル webpack.config.jsを作成

```shell
touch webpack.config.js
```
編集。

```js:webpack.config.js
var path = require("path")
var webpack = require('webpack')
var BundleTracker = require('webpack-bundle-tracker')

module.exports = {
  mode: 'development',

  context: __dirname,

  entry: {
      main: './assets/js/main.js' // エントリ名とエントリポイント
  },

  output: {
      path: path.resolve('./assets/webpack_bundles/'), // 出力
      filename: "[name]-[hash].js",
  },

  plugins: [
    new BundleTracker({filename: './webpack-stats.json'}),
  ],
}
```

上記のように、エントリは/assets/js/に、出力は/assets/webpack_bundles/に設定した。それぞれフォルダを作成しておく

```
mkdir -p assets/js
mkdir assets/webpack_bundles
```

---

### django-webpack-loaderのインストール

もしdjangoをインストールしていなければ

```shell
pip install django
```

djangoのプロジェクトを作成。名前は例として「djangoproject」。

```shell
django-admin.py startproject djangoproject
```

```shell
pip install django-webpack-loader
```

```py:djangoproject/djangoproject/settings.py
...

INSTALLED_APPS = (
 ...
 'webpack_loader',
)

...

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, '../assets'), 
)

...

WEBPACK_LOADER = {
    'DEFAULT': {
        'CACHE': not DEBUG,
        'BUNDLE_DIR_NAME': 'webpack_bundles/', # must end with slash
        'STATS_FILE': os.path.join(BASE_DIR, '../webpack-stats.json'),
        'POLL_INTERVAL': 0.1,
        'TIMEOUT': None,
        'IGNORE': [r'.+\.hot-update.js', r'.+\.map']
    }
}


```

## 使用例: Vue.js

vueを使ってみる。

```
npm install --save-dev vue
```

エントリポイントの作成

```
touch assets/js/main.js
```

編集。

```js:assets/js/main.js
window.Vue = require('vue');
```

上記のように書く際はランタイムだけのビルドを読み込む必要がある。

[Vue is not a constructor
](https://stackoverflow.com/questions/42343778/vue-is-not-a-constructor)

webpack.config.jsに追記。

```js:webpack.config.js
module.exports = { 
  ...
  resolve: {
    alias: {
      vue: 'vue/dist/vue.js'
    }
  },
  ...
}
```


コンパイル。

```shell
./node_modules/.bin/webpack --config webpack.config.js
```

assets/bundlesにバンドルされたファイルができる

djangoでバンドルを呼び出してみる。vueというアプリを仮につくる

```shell
mkdir -p djangoproject/vue/templates/vue
touch djangoproject/vue/templates/vue/index.html
```

```py:djangoproject/djangoproject/settings.py
INSTALLED_APPS = (
 ...
 'vue',
)
```

```py:djangoproject/djangoproject/urls.py
...
from django.views.generic.base import TemplateView
...

urlpatterns = [
    ...
    path('', TemplateView.as_view(template_name='vue/index.html')),
    ...
]

```

Hello Vue!

```django:djangoproject/vue/templates/vue/index.html
{% load render_bundle from webpack_loader %}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Example</title>
  </head>

  <body>
    {% verbatim %}
    <div id="app">
      {{ message }}
    </div>
    {% endverbatim %}

    {% render_bundle 'main' %}
    <script>
      var app = new Vue({
        el: '#app',
        data: {
          message: 'Hello Vue!'
        }
      })
    </script>
  </body>
</html>
```
`render_bundle`はテンプレートに必要な`script`と`link`を読み込む。`{{ message }}`がdjangoによってレンダリングされないよう、`verbatim`している

```shell
python djangoproject/manage.py runserver
```
`http://127.0.0.1:8000/`をブラウザで開く