Django с интерфейсом vue.js - путь к статическим файлам
Я пытаюсь обслуживать приложение django с интерфейсом vue, и мне нужна помощь в настройке статических файлов.
TL; DR для вопроса:
Как мне заставить Django распознавать этот построенный путь как попытку доступа к статическому файлу или, альтернативно, как мне изменить путь внедрения после сборки на стороне Vue, чтобы он соответствовал текущим настройкам статического файла Django?
Django обслуживает встроенный index.html из vue, однако он не может найти статические файлы (скрипты / 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. Я понимаю, что нарушаю соглашение vue, что assetsDir является подкаталогом outputDir, и я не против добавления еще одного каталога staticfile в 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
})
],
},
общедоступный / 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:
приложение / шаблоны / приложение / 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 требует изменения встроенных путей сценария / css внутри app / templates / app / index.html.
Вместо того <script src="{% static '/app/../../../assets/js/chunk-vendors.6a3b11f1.js' %}">
Путь в настоящее время должен быть <script src="{% static 'js/chunk-vendors.6a3b11f1.js' %}">
Изменение пути assetsDir в vue.config.js для соответствия соглашению Vue о том, что активы должны быть подкаталогом outputDir, приводит к аналогичной проблеме, при которой путь 'app/assets/js/...'
вместо'js/...'
Ответы
Я решил настроить путь, который загружается в шаблон во время сборки Vue, изменив файл public / index.html, а также параметры vue.config.js. Я объявил a const asset_dir = '/asset/dir
в vue.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
})
],
}
}
общедоступный / 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>