๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿ’ก์›น ํ”„๋กœ์ ํŠธ/(ํ’€์Šคํƒ) MOVIEW ์‚ฌ์ดํŠธ

webpack์œผ๋กœ Django - Vue.js ์—ฐ๋™ํ•˜๊ธฐ

1. Django ํ”„๋กœ์ ํŠธ

๊ฐ€์ƒํ™˜๊ฒฝ์„ ์ƒ์„ฑํ•˜๊ณ  ์‹คํ–‰ํ•œ๋‹ค.

$ mkdir semoview
$ python -m venv venv
$ .\venv\Scripts\activate
# ๊ฐ€์ƒํ™˜๊ฒฝ ์ข…๋ฃŒ : deactivate

๊ฐ€์ƒํ™˜๊ฒฝ ์•ˆ์— ์žฅ๊ณ ๋ฅผ ์„ค์น˜ํ•œ๋‹ค.

$ pip install django

์žฅ๊ณ  ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ์ตœ์ƒ์œ„ ํ”„๋กœ์ ํŠธ๋ช…์„ django-vue๋กœ ๋ณ€๊ฒฝํ•ด์ค€๋‹ค. 

$ django-admin startproject config
$ move config django-vue

manage.pyํŒŒ์ผ์ด ์กด์žฌํ•˜๋Š” ๋””๋ ‰ํ† ๋ฆฌ์—์„œ ์•ฑ(api)์„ ์ƒ์„ฑํ•ด์ค€๋‹ค.

$ cd django-vue
$ python manage.py startapp api

settings.pyํŒŒ์ผ์—์„œ ์„ค์ •์„ ๋ณ€๊ฒฝํ•ด์ค€๋‹ค.

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    
    'api', #์ถ”๊ฐ€
]

#TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Seoul' #๋ณ€๊ฒฝ

migrationํ›„์— ์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•ด๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์‹œ์ž‘ํŽ˜์ด์ง€ ๋œจ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

$ python manage.py migrate
$ python manage.py runserver

 

 

2. Vue.js ํ”„๋กœ์ ํŠธ

ํ˜„์žฌ ์žฅ๊ณ ํ”„๋กœ์ ํŠธ์— vue ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ด์ค€๋‹ค.

$ cd django-vue
$ vue create .
$ npm run serve

vue ํ”„๋กœ์ ํŠธ ์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•œ ํ›„ ์ ‘์†ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์•„๋ž˜์™€ ๊ฐ™์€ ํ™”๋ฉด์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

3. webpack์„ ์ด์šฉํ•˜์—ฌ Vue.js์™€ Django ์—ฐ๊ฒฐํ•˜๊ธฐ

django-webpack-loader(owais/django-webpack-loader)๋ฅผ ์„ค์น˜ํ•ด์ค€๋‹ค.

$ cd django-vue
$ pip install django-webpack-loader

settings.py์— webpack loader์™€ ๊ด€๋ จ๋œ ์„ค์ •๊ณผ vue ํ”„๋กœ์ ํŠธ ๊ฒฝ๋กœ๋ฅผ ์„ค์ •ํ•ด์ค€๋‹ค.

INSTALLED_APPS = [
    'webpack_loader',  #์ถ”๊ฐ€
]

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'public')], #๋ณ€๊ฒฝ
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

#์ถ”๊ฐ€
WEBPACK_LOADER = {
    'DEFAULT': {
        'CACHE': DEBUG,
        'BUNDLE_DIR_NAME': '/bundles/',  # must end with slash
        'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.json'),
    }
}

urls.pyํŒŒ์ผ์— ์žฅ๊ณ ์•ฑ url ์„ค์ •์„ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.

from django.contrib import admin
from django.urls import path
from . import views #์ถ”๊ฐ€

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.HomeView.as_view(), name='home'), #์ถ”๊ฐ€
]

configํด๋” ํ•˜์œ„์— views.py์„ ์ƒˆ๋กœ ์ƒ์„ฑํ•˜๊ณ  HomeView ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.

from django.shortcuts import render
from django.views.generic import TemplateView

# Create your views here.
class HomeView(TemplateView):
  template_name = 'index.html'

public/index.html์— {% load render_bundle from webpack_loader %}์™€ {% render_bundle 'index' %}๋ฅผ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.

{% load render_bundle from webpack_loader %}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title>django-vue</title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but django-vue doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    {% render_bundle 'index' %}
    <!-- built files will be auto injected -->
  </body>
</html>

 

4. webpack-bundle-tracker

webpack-bundle-tracker(owais/webpack-bundle-tracker)๋ฅผ ์„ค์น˜ํ•ด์ค€๋‹ค.

$ cd django-vue
$ npm install --save-dev webpack-bundle-tracker

์ตœ์ƒ์œ„ํด๋”(django-vue/) ํ•˜์œ„์— vue.config.jsํŒŒ์ผ์„ ์ƒ์„ฑํ•œ๋‹ค.

const BundleTracker = require('webpack-bundle-tracker');

module.exports = {
  publicPath: 'http://127.0.0.1:8080/',
  outputDir: './dist/',

  chainWebpack: config => {
    config.optimization.splitChunks(false)

    config.plugin('BundleTracker').use(BundleTracker, [{filename: './webpack-stats.json'}])

    config.devServer.public('http://0.0.0.0:8080').host('0.0.0.0').port(8080).https(false).headers({"Access-Control-Allow-Origin":["\*"]})
  },

  pages: {
    index: 'src/main.js'
  }
}

 

5. ์„œ๋ฒ„ ์‹คํ–‰

Django ํ”„๋กœ์ ํŠธ์™€ Vue ํ”„๋กœ์ ํŠธ์˜ ์„œ๋ฒ„๋ฅผ ๊ฐ๊ฐ ์‹คํ–‰ํ•œ ํ›„ 'http://127.0.0.1:8080/'(์žฅ๊ณ  ๊ธฐ๋ณธ ์„œ๋ฒ„) ์— ์ ‘์†ํ•˜๋ฉด Vueํ”„๋กœ์ ํŠธ ์‹คํ–‰ ์ฒซํ™”๋ฉด์ด ๋œจ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

$ npm run serve
$ python manage.py runserver