6
8

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

DjangoでVue.js(webpack)を扱うための備忘録

Posted at

前書き

この記事はPythonをバックエンド(Djangoをフレームワークとして使用)、Node.jsでWebpackを用いてVue.jsをフロントエンドとして使用できるようにするための備忘録記事です。

node.jsの知識が浅いので、使い方を間違っていることもあります。ご了承ください。

また、この記事はpipenvyarnを使用しています。導入していない場合は導入してからこの記事を読むことをお勧めします。

パッケージのインストール

Djangoのstartprojectで自動作成されたフォルダを基にします。

Python

pip install django
django-admin startproject django_vuejs
cd django_vuejs
pipenv --python 3
pipenv install django
pipenv install django-webpack-loader==0.7.0

node.js

yarn init -yp # package.jsonを作る(対話なし)
yarn add --dev @babel/core @babel/preset-env
yarn add --dev babel-loader css-loader sass-loader style-loader vue-loader vue-template-compiler
yarn add --dev webpack webpack-cli
yarn add --dev webpack-bundle-tracker@0.4.3
yarn add vue vuex vue-router
yarn add --dev clean-webpack-plugin # これは任意ですが、これを入れておくとビルドしたjsファイルがかさばらなくなるので導入推奨。

気をつけてほしいのはwebpack-bundle-trackerのバージョン指定です。バージョンが新しすぎてPython側のdjango-webpack-loaderが上手く動作しなかったため、バージョン指定しています1。念の為Python側のdjango-webpack-loaderのバージョンも指定してます。

設定

webpack

webpack.config.js
var path = require("path");
var webpack = require('webpack');
var BundleTracker = require('webpack-bundle-tracker');
var VueLoaderPlugin = require('vue-loader/lib/plugin');
var { CleanWebpackPlugin } = require('clean-webpack-plugin'); // clean-webpack-pluginを導入した場合は追記

module.exports = {
  context: __dirname,
  mode: process.env.NODE_ENV,
  entry: {
    main: './src-front/main.js'
  },

  output: {
    filename: "[name]-[hash].js",
    path: path.resolve('./static/build/')
  },

  plugins: [
    new BundleTracker({
      path: '.',
      filename: 'webpack-stats.json'
    }),
    // clean-webpack-pluginを導入した場合は追記(ここから)
    new CleanWebpackPlugin({
      verbose: true
    }),
    // (ここまで)
    new VueLoaderPlugin()
  ],

  module: {
    rules: [
      {
        test: /\.js$/,
        loader: 'babel-loader'
      },
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      },
      {
        test: /\.scss$/,
        use: [
          'style-loader',
          'css-loader',
          'sass-loader'
        ]
      },
      {
        test: /\.css$/,
        use: [
          'vue-style-loader',
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              url: false,
              sourceMap: true
            }
          }
        ]
      }
    ]
  },

  resolve: {
    extensions: ['.js', '.vue'],
    modules: [
      'node_modules'
    ],
    alias: {
      'vue': path.resolve('./node_modules/vue/dist/vue.js')
    }
  }
}

Django

django_vuejs/settings.py
# (省略)
INSTALLED_APPS = [
    # ...
    # 以下の文を追記
    'webpack_loader',
]

# 追記
WEBPACK_LOADER = {
   'DEFAULT': {
       'CACHE': not DEBUG,
       'BUNDLE_DIR_NAME': 'build/',
       'TIMEOUT': None,
       'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.json'),
       'IGNORE': [r'.+\.hot-update.js', r'.+\.map']
   }
}

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
]

package.json

package.json内に以下の内容を追記します。
--progressオプションはwebpackの進捗状況を可視化できるオプションのため、不要であれば付ける必要はありません。

package.json
  "scripts": {
    "dev": "webpack --mode development --progress",
    "build": "webpack --mode production --progress",
    "watch": "webpack --watch -d --progress"
  },

メインページ

これがフロントエンドがベースとなるファイルです。ここにwebpackでビルドしたCSSやjavascriptのリンクが埋め込まれます。

template/index.html
{% load render_bundle from webpack_loader %}
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>django_vuejs</title>
        {% render_bundle 'main' 'css' %}
    </head>
    <body>
        <noscript>
            <p>Your browser is disabled JavaScript. To use this web application, please enable JavaScript.</p>
        </noscript>
        <div id="app"></div>
        {% render_bundle 'main' 'js' %}
    </body>
</head>

Django URL

※今回は1ファイルにまとめていますが、適宜場所を移してください。

django_vuejs
from django.contrib import admin
from django.urls import path
from django.shortcuts import render

def index(request):
    return render(request, "index.html")

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', index, name="index"),
]

フロントエンド

src-front/main.js
import Vue from 'vue'

import App from './App'
import router from './router.js'
import store from './store'

Vue.config.productionTip = false

const app = new Vue({
    el: '#app',
    router,
    store,
    template: "<App/>",
    components: { App }
})
src-front/App.vue
<template>
  <div>
      <p>Hello World!</p>
      <router-view></router-view>
  </div>
</template>

<script>
export default {
    name: 'App'
}
</script>

<style>

</style>

./router.js./storeはVue.jsのコマンドで自動生成されるものともろ一緒なので、申し訳ないのですが割愛します。

gitignore (gitで管理する場合は設定)

.gitignore
# 追記
/static/build/
/webpack-stats.json

ビルド

本番用でビルドする場合はyarn run build
開発用としてビルドする場合はyarn run devまたはyarn run watch(フロントエンド系のソースを集中的に弄る場合は推奨)
のコマンドを実行します。

ビルドが完了したらpython manage.py runserverでDjangoの開発サーバーを起動し、http://localhost:8000/にアクセスすると、表示されるはずです。

参考文献

  1. 動作しない問題はすでにdjango-webpack-loaderIssueで上がっています。これを見るまでわかりませんでした・・・。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?