【发布时间】:2019-07-18 19:05:19
【问题描述】:
我正在构建一个带有 React 前端的 Django 应用,使用 react-create-app 构建。我无法让网站图标显示在生产环境中。
我正在使用 Django 2.10.0。
当我构建 React 应用程序时,构建输出文件放在 assets/static/ 文件夹中。这包括通过 css 用作背景的图像文件,并且一切正常。这些包含在构建中,因为它们在样式表中被引用。 favicon 是从 index.html 引用的,因此不会被构建过程拾取。
但是我不知道如何让服务器提供网站图标。如果我将它们放在 frontend/public 文件夹中,Django 服务器将找不到它们。
如果我手动将它们复制到 static/ 文件夹中,它们会显示出来,但该文件夹由 Webpack 管理,并且在构建应用程序时会删除内容。
将网站图标复制到项目根目录中不起作用。它们与 index.html 位于同一文件夹中,已提供服务,但 Django 服务器不会提供这些位于同一位置的图像文件。
我能找到的唯一文档涉及 Django 或 create-react-app;我找不到任何解释如何将它们绑定在一起的网站图标。
在settings.py中:
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'assets/static'),
os.path.join(BASE_DIR, 'assets'),
]
在 index.html 中:
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
在浏览器中,这被转换为:
<link rel="shortcut icon" href="/favicon.ico">
这不起作用 - 文件未提供。我不确定为什么这不起作用,因为我已在 settings.py 中将“资产”添加到 STATICFILES_DIRS 并将网站图标复制到“资产”的根目录中。
所有可用的 css 和图片链接都包含静态文件夹,例如:
http://localhost:8000/static/media/private.d7365d01.svg
好像有两个问题:
1) 如何让构建过程将 favicon 和相关文件复制到 assets 文件夹中,以便提供服务
2) 如何让 index.html 在正确的位置查找网站图标
如果我可以自定义 PUBLIC_URL 以指向 static/ 可能会这样做,但这可能会破坏引用它的其他代码位?
我确定我错过了一些简单的东西。如有任何帮助,我将不胜感激!
编辑:我现在已将网站图标显示在本地计算机上运行的构建版本中,但生产服务器未提供该图标。
Base.py
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'assets/static'),
os.path.join(BASE_DIR, 'assets'),
]
index.html
<link rel="shortcut icon" href="%PUBLIC_URL%/static/favicon.ico" />
favicon.ico 位于“assets”文件夹中。在构建我的 React 应用程序并在本地运行开发服务器后,url http://localhost:8000/static/favicon.ico 会显示我的 favicon。但是在将它部署到服务器后,url https://example.com/static/favicon.ico 什么也没找到。我已经检查并且 favicon.ico 文件存在于服务器上的资产文件夹中。 Settings.py 是一样的。我不明白为什么生产服务器没有提供网站图标?
编辑:我已经尝试将它添加到我的 settings.py 中,但它仍然不起作用:
STATIC_ROOT = os.path.join(BASE_DIR, 'assets')
'assets' 是服务器上包含我的构建文件的文件夹的名称。 favicons 和 index.html 一样在 assets 中,React 文件在 assets/static 中。
编辑:这是我的 Nginx 乘客配置文件:
server {
listen 80;
server_name 178.62.85.245;
passenger_python /var/www/myappname/venv36/bin/python3.6;
# Tell Nginx where your app's 'public' directory is
root /var/www/myappname/myappname/myappname;
# Turn on Passenger
passenger_enabled on;
# Tell Nginx the location of the build output files
location /static/ {
autoindex on;
alias /var/www/myappname/myappname/assets/;
}
}
Nginx 找到文件 index.html 和 React 构建的所有文件。不知道为什么在同一个文件夹下找不到favicon!
编辑:感谢 Sune Kjærgård 的帮助,我终于解决了这个问题。通过阅读有关部署的 Django 文档,我认为我需要在 settings.py 中配置所有静态文件位置。然而,这似乎只适用于 Django 开发服务器,即使在使用生产设置运行时也是如此。在生产服务器上,我通过Passenger 使用Nginx 为应用程序提供服务。 Nginx 需要知道我所有的静态文件的位置。并且'root'和'location'都需要正确设置。
这是我的工作代码。网站图标在生产服务器上提供服务,并在单独运行前端时在端口 3000 上进行开发。在端口 8000 上本地测试构建时,我没有为它们提供服务,但我可以忍受,也许以后会找到解决方案。
似乎不需要STATIC_ROOT,我也没有运行buildstatic。
我的 favicon 位于 frontend/public 中,与 index.html 相同的文件夹。 Webpack 构建过程将它们全部复制到 assets 文件夹中。
server {
listen 80;
server_name 178.62.85.245;
passenger_python /var/www/myappname/venv36/bin/python3.6;
# Tell Nginx where your app's 'public' directory is
root /var/www/myappname/myappname/assets;
# Turn on Passenger
passenger_enabled on;
# Tell Nginx the location of the build output files
location /static/ {
autoindex on;
alias /var/www/myappname/myappname/assets/;
}
}
在settings.py中:
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'assets/static'),
os.path.join(BASE_DIR, 'assets'),
]
在 index.html 中:
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
在浏览器中,这被转换为:
<link rel="shortcut icon" href="/favicon.ico">
我可以在浏览器中看到地址为https://example.com/favicon.ico的图标
跳舞快乐!
【问题讨论】:
-
听起来您正在尝试在生产中使用 Django 开发。不要那样做!您应该在 uwsgi 前面使用 nginx 或类似设置。
-
我在生产服务器上的 Nginx 下通过 wsgi 文件使用 Phusion Passenger。你觉得我的代码有什么问题?
-
好的,由于您问题中的本地主机引用,我只是误解了。通常,当您在前面有 nginx 时,您应该将其配置为提供静态文件。你能告诉我们你的nginx配置吗?
-
谢谢!所有的 Django 文档都在谈论在生产中使用 static_files ,这导致我走错了方向。我的 Nginx 配置错误,因为我不明白它是如何工作的。设置根 /var/www/myappname/myappname/assets;因为 Nginx 已经解决了这个问题。如果您将其发布为答案,我会接受。
-
很高兴你知道了。我添加了一个答案:-)
标签: django create-react-app favicon