我的想法是使用 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
。我已经建立了它
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] WEBrick INFO 1.3.1
[2017-03-15 21:28:23] 信息 ruby 2.3.3 (2016-11-21) [x86_64-linux]
[2017-03-15 21:28:23] 信息 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 请求重定向到poros(Plain Old Ruby Objects),它们是API部分。
这个概念很简单。但我就是不明白为什么这个特定的资源,svg 标志,没有加载。
这完全是由错误的 mime 类型引起的。
在我写的问题中可以清楚地看到:
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”...
这使浏览器忽略收到的文件,因此无法正确显示。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句