WebフレームワークでWebpackを使ってみよう〜Django+Webpack+Vue.js編〜
Webpackの第2弾です
前回はLaravelでしたが今度はDjangoでWebpackを使ってみようと思います
作るものは前回同じVue.jsのツリーです
環境
以下の環境で動かしました
- Python@3.6.2
- Django@2.0.2
- Webpack@3.11.0
- Vue@2.5.13
- webpack-bundle-tracker@0.2.1
- css-loader@0.28.10
- style-loader@0.20.2
仮想環境とDjangoのインストール
以下のコマンドで環境とDjangoのインストールを行います
python3 -m venv env source env/bin/activate pip install django pip install django-webpack-loader
プロジェクトを作ります
起動時にワーニングが出てしまうのでmigrateもしておきます
django-admin startproject django_webpack_vue python manage.py migrate
以下のコマンドで http://localhost:8000/ でDjango初期画面が表示されるか確認します
python manage.py runserver
フロントエンド
フロントエンドのインストールを行っていきます
npm init -f npm install --save-dev webpack webpack-bundle-tracker vue npm install --save-dev style-loader css-loader
webpack.config.js
を作ります
JavaScriptのコンパイルやcssのロードの設定になります
var path = require("path") var webpack = require('webpack') var BundleTracker = require('webpack-bundle-tracker') module.exports = { context: __dirname, entry: './public/js/app.js', output: { path: path.resolve('./assets/bundles/'), filename: "[name]-[hash].js", }, plugins: [ new BundleTracker({filename: './webpack-stats.json'}), ], module : { rules : [ { test: /\.css/, use: [ 'style-loader', { loader: 'css-loader', options: { url: false, sourceMap: true, }, }, ], }, ] }, resolve: { alias: { 'vue': path.resolve('./node_modules/vue/dist/vue.js'), } }, }
サンプル画面
サンプル画面を組み込んでいきます
Laravelとあまり変わらないので細かい説明は省きます
public/css/app.css
body { font-family: Menlo, Consolas, monospace; color: #444; } .item { cursor: pointer; } .bold { font-weight: bold; } ul { padding-left: 1em; line-height: 1.5em; list-style-type: dot; }
public/js/app.js
import '../css/app.css'; window.Vue = require('vue'); // demo data var data = { name: 'My Tree', children: [ { name: 'hello' }, { name: 'wat' }, { name: 'child folder', children: [ { name: 'child folder', children: [ { name: 'hello' }, { name: 'wat' } ] }, { name: 'hello' }, { name: 'wat' }, { name: 'child folder', children: [ { name: 'hello' }, { name: 'wat' } ] } ] } ] } // define the item component Vue.component('item', { template: '#item-template', props: { model: Object }, data: function () { return { open: false } }, computed: { isFolder: function () { return this.model.children && this.model.children.length } }, methods: { toggle: function () { if (this.isFolder) { this.open = !this.open } }, changeType: function () { if (!this.isFolder) { Vue.set(this.model, 'children', []) this.addChild() this.open = true } }, addChild: function () { this.model.children.push({ name: 'new stuff' }) } } }) // boot up the demo var demo = new Vue({ el: '#demo', data: { treeData: data } })
templates/index.html
{% load render_bundle from webpack_loader %} <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>django_webpack_vue</title> </head> <body> {% verbatim %} <!-- item template --> <script type="text/x-template" id="item-template"> <li> <div :class="{bold: isFolder}" @click="toggle" @dblclick="changeType"> {{ model.name }} <span v-if="isFolder">[{{ open ? '-' : '+' }}]</span> </div> <ul v-show="open" v-if="isFolder"> <item class="item" v-for="(model, index) in model.children" :key="index" :model="model"> </item> <li class="add" @click="addChild">+</li> </ul> </li> </script> <p>(You can double click on an item to turn it into a folder.)</p> <!-- the demo root element --> <ul id="demo"> <item class="item" :model="treeData"> </item> </ul> {% endverbatim %} {% render_bundle 'main' %} </body> </html>
Vue.jsのバインドとテンプレートエンジンの置き換え方法がかぶってしまっているため {% verbatim %}
{% endverbatim %}
で挟み込んであげる必要があります
また、 {% render_bundle 'main' %}
でwebpackで作られた main.js
を組み込むことができます
続いてDjango側です
django_webpack_vue/views.py
from django.shortcuts import render from django.http.response import HttpResponse def index(request): return render(request, 'index.html')
django_webpack_vue/urls.py
from django.contrib import admin from django.urls import path from django.conf.urls import url from . import views urlpatterns = [ path('admin/', admin.site.urls), url(r'^', views.index), ]
コンパイル
JavaScriptファイルとcssファイルをコンパイルします
./node_modules/.bin/webpack --config webpack.config.js
ローカル開発サーバを起動してアクセスしてみてVue.jsサイトのサンプルと同じ物が表示されていれば完成です
今回作ったソースはGitHubにあげてあります
まとめ
LaravelもDjangoもWebpack用のモジュールが用意されているので簡単に組み込みことができました
ただ、Webpackを導入するメリットがあまり感じられないのはただ組み込んでいるからなんだろうなぁ...
他の言語フレームワークを試し終わったら基礎知識を上げていかないと