带有 React 的 Webpack:我缺少什么吗?
Webpack with React: is there something I am missing?
这个问题会有点长,但我需要解释上下文,请耐心等待。
我正在开发按以下方式构建的 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,contents、footer 和 reader 是 ReactJS 组件。这个想法是将后端 be 与前端 fe 完全分离,由 webpack 和 Rack 协调,我将在其中使用 fetch
从 tye 后端获取动态数据。
该应用程序在与 Webpack 捆绑后,将由 Rack 运行。 Rack::Static
中间件将处理由 npm run build
构建的静态资产,我创建的 Ruby gem 会将 de frontend 进行的调用重定向到一组 PORO(Plain旧 Ruby 对象)将提供动态数据。如您所见,它是一个小型框架。我试图证明的一个概念。
到了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']
}
}]
}
}
如您所见,我正在 fe/public
创建 bundle.js
。我的 Rack::Static
配置为 fe/public
内的 index.html
服务于所有静态请求,而我的 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
,还特么小
我通过对代码进行一些更改解决了这个问题。
首先,我编辑了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
目录中。之后,我在同一个 public
目录中创建了一个 index.html
文件。指向 fe/src
内的 index.html
会给图像和其他资源的路径带来很多麻烦,现在将把它们放在 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>
执行此操作后,应用程序不再 运行ning。 Webpack 找不到已安装的节点模块。它们在 fe
目录中,然后我用
创建了一个符号链接
$ ln -sf fe/node_modules
然后 webpack 运行 非常好并创建了包。
这是我的主要目标,将前端完全隔离在 fe
目录中,同时能够从这个目录之外 运行 这个应用程序,我可以 运行 使用单个命令和单个进程的完整应用程序(后端和前端)。这将使 Heroku 和其他类似服务的部署更加容易。
感谢所有花时间帮助我的人。这是我的 Web 开发框架 运行ning 的最后一步。现在只是进一步改进它的问题。
这个问题会有点长,但我需要解释上下文,请耐心等待。
我正在开发按以下方式构建的 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,contents、footer 和 reader 是 ReactJS 组件。这个想法是将后端 be 与前端 fe 完全分离,由 webpack 和 Rack 协调,我将在其中使用 fetch
从 tye 后端获取动态数据。
该应用程序在与 Webpack 捆绑后,将由 Rack 运行。 Rack::Static
中间件将处理由 npm run build
构建的静态资产,我创建的 Ruby gem 会将 de frontend 进行的调用重定向到一组 PORO(Plain旧 Ruby 对象)将提供动态数据。如您所见,它是一个小型框架。我试图证明的一个概念。
到了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']
}
}]
}
}
如您所见,我正在 fe/public
创建 bundle.js
。我的 Rack::Static
配置为 fe/public
内的 index.html
服务于所有静态请求,而我的 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
,还特么小
我通过对代码进行一些更改解决了这个问题。
首先,我编辑了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
目录中。之后,我在同一个 public
目录中创建了一个 index.html
文件。指向 fe/src
内的 index.html
会给图像和其他资源的路径带来很多麻烦,现在将把它们放在 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>
执行此操作后,应用程序不再 运行ning。 Webpack 找不到已安装的节点模块。它们在 fe
目录中,然后我用
$ ln -sf fe/node_modules
然后 webpack 运行 非常好并创建了包。
这是我的主要目标,将前端完全隔离在 fe
目录中,同时能够从这个目录之外 运行 这个应用程序,我可以 运行 使用单个命令和单个进程的完整应用程序(后端和前端)。这将使 Heroku 和其他类似服务的部署更加容易。
感谢所有花时间帮助我的人。这是我的 Web 开发框架 运行ning 的最后一步。现在只是进一步改进它的问题。