【问题标题】:Webpack with React: is there something I am missing?带有 React 的 Webpack:我缺少什么吗?
【发布时间】:2017-05-18 22:47:22
【问题描述】:

这个问题会有点长,但我需要解释一下上下文,所以请耐心等待。

我正在开发一个结构如下的 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 的混合体,其中 appcontentsfooterreader 是 ReactJS 组件。这个想法是将后端 be 与前端 fe 完全分开,由 webpack 和 Rack 编排,我将使用 fetch 从后端获取动态数据。

与 Webpack 捆绑后的应用程序将由 Rack 运行。 Rack::Static 中间件将处理由 npm run build 构建的静态资产,我创建的一个 Ruby gem 将把 de frontend 的调用重定向到一组 PORO(Plain Old Ruby Objects),它将提供动态数据。如您所见,它是一个小型框架。我试图证明的一个概念。

说到fe,里面的一切都很好。当我输入它的directoty 并执行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 也可以创建它们,特别是这么小的一个。

【问题讨论】:

  • 分享你的 package.json、index.js 和 index.html 可能会有所帮助。还可以尝试在 index.js 的入口点添加控制台日志以查看它是否被命中。另外, npm start 有什么作用?你用过 create-react-app 吗?从您的描述中不清楚 npm start 如何在localhost:3000启动服务器
  • 好的,我会这样做的。
  • 我编辑了这个问题,@skypecakes。
  • 我认为起点是查看是否提供了 index.html。你检查过页面来源吗?浏览器控制台是否有错误?

标签: ruby reactjs webpack rubygems rack


【解决方案1】:

我通过修改代码解决了这个问题。

首先,我编辑了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>

执行此操作后,应用程序仍未运行。 Webpack 找不到安装的节点模块。他们在fe 目录中,然后我刚刚创建了一个符号链接

$ ln -sf fe/node_modules

然后 webpack 运行良好并创建了包。

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

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

【讨论】:

    猜你喜欢
    • 2021-12-26
    • 1970-01-01
    • 2017-03-17
    • 1970-01-01
    • 2013-12-20
    • 2011-07-12
    • 1970-01-01
    • 2012-10-01
    • 1970-01-01
    相关资源
    最近更新 更多