使用React的Webpack:我有什么遗漏的东西吗?

时间:2017-05-18 22:47:23

标签: ruby reactjs webpack rubygems rack

这个问题有点长,但我需要解释一下背景,请耐心等待。

我正在研究以下列方式构建的Reacj / Ruby应用程序:

<my_app>
 |
 |_____be/
 |     
 |_____fe/
 |     |
 |     |_____node_module/
 |     |_____public/
 |     |     |_____index.html    
 |     |     |_____index.jsx
 |     |     |_____index.test.js
 |     |     |_____bundle.js
 |     |_____src/
 |           |_____app/
 |           |     |_____app.jsx
 |           |     |_____app.test.js
 |           |     |_____app.css
 |           |_____contents/
 |           |     |_____contents.jsx
 |           |     |_____contents.test.js
 |           |     |_____contents.css
 |           |_____footer/
 |           |     |_____footer.jsx
 |           |     |_____footer.test.js
 |           |     |_____footer.css
 |           |_____header/
 |           |     |_____header.jsx
 |           |     |_____header.teste.js
 |           |     |_____header.css
 |           |_____package.json
 |           |_____index.jsx
 |           |_____index.test.js
 |           |_____index.css
 |_____config.ru
 |_____Gemfile
 |_____Gemfile.lock
 |_____integrations.json
 |_____package.json
 |_____webpack.config.js

它是纯Ruby(没有Rails,没有Sinatra)和ReactJS的混合,其中 app 内容页脚 reader 是ReactJS组件。这个想法完全将后端与前端 fe 完全分开,由webpack和Rack精心策划,我将使用fetch从tye中获取动态数据后端。

该应用程序与Webpack捆绑后,将由Rack运行。 Rack::Static中间件将处理由npm run build构建的静态资产,并且我创建的Ruby gem会将de前端的调用重定向到一组PORO(Plain Old Ruby Objects),这将提供de动态数据。你可能会看到它是一个小框架。我试图证明的一个概念。

说到 fe ,里面一切都很好。当我进入它的直接并且npm test所有测试运行正常时,当我运行npm start时它也运行正常。

为了简化测试,所有ReactJS组件都只写一个单词。像这样:

app.jsx

import React from 'react';
import './app.css';
import Header from '../header/header.jsx';
import Contents from '../contents/contents.jsx';
import Footer from '../footer/footer.jsx';

export default class App extends React.Component {
  render() {
    return (
      <div className="app">
        <Header />
        <Contents />
        <Footer />
      </div>
    );
  }
}

而且:

header.jsx

import React from 'react';
import './header.css';

export default class Header extends React.Component {
  render() {
    return (
      <p>Header</p>
    );
  }
}

这样,当我在 fe 中运行npm start时,我在浏览器中看到的所有内容(http://localhost:3000)都是

Header
Contents
Footer

嗯,一切都很好,直到这一点。但我需要将前端应用程序与Webpack捆绑在一起。这是我的配置:

webpack.config.js

var path = require('path');

module.exports = {
    entry: path.resolve(__dirname, 'fe/src/') + '/index.js',
    output: {
        path: path.resolve(__dirname,'fe/public/'), 
        filename: 'bundle.js'
    },
    devServer: {
        inline: true,
        contentBase: './public',
        port: 3333
    },
    module: {
        loaders: [{
            test: /\.jsx?$/,
            exclude: /node_modules/,
            loader: 'babel-loader',
            query: {
                presets: ['es2015', 'react']
            }
        }]
    }
}

正如您所看到的,我正在bundle.js创建fe/public。我的Rack::Static已配置为向所有静态请求index.htmlfe/public提供服务,而我的gem处理动态请求。

碰巧的是,尽管所有模块都已正确安装并且所有模块都已正确捆绑,但当我使用rackup运行我的应用时,我什么也看不到。没有错误,没有问题......没有言语!只是一个空白的浏览器屏幕。

我到底错过了什么?

修改

的package.json

{
  "name": "emerald_application",
  "title": "Emerald Framework Application",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "bootstrap": "^3.3.7",
    "fb": "^1.1.1",
    "react": "^15.4.2",
    "react-dom": "^15.4.2",
    "react-router": "^4.0.0"
  },
  "devDependencies": {
    "babel-cli": "^6.24.1",
    "babel-core": "^6.24.1",
    "babel-loader": "^7.0.0",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react": "^6.24.1",
    "react-scripts": "0.9.5",
    "webpack": "^2.5.1",
    "webpack-dev-server": "^2.4.5"
  },
  "scripts": {
    "start": "npm run serve | npm run dev",
    "dev": "webpack-dev-server --progress --colors --port 8090"
  }
}

不,我没有使用create-react-app。但这不是一个问题,因为fe部分运行正常,即ReactJS部分运行良好,我对ReactJS应用程序的了解甚至没有create-react-app,特别是一个如此小的

1 个答案:

答案 0 :(得分:0)

我通过对代码进行一些更改来解决问题。

首先,我编辑了webpack.config.js

webpack.config.js

var path = require('path');

module.exports = {
    entry: path.resolve(__dirname, 'fe/src/') + '/index.jsx',
    output: {
        path: path.resolve(__dirname, 'public'), // <<== THIS
        filename: 'bundle.js'
    },
    devServer: {
        inline: true,
        contentBase: './app',
        port: 3333
    },
    module: {
        loaders: [{
            test: /\.jsx?$/,
            exclude: [ "node_modules" ],
            loader: 'babel-loader',
            query: {
                presets: ['es2015', 'react']
            }
        }]
    }
}

正如您所看到的,这将使Webpack将bundle.js文件放在我的应用程序根目录的public目录中。之后,我在同一个index.html目录中创建了一个public文件。指向index.html内的fe/src会对图像和其他资源的路径造成很多麻烦,现在将放在public/resources处,以便更容易在其中引用它们创建的页面。我的index.html文件现在显示为:

的index.html

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <div id="root"></div>
    <script type="text/javascript" src="bundle.js"></script>
  </body>
</html>

执行此操作后,应用程序仍未运行。 Webpack找不到安装的节点模块。它们在fe目录内,然后我用

创建了一个符号链接
$ ln -sf fe/node_modules

然后webpack运行得很好并创建了捆绑包。

这是我的主要目标,将前端完全隔离在fe目录中,并且能够同时从此dir外部运行此应用程序,在那里我可以运行完整的应用程序(后端和前端)单个命令和单个进程。这将使Heroku和其他类似服务的部署更容易。

我感谢所有花时间帮助我的人。这是让我的Web开发框架运行的最后一步。现在只需要进一步改善它。