Python/Django

[Django][React] Django와 React 설정하기

S0PH1A 2019. 8. 1. 00:28
반응형

[Django][React] Django와 React 설정하기

이 글은 http://v1k45.com/blog/modern-django-part-1-setting-up-django-and-react/ 를 번역한 글입니다.

- 사용 언어

  • Django 1.11.22
  • Python 2.7
  • ReactJS ^16.8.6

1. Virtualenv 및 Django 설치

  1. backend폴더 생성 후 virtualenv 설치 및 활성화
    $ mkdir backend
    $ cd backend
    $ virtualenv venv
    $ source venv/bin/activate
  2. virtualenv에서 django 설치 한 후 backend프로젝트 생성
    (venv) $ pip install django
    (venv) $ django-admin startproject Dreact
  3. 프로젝트 폴더로 이동 후 마이그레이션
    (venv) $ cd Dreact
    (venv) $ ./manage.py migrate

2. ReactJS , Webpack 설치

  1. create-react-app 설치
    $ sudo npm install -g create-react-app
    또는
    $ yarn add create-react-app
  2. frontend이름을 갖는 React 프로젝트 생성 한 후 eject실행.
    $ create-react-app frontend
    $ cd frontend
    $ npm run eject  또는  yarn eject
  3. run하여 React가 정상적으로 실행되는지 확인.
    $ npm run start
    또는
    $ yarn run start
  • 만약 Cannot find module '@babel/plugin-transform-react-jsx'~ 에러가 발생할 경우 아래 명령어를 실행해서 node_modules삭제 후 재 설치
    $ rm -rf node_modules && rm yarn.lock && yarn
  • 현재까지 전체 폴더 구조
    ├── ProjectFolder
    │ ├── backend
    │ │ ├── venv
    │ │ ├── Dreact
    │ ├── frontend
    │ │ ├── config
    │ │ ├── src

