vue.js 프론트 엔드가있는 Django-정적 파일 경로

Aug 19 2020

vue 프런트 엔드로 django 앱을 제공하려고 시도 중이며 정적 파일을 구성하는 데 도움이 필요합니다.

질문 TLDR :

Django가이 빌드 된 경로를 정적 파일에 도달하려는 시도로 인식하도록하려면 어떻게해야합니까? 아니면 현재 Django 정적 파일 설정과 일치하도록 Vue 측에서 빌드 후 주입 경로를 어떻게 수정합니까?

Django는 vue에서 빌드 된 index.html을 제공하지만 경로가 "절대"이기 때문에 빌드 프로세스에서 자동 삽입 된 정적 파일 (스크립트 / css)을 찾을 수 없습니다. 스크립트를 자동 주입하지 않도록 vue.config.js를 수정했습니다 ( {% static %}빌드 중에 필요하므로 적절하게 추가하려면 index.html 템플릿 이 필요하기 때문입니다) .

내 디렉토리 구조는 다음과 같습니다.

- Root
  - app
  - migrations
  - templates
    - app (outputDir)
      - index.html (Built from vue)
      - base.html
      - templateFolder1
      - templateFolder2
  - various .py files
  - assets (assetsDir)
    - css
      - static files
    - js
      - static files
  - frontend
    - public
      - index.html (Template for build for vue)
    - src
    - assets
    - components
    - App.vue
    - main.js

빌드는 프론트 엔드 디렉토리에서 실행되며 --no-clean을 사용하여 빌드시 내 django 템플릿 폴더를 삭제하지 않습니다.

{% static %}빌드 된 index.html에 태그를 추가하는 방법은 다음과 같습니다 . 나는 assetDir이 outputDir의 하위 디렉토리라는 규칙을 위반하고 있음을 알고 있으며, 규칙과 일치하도록 settings.py에 다른 정적 파일 디렉토리를 추가하는 것에 반대하지 않습니다 (내 문제는 여전히 동일하지만).

vue.config.js

publicPath: isProd ? '/app/' : '/',
outputDir: __dirname + '/../app/templates/app',
assetsDir: "../../../assets",
indexPath: './index.html',
configureWebpack: {
        ...
        plugins: [
            new HtmlWebpackPlugin({
                template: __dirname + '/public/index.html',
                favicon: __dirname + '/../assets/img/favicon/favicon.ico',
                inject: false,
                minify: false
            })
        ],
    },

public / index.html

{% load static %}
<!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">
    <title>MAPP Remote</title>
      <link rel="shortcut icon" href="{% static '<%= htmlWebpackPlugin.files.favicon %>' %}">
      <% for (key in htmlWebpackPlugin.files.css) { %> <link rel="stylesheet" href="{% static '<%= htmlWebpackPlugin.files.css[key] %>' %}"> <% } %>
  </head>
    <body>
    ...
    <div id="app"></div>

    <!-- built files will be auto injected -->
  <% for (key in htmlWebpackPlugin.files.js) { %> <script type="text/javascript" src="{% static '<%= htmlWebpackPlugin.files.js[key] %>' %}"></script> <% } %>
  </body>
</html>

빌드 된 index.html :

app / templates / app / index.html

{% load static %}
<!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">
    <title>MAPP Remote</title>
      <link rel="shortcut icon" href="{% static '/app/favicon.ico' %}">
       <link rel="stylesheet" href="{% static '/app/../../../assets/css/chunk-vendors.0ba3e87d.css' %}">  <link rel="stylesheet" href="{% static '/app/../../../assets/css/app.fb012fc8.css' %}"> 
  </head>
  <body>
    ...
    <div id="app"></div>

    <!-- built files will be auto injected -->
   <script type="text/javascript" src="{% static '/app/../../../assets/js/chunk-vendors.6a3b11f1.js' %}"></script>  <script type="text/javascript" src="{% static '/app/../../../assets/js/app.45295baa.js' %}"></script> 
  </body>
</html>

정적 파일에 대한 내 django settings.py 구성 :

Settings.py

...
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_URL = "/static/"
STATICFILES_DIRS = [os.path.join(BASE_DIR, "assets")]
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")
STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"
...

내 정적 파일 파인더가 Django를 통해 구성되는 방식은 app / templates / app / index.html 내부의 빌드 된 스크립트 / css 경로를 수정해야합니다.

대신에 <script src="{% static '/app/../../../assets/js/chunk-vendors.6a3b11f1.js' %}">

현재 경로는 <script src="{% static 'js/chunk-vendors.6a3b11f1.js' %}">

vue.config.js에 assetsDir 경로를 변경하면 자산 경로가있는 유사한 문제에 outputDir 결과의 하위 디렉토리를 할 수있는의 뷰 규칙에 맞게 'app/assets/js/...'보다는를'js/...'

답변

1 plum0 Aug 19 2020 at 03:16

vue.config.js 옵션뿐만 아니라 public / index.html 파일을 수정하여 Vue 빌드 중에 템플릿에로드되는 경로를 조정하기로 결정했습니다. const asset_dir = '/asset/dirvue.config.js에서를 선언 한 다음 HtmlWebpackPlugin에 추가 옵션으로 추가하여 템플릿으로 가져 왔습니다. 마지막으로 정적 파일의 경로를 불필요한 부분의 길이로 하위 문자열로 지정합니다.

vue.config.js

const asset_dir = "../../../assets"

module.exports = {
    publicPath: isProd ? '/app/' : '/',
    outputDir: __dirname + '/../app/templates/app',
    assetsDir: asset_dir,
    indexPath: './index.html',
    configureWebpack: {
        ...
        plugins: [
            new HtmlWebpackPlugin({
                template: __dirname + '/public/index.html',
                inject: false,
                minify: false,
                assetsDir: asset_dir
            })
        ],
    }
}

public / index.html

{% load static %}
<% if (htmlWebpackPlugin.options['assetsDir'] !== undefined) { %> <% var assetDirLength = htmlWebpackPlugin.options['assetsDir'].length + htmlWebpackPlugin.files.publicPath.length + "/".length%> <% } %>
<!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">
    <title>MAPP Remote</title>
      <link rel="shortcut icon" href="{% static 'img/favicon/favicon.ico' %}">
      <% for (key in htmlWebpackPlugin.files.css) { %> <link rel="stylesheet" href="{% static '<%= htmlWebpackPlugin.files.css[key].substr(assetDirLength) %>' %}"> <% } %>
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
    <!-- Pulled from htmlWebpackPlugin Docs -->
    <!-- https://github.com/jaketrent/html-webpack-template/blob/86f285d5c790a6c15263f5cc50fd666d51f974fd/index.html -->
    <% for (var chunk in htmlWebpackPlugin.files.chunks) { %>
      <script src="{% static '<%= htmlWebpackPlugin.files.chunks[chunk].entry.substr(assetDirLength) %>' %}"></script>
    <% } %>

  </body>
</html>