使用Rack运行React应用程序不起作用

时间:2017-03-16 01:10:38

标签: ruby reactjs svg

我的想法是使用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徽标应该在我的应用首页中旋转,并不存在!好像它没有加载。

enter image description here

所有这一切的大局是让这个机架中间件加载应用程序的React前端,同时正确地重定向使用fetch从前端到<的{api}请求strong> poros (Plain Old Ruby Objects)是API的一部分。

这个概念非常简单。但我无法理解为什么这个特定的资源,即svg徽标,没有加载。

1 个答案:

答案 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'...

这使浏览器忽略收到的文件,因此无法正确显示。