我的想法是使用Rack加载分为两部分的Web应用程序。这是结构:
my_app
|______api
| |______poros
|
|______fe
| |______build
| |______node_modules
| |______package.json
| |______public
| | |______ index.html
| | ...
| |______README.md
| |______src
| |______index.js
| ...
|______config.ru
fe 部分(代表前端)是使用create-react-app
创建的React应用程序。我用
npm run build
然后它的静态优化版本在my_app/fe/build
目录下。
这是我的my_app/config.ru
:
#\ -w -p 3000
require 'emeraldfw'
use Rack::Reloader, 0
use Rack::ContentLength
run EmeraldFW::Loader.new
这是我的EmeraldFW::Loader
类,它是安装并运行良好的gem的一部分。
module EmeraldFW
class Loader
def call(env)
path_info = (env['PATH_INFO'] == '/') ? '/index.html' : env['PATH_INFO']
extension = path_info.split('/').last.split('.').last
file = File.read("fe/build#{path_info}")
[200,{'Content-Type' => content_type[extension]},[file]]
end
def content_type
{
'html' => 'text/html',
'js' => 'text/javascript',
'css' => 'text/css',
'svg' => 'image/svg+xm',
'ico' => 'image/x-icon',
'map' => 'application/octet-stream'
}
end
end
end
正如您所看到的,这一切都非常简单。我在EmeraldFW::Loader
类中捕获请求并将其path_info
转换一下。如果请求是' /'我把它重写为' /index.html'在做任何事之前。在所有情况下,我都会在fe/build
之前添加,以便从React应用程序的静态构建中加载它。
当我跑步时
rackup config.ru
并在http://localhost:3000
加载应用程序,结果完全正常:
[2017-03-15 21:28:23] INFO WEBrick 1.3.1
[2017-03-15 21:28:23] INFO ruby 2.3.3(2016-11-21)[x86_64-linux]
[2017-03-15 21:28:23] INFO WEBrick :: HTTPServer #start:pid = 11728 port = 3000
:: 1 - - [15 / Mar / 2017:21:28:27 -0300]" GET / HTTP / 1.1" 200 386 0.0088
:: 1 - - [15 / Mar / 2017:21:28:27 -0300]" GET /static/css/main.9a0fe4f1.css HTTP / 1.1" 200 623 0.0105
:: 1 - - [15 / Mar / 2017:21:28:27 -0300]" GET /static/js/main.91328589.js HTTP / 1.1" 200 153643 0.0086
:: 1 - - [15 / Mar / 2017:21:28:28 -0300]" GET /static/media/logo.5d5d9eef.svg HTTP / 1.1" 200 2671 0.0036
:: 1 - - [15 / Mar / 2017:21:28:28 -0300]" GET /static/js/main.91328589.js.map HTTP / 1.1" 200 1705922 0.1079
:: 1 - - [15 / Mar / 2017:21:28:28 -0300]" GET /static/css/main.9a0fe4f1.css.map HTTP / 1.1" 200 105 0.0021
正如您所看到的,使用正确的mime类型正确加载所有资源。但是我的默认React徽标应该在我的应用首页中旋转,并不存在!好像它没有加载。
所有这一切的大局是让这个机架中间件加载应用程序的React前端,同时正确地重定向使用fetch
从前端到<的{api}请求strong> poros (Plain Old Ruby Objects)是API的一部分。
这个概念非常简单。但我无法理解为什么这个特定的资源,即svg徽标,没有加载。
答案 0 :(得分:0)
由于一个拼写错误,所有这都是错误的哑剧类型。
在我的问题中可以清楚地看到我写道:
def content_type
{
'html' => 'text/html',
'js' => 'text/javascript',
'css' => 'text/css',
'svg' => 'image/svg+xm', # <== Here is the error!!!
'ico' => 'image/x-icon',
'map' => 'application/octet-stream'
}
end
当SVG文件的正确mime类型为'image/svg-xml'
时,带有'l'...
这使浏览器忽略收到的文件,因此无法正确显示。