8
15

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 5 years have passed since last update.

【Django】DjangoによるWeb開発プロジェクトPart3 - webpackでフロントエンドをDjangoから独立させるまで -

Last updated at Posted at 2018-12-01

はじめに

今日はフロントエンドの設定を行います。

フロントエンドをDjangoと独立させてマネジメントできるようにwebpackを追加する

一先ず、今後どうなるかは分かりませんがRails5の開発と同じくバックエンドとフロントエンドでそれぞれの別に、独立したマネジメントツールで運用したいため、Djangoにもwebpackをインストールする事にします。
以前、npmマネージャーからwebpackをインストールしていましたが、今回はyarnマネージャーからインストールする事にします。

% sudo pkg update
% sudo pkg install yarn

なお、Djangoでwebpackを読み込むためにjango-webpack-loaderと言うWrapperを使います。
こちらは、webpack-bundle-trackerによって生成された出力ファイルをDjangoで使えるようにします。
また、今回はフロントエンドはbootstrap-vueを使う訳なのですが、それに伴いJavaScriptからcssをimportできるように、各ローダを一緒にインストールしておきます。

webpack, vue-bootstrapをインストール

% yarn add --dev webpack
% yarn add --dev bootstrap-vue
% yarn add --dev webpack-bundle-tracker css-loader style-loader babel-loader @babel/core vue

では、webpack.config.jsの設定を行なっていきましょう。

webpack.config.jsの設定

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

module.exports = {
    entry: './frontend/packs/application.js',
    output: {
      path: path.resolve(__dirname, './public/bundles/'),
      filename: "[name]-[hash].js",
    },
    plugins: [
      new BundleTracker({filename: './webpack-stats.json'})
    ],
    module: {
        rules: [
            {
                test: /\.js$/,
                include: [ // use `include` vs `exclude` to white-list vs black-list
                    path.resolve(__dirname, "node_modules"), // white-list your app source files
                    require.resolve("bootstrap-vue"), // white-list bootstrap-vue
                ],
                loader: "babel-loader"
            },
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            }
        ]
    }
}

エントリーポイントのapplication.jsを編集

application.jsでbootstrap-vueをimportするように記述します。ついでに必要なディレクトリを作成していきます。

% mkdir -p frontend/packs
% mkdir -p public/bundles
frontend/packs/application.js
import Vue from 'vue'
import BootstrapVue from 'bootstrap-vue'

Vue.use(BootstrapVue);

import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'

以上で、development環境でwebpackのコンパイルを行います。

% ./node_modules/.bin/webpack --config webpack.config.js --mode=development

続いてはDjango側の設定です。

Djangoのwebpack設定

pipでdjango-webpack-loaderをインストールします。その後、Djangoのsettings.pyを以下のように設定してあげましょう。

% pip install django-webpack-loader
settings.py
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'public'),
)
WEBPACK_LOADER = {
    'DEFAULT': {
        'BUNDLE_DIR_NAME': 'bundles/',
        'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.json'),
    }
}
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'webpack_loader',
]

テンプレートエンジンでwebpack_loaderとコンパイルしたmain.jsを読み込めるようにします。

templates/application.html
{% load render_bundle from webpack_loader %}
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>{% block title %}Django Auth Tutorial{% endblock %}</title>
      {% render_bundle 'main' %}
  </head>
  <body>
    <main>
      {% block content %}
      {% endblock %}
    </main>
  </body>
</html>

ログイン画面改善

webpackによるコンパイルが完了したので、BootStrapでログイン画面のデザインを改良してきましょう。下記のテンプレートを参考にします。
https://getbootstrap.com/docs/4.0/examples/sign-in/

packs/css/signin.css
html,
body {
  height: 100%;
}

body {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-align: center;
  align-items: center;
  padding-top: 40px;
  padding-bottom: 40px;
  background-color: #f5f5f5;
}

.form-signin {
  width: 100%;
  max-width: 330px;
  padding: 15px;
  margin: auto;
}
.form-signin .checkbox {
  font-weight: 400;
}
.form-signin .form-control {
  position: relative;
  box-sizing: border-box;
  height: auto;
  padding: 10px;
  font-size: 16px;
}
.form-signin .form-control:focus {
  z-index: 2;
}
.form-signin input[type="email"] {
  margin-bottom: -1px;
  border-bottom-right-radius: 0;
  border-bottom-left-radius: 0;
}
.form-signin input[type="password"] {
  margin-bottom: 10px;
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}
frontend/packs/applications.js
import Vue from 'vue'
import BootstrapVue from 'bootstrap-vue'

Vue.use(BootstrapVue);

import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
import '../css/login.css'
templates/login.html
{% extends 'application.html' %}

{% block title %}Login{% endblock %}
{% block content %}
<form method="post" class="form-signin">
  <h1 class="h3 mb-3 font-weight-normal"">ログイン画面</h1>
  {% csrf_token %}
  {{ form.as_p }}
  <button class="btn btn-lg btn-primary btn-block" type="submit">ログイン</button>
</form>
{% endblock %}

以上の設定でログイン画面を実装できました。

スクリーンショット 2018-12-01 17.36.39.png

まとめ

ログイン画面の画面がようやくリッチ(?)になりました。ただし、よく見てもらうと、form.as_pで展開しているフォーム部分にclass指定をしていないため、後々loginのviewをカスタマイズする必要があります。
ですが、そろそろ中身の実装に行きたいので、今回はここまで。

シリーズ

Part2Part3Part4

参考文献

https://qiita.com/ynakahira/items/bd8580397fc2615b9dd8

8
15
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
8
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?