Django mit vue.js Frontend - Pfad für statische Dateien
Ich versuche, eine Django-App mit einem Vue-Frontend bereitzustellen und benötige Hilfe beim Konfigurieren der statischen Dateien.
Die Frage TLDR:
Wie bringe ich Django dazu, diesen erstellten Pfad als Versuch zu erkennen, eine statische Datei zu erreichen, oder wie ändere ich alternativ den Injektionspfad nach dem Erstellen auf der Vue-Seite, um ihn an die aktuellen Einstellungen für statische Django-Dateien anzupassen?
Django stellt die erstellte index.html von vue bereit, kann jedoch die statischen Dateien (Skripte / CSS) nicht finden, die vom Erstellungsprozess automatisch injiziert werden, da der Pfad "absolut" ist. Ich habe die Datei vue.config.js so geändert, dass die Skripte nicht automatisch injiziert werden (da sie {% static %}während des Builds benötigt werden, und die Vorlage index.html, um sie entsprechend hinzuzufügen.
Meine Verzeichnisstruktur ist wie folgt:
- 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
Der Build wird aus dem Frontend-Verzeichnis mit --no-clean ausgeführt, um meinen Django-Vorlagenordner beim Build nicht zu löschen.
Hier ist meine Problemumgehung zum Hinzufügen von {% static %}Tags zur erstellten index.html. Mir ist klar, dass ich gegen die Konvention verstoße. Vue hat festgestellt, dass AssetsDir ein Unterverzeichnis von outputDir ist, und ich bin nicht dagegen, der settings.py ein weiteres statisches Dateiverzeichnis hinzuzufügen, das der Konvention entspricht (obwohl mein Problem immer noch dasselbe ist).
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>
Die erstellte 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>
Meine Konfiguration von django settings.py für statische Dateien:
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"
...
Die Art und Weise, wie meine statischen Dateisucher über Django konfiguriert werden, erfordert Änderungen an den erstellten Skript- / CSS-Pfaden in app / templates / app / index.html.
Anstatt von <script src="{% static '/app/../../../assets/js/chunk-vendors.6a3b11f1.js' %}">
Der Pfad muss derzeit sein <script src="{% static 'js/chunk-vendors.6a3b11f1.js' %}">
Ändern des assetsDir Weg in vue.config.js von mit Vermögenswerten die Vue Konvention entsprechen , ein Unterverzeichnis von outputDir führt zu einem ähnlichen Problem sein , in dem der Pfad 'app/assets/js/...'nicht'js/...'
Antworten
Ich habe beschlossen, den Pfad, der während des Vue-Builds in die Vorlage geladen wird, anzupassen, indem ich die Datei public / index.html sowie die Optionen vue.config.js geändert habe. Ich habe eine const asset_dir = '/asset/dirin vue.config.js deklariert und diese dann als zusätzliche Option zum HtmlWebpackPlugin hinzugefügt, um sie in die Vorlage zu ziehen. Zuletzt habe ich den Pfad für die statischen Dateien nach der Länge des unnötigen Teils des Pfads unterteilt.
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>