3. Django와 ReactJS 연동

  1. Django webpack_loader설치

    $ pip install django-webpack-loader
  2. Django 프로젝트 폴더 내 settings.py파일 수정.

  • INSTALLED_APPS에 webpack_loader추가
  • WEBPACK_LOADER추가
  • TEMPLATES에 DIRS수정
  • STATICFILES_DIRS추가
    INSTALLED_APPS = [
      # ...
      'webpack_loader',
    ]
    WEBPACK_LOADER = {
      'DEFAULT': {
              'BUNDLE_DIR_NAME': 'bundles/',
              'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.dev.json'),
          }
    }
    TEMPLATES = [
      {
          # ... 
          'DIRS': [os.path.join(BASE_DIR, "templates"), ],
          # ... 
      },
    ]
    STATICFILES_DIRS = (
      os.path.join(BASE_DIR, 'assets'),
    )
  1. 테스트를 위한 index.html템플릿 파일 추가
  • Dreact(프로젝트폴더)/templates/index.html
    {% load render_bundle from webpack_loader %}
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="UTF-8" />
      <meta name="viewport" content="width=device-width" />
      <title>Dreact</title>
    </head>
    <body>
      <div id="root">
      </div>
      {% render_bundle 'main' %}
    </body>
    </html>
  1. urls.py파일 수정
  • 방금 만든 index.html파일 접속을 위한 URL생성
  • Dreact(프로젝트폴더)/Dreact/urls.py
    from django.conf.urls import url
    from django.contrib import admin
    from django.views.generic import TemplateView
    urlpatterns = [
      url(r'^admin/', admin.site.urls),
      url(r'^', TemplateView.as_view(template_name="index.html")),
    ]
  1. webpack-builder-tracker 설치
    $ npm install webpack-bundle-tracker --save-dev
  2. react 프로젝트내 config/paths.js파일 수정
  • frontend/config/paths.js
  • 하단에 statsRoot추가
    module.exports = {
    // ...
    statsRoot: resolveApp('../backend/Dreact'),
    };
  1. webpack.config.js파일 수정
  • frontend/config/webpack.config.js
  • publicPath와 publicUrl 값 변경
    const publicPath = isEnvProduction
      ? "/static/bundles/"
      : 'http://localhost:3000/';
    const publicUrl = 'http://localhost:3000/';
  • webpack-bundle-tracker 모듈 추가
  • module.exports의 entry와 plugins에 추가
  • output의 filename과 chunkFilename에 static/ 제거
  • moule.rules.oneOf의 options.name에 static/ 제거
    const BundleTracker = require('webpack-bundle-tracker');
    module.exports = {
      entry: [
        // ...
        require.resolve('webpack-dev-server/client') + '?http://localhost:3000',
        require.resolve('webpack/hot/dev-server'),
      ],
      plugins: [
        // ...
        new BundleTracker({path: paths.statsRoot, filename: 'webpack-stats.dev.json'}),
      ],
        output: [
        // ..
        filename: isEnvProduction
          ? 'js/[name].[contenthash:8].js'
          : isEnvDevelopment && 'js/bundle.js',
        chunkFilename: isEnvProduction
          ? 'js/[name].[contenthash:8].chunk.js'
          : isEnvDevelopment && 'js/[name].chunk.js',
      module: [
        rules: [
          {
            oneOf: [
                // ...
              {
                test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
                loader: require.resolve('url-loader'),
                options: {
                  limit: 10000,
                  name: 'media/[name].[hash:8].[ext]',
                },
              },
              //  ...
              {
                loader: require.resolve('file-loader'),
                // Exclude `js` files to keep "css" loader working as it injects
                // its runtime that would otherwise be processed through "file" loader.
                // Also exclude `html` and `json` extensions so they get processed
                // by webpacks internal loaders.
                exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
                options: {
                  name: 'media/[name].[hash:8].[ext]',
                },
              },
            ]
          }
        ]
      ]
    }
  1. webpackDevServer.config.js파일을 열어서 수정
  • frontend/config/webpackDevServer.config.js
  • module.exports의 host요소와 동등한 위치에 추가
    headers: {
    'Access-Control-Allow-Origin': '*'
    },

1) development(dev) 모드로 React 실행

  1. webpack.config.js파일 수정
  • frontend/config/webpack.config.js
  • plugins부분에 BundleTracker 추가
    plugins: [
        // ...
        new BundleTracker({
            path: paths.statsRoot,
            filename: "webpack-stats.dev.json"
        })    
    ]
  1. reactjs 실행 후 django 실행
    # frontend 폴더에서 reactjs 실행
    $ yarn start
    # backend 폴더에서 django 실행
    $ python manage.py runserver

2) Production(prod) 모드로 실행

  1. Django의 settings.py와 동일한 위치에 production_settings.py 파일 생성
  • 프로젝트 루트에 있는 assets폴더 내 static파일들을 사용한다.
    from .settings import *
    STATICFILES_DIRS = [
      os.path.join(BASE_DIR, "assets"),
    ]
    WEBPACK_LOADER = {
      'DEFAULT': {
              'BUNDLE_DIR_NAME': 'bundles/',
              'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.prod.json'),
          }
    }
  1. 프로젝트 루트에 assets/bundle폴더 생성
    $ mkdir -p assets/bundles
  2. webpack.config.js파일 수정
  • frontend/config/webpack.config.js
  • plugins부분에 BundleTracker 추가
    plugins: [
        // ...
        new BundleTracker({
            path: paths.statsRoot,
            filename: "webpack-stats.prod.json"
        })    
    ]
  1. reactjs 빌드 후 django 실행
    # frontend 폴더에서 reactjs 빌드
    $ yarn build
    # backend 폴더에서 django 실행
    $ python manage.py runserver --settings=dreact.production_settings
  • 전체 폴더 구조
    ├── ProjectFolder
    │ ├── backend
    │ │ ├── venv
    │ │ ├── Dreact
    │ │ │ ├── assets
    │ │ │ │ ├── bundles
    │ │ │ ├── templates
    │ │ │ ├── Dreact
    │ │ │ │ ├── settings.py
    │ │ │ │ ├── production_settings.py
    │ │ │ ├── webpack-stats.dev.json
    │ │ │ ├── webpack-stats.prod.json
    │ ├── frontend
    │ │ ├── config
    │ │ ├── src

[참고] http://v1k45.com/blog/modern-django-part-1-setting-up-django-and-react/

반응형