【问题标题】:Use React-Router browserHistory, Webpack 2 historyApiFallback and Node使用 React-Router browserHistory、Webpack 2 historyApiFallback 和 Node
【发布时间】:2017-09-13 12:46:17
【问题描述】:

我正在尝试使用 React、Node、Webpack 2 在本地运行我的 React 应用程序。每当我遇到不是 / 的路由时,我都会收到 404。我的目标是能够运行我的节点服务器,运行 webpack-dev-server,使用 browserHistory 并支持我的 webpack historyApiFallback 工作。

目前的工作方式:

  1. 如果我只运行 webpack-dev-server 并且没有节点服务器,那么 browserHistory 工作正常,没有 404。
  2. 如果我使用 hashHistory 运行节点,它可以正常工作,不会出现 404。

这样就排除了我的路线不起作用。这是一些代码:

server.js

const express = require('express');
const expressGraphQL = require('express-graphql');
const schema = require('./schema');

const app = express();

app.use('/graphql', expressGraphQL({
  schema,
  graphiql: true
}));

const webpackMiddleware = require('webpack-dev-middleware');
const webpack = require('webpack');
const webpackConfig = require('../webpack.config.js');
app.use(webpackMiddleware(webpack(webpackConfig)));

app.listen(process.env.PORT || 5000, () => console.log('Listening'));

webpack.config.js

const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const VENDOR_LIBS = [
  'axios', 'react', 'react-dom', 'react-router', 'react-apollo', 'prop-types'
];

module.exports = {
  entry: {
    bundle: './client/src/index.js',
    vendor: VENDOR_LIBS
  },
  output: {
    path: path.join(__dirname, 'dist'),
    publicPath: '/',
    filename: '[name].[chunkhash].js'
  },
  module: {
    rules: [
      {
        use: 'babel-loader',
        test: /\.js$/,
        exclude: /node_modules/
      },
      {
        test: /\.scss$/,
            use: [{
                loader: "style-loader"
            }, {
                loader: "css-loader"
            }, {
                loader: "sass-loader"
            }]
      },
      {
        test: /\.(jpe?g|png|gif|svg|)$/,
        use: [
          {
            loader: 'url-loader',
            options: {limit: 40000}
          },
          'image-webpack-loader'
        ]
      }
    ]
  },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      names: ['vendor', 'manifest']
    }),
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
    }),
    new HtmlWebpackPlugin({
      template: './client/src/index.html'
    })
  ],
  devServer: {
    historyApiFallback: true
  }
};

routes.js

import React from 'react';
import { Router, Route, IndexRoute, browserHistory } from 'react-router';

import App from './components/App';
import Portal from './components/portal/Portal';

const componentRoutes = {
  component: App,
  path: '/',
  indexRoute: { component: Portal },
  childRoutes: [
    {
      path: 'home',
      getComponent(location, cb) {
        System.import('./components/homepage/Home')
          .then(module => cb(null, module.default));
      }
    }
  ]
};

const Routes = () => {
  return <Router history={ browserHistory } routes={ componentRoutes } />
};

export default Routes;

同样,目标是能够在本地启动我的节点服务器,使用 browserHistory 而不会出现 404。我不想使用 hashHistory,我需要使用我的节点服务器,这样我才能使用 graphql。我也不想恢复到 webpack v1。虽然这里是人们在 v1 中使用它的地方的链接:

historyApiFallback doesn't work in Webpack dev server

【问题讨论】:

标签: node.js reactjs webpack react-router webpack-dev-server


【解决方案1】:

historyApiFallback 选项专门用于webpack-dev-server。如果您正在运行自己的服务器,即使使用webpack-dev-middleware,您也需要将其配置为在发生 404 时发送index.html。因为您使用的是html-webpack-plugin,所以您要发送的index.html 不存在于您的文件系统中,而仅存在于内存中。要使其正常工作,您可以访问 webpack 编译器的输出,如 comment of html-webpack-plugin #145 所示。

server.js

const path = require('path');
const express = require('express');
const expressGraphQL = require('express-graphql');
const schema = require('./schema');

const app = express();

app.use('/graphql', expressGraphQL({
  schema,
  graphiql: true
}));

const webpackMiddleware = require('webpack-dev-middleware');
const webpack = require('webpack');
const webpackConfig = require('../webpack.config.js');
const compiler = webpack(webpackConfig);

app.use(webpackMiddleware(compiler));
// Fallback when no previous route was matched
app.use('*', (req, res, next) => {
  const filename = path.resolve(compiler.outputPath, 'index.html');
  compiler.outputFileSystem.readFile(filename, (err, result) => {
    if (err) {
      return next(err);
    }
    res.set('content-type','text/html');
    res.send(result);
    res.end();
  });
});

app.listen(process.env.PORT || 5000, () => console.log('Listening'));

【讨论】:

  • 知道为什么我会收到DevTools failed to parse SourceMap: http://localhost:5000/shallowEqual.js.map 错误吗?
  • 不抱歉,我什至不确定这是从哪里来的,因为webpack-dev-middleware 应该处理源映射。您可以尝试使用不同的source map,例如devtool: 'inline-source-map'。但是,如果它们来自您的文件系统,您将需要配置 express 来处理它们(作为静态文件),而不是去回退路线。
猜你喜欢
  • 2019-04-22
  • 2015-11-28
  • 2018-09-29
  • 2017-03-24
  • 2018-08-20
  • 1970-01-01
  • 1970-01-01
  • 2019-06-17
  • 2016-06-01
相关资源
最近更新 更多