带有 vue.js 前端的 Django - 静态文件路径
Django with vue.js frontend - Static Files Path
我正在尝试使用 vue 前端提供 django 应用程序,需要一些配置静态文件的帮助。
问题 TLDR:
如何让 Django 将此构建路径识别为尝试访问静态文件,或者如何修改 Vue 端的 post-build 注入路径以匹配当前 Django静态文件设置?
Django 为 vue 构建的 index.html 提供服务,但是由于路径是“绝对”,它无法找到从构建过程中自动注入的静态文件 (scripts/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 的子目录,我不反对向 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>
My 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.
内的内置 script/css 路径
代替<script src="{% static '/app/../../../assets/js/chunk-vendors.6a3b11f1.js' %}">
路径目前需要<script src="{% static 'js/chunk-vendors.6a3b11f1.js' %}">
更改 vue.config.js 中的 assetsDir 路径以匹配将资产作为 outputDir 的子目录的 Vue 约定会导致类似的问题,其中路径是 'app/assets/js/...'
而不是 'js/...'
我决定通过修改 public/index.html 文件以及 vue.config.js 选项来调整在 Vue 构建期间加载到模板中的路径。我在 vue.config.js 中声明了一个 const asset_dir = '/asset/dir
,然后将其作为额外选项添加到 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>
我正在尝试使用 vue 前端提供 django 应用程序,需要一些配置静态文件的帮助。
问题 TLDR:
如何让 Django 将此构建路径识别为尝试访问静态文件,或者如何修改 Vue 端的 post-build 注入路径以匹配当前 Django静态文件设置?
Django 为 vue 构建的 index.html 提供服务,但是由于路径是“绝对”,它无法找到从构建过程中自动注入的静态文件 (scripts/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 的子目录,我不反对向 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>
My 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.
内的内置 script/css 路径代替<script src="{% static '/app/../../../assets/js/chunk-vendors.6a3b11f1.js' %}">
路径目前需要<script src="{% static 'js/chunk-vendors.6a3b11f1.js' %}">
更改 vue.config.js 中的 assetsDir 路径以匹配将资产作为 outputDir 的子目录的 Vue 约定会导致类似的问题,其中路径是 'app/assets/js/...'
而不是 'js/...'
我决定通过修改 public/index.html 文件以及 vue.config.js 选项来调整在 Vue 构建期间加载到模板中的路径。我在 vue.config.js 中声明了一个 const asset_dir = '/asset/dir
,然后将其作为额外选项添加到 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>