这个问题有点长,但我需要解释一下背景,请耐心等待。
我正在研究以下列方式构建的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组件都只写一个单词。像这样:
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>
);
}
}
而且:
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捆绑在一起。这是我的配置:
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.html
内fe/public
提供服务,而我的gem处理动态请求。
碰巧的是,尽管所有模块都已正确安装并且所有模块都已正确捆绑,但当我使用rackup
运行我的应用时,我什么也看不到。没有错误,没有问题......没有言语!只是一个空白的浏览器屏幕。
我到底错过了什么?
修改
{
"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
,特别是一个如此小的
答案 0 :(得分:0)
我通过对代码进行一些更改来解决问题。
首先,我编辑了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
文件现在显示为:
<!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开发框架运行的最后一步。现在只需要进一步改善它。