Javascript 节点、Web包开发服务器、React的开发模式-嵌套路由没有此类文件或目录

Javascript 节点、Web包开发服务器、React的开发模式-嵌套路由没有此类文件或目录,javascript,node.js,webpack,react-router,webpack-dev-server,Javascript,Node.js,Webpack,React Router,Webpack Dev Server,我试图让我的应用程序在开发模式下与节点和网页包开发服务器一起工作。当我上菜时,我得到的正是我想要的。但是,当我执行“/test”时,我得到的是“没有这样的文件或目录”。我在Webpack的网站和React路由器培训上读了很多文档,似乎没有一个真正回答这个问题。我希望能够使用browserHistory而不是hashHistory(我仍在使用React Router v3) package.json: { "name": "boilerplate", "version": "1.0.0",

我试图让我的应用程序在开发模式下与节点和网页包开发服务器一起工作。当我上菜时,我得到的正是我想要的。但是,当我执行“/test”时,我得到的是“没有这样的文件或目录”。我在Webpack的网站和React路由器培训上读了很多文档,似乎没有一个真正回答这个问题。我希望能够使用browserHistory而不是hashHistory(我仍在使用React Router v3)

package.json:

{
  "name": "boilerplate",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "clean": "rimraf dist",
    "build": "NODE_ENV=production npm run clean && webpack -p",
    "dev": "nodemon server.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "axios": "^0.15.3",
    "babel-core": "^6.7.2",
    "babel-loader": "^6.2.4",
    "babel-plugin-transform-class-properties": "^6.22.0",
    "babel-preset-env": "^1.1.8",
    "babel-preset-react": "^6.5.0",
    "css-loader": "^0.26.1",
    "express": "^4.14.0",
    "html-webpack-plugin": "^2.26.0",
    "react": "^15.4.1",
    "react-dom": "^15.4.1",
    "react-redux": "^4.4.1",
    "react-router": "^3.2.0",
    "redux": "^3.3.1",
    "redux-promise": "^0.5.3",
    "rimraf": "^2.5.4",
    "style-loader": "^0.13.1",
    "url-loader": "^0.5.7",
    "webpack": "^3.8.1"
  },
  "devDependencies": {
    "nodemon": "^1.11.0",
    "webpack-dev-middleware": "^1.9.0",
    "webpack-dev-server": "^2.2.0-rc.0",
    "webpack-hot-middleware": "^2.20.0"
  }
}
webpack.config.js

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

const VENDOR_LIBS = [
  'axios', 'react', 'redux', 'react-dom', 'react-redux',
  'react-router', 'redux-promise'
];

module.exports = {
  entry: {
    bundle: './client/src/index.js',
    vendor: VENDOR_LIBS
  },
  output: {
    chunkFilename: '[name].[chunkhash].js',
    path: path.join(__dirname, 'dist'),
    publicPath: '/'
  },
  module: {
    rules: [
      {
        use: 'babel-loader',
        test: /\.js$/,
        exclude: /node_modules/
      },
      {
        use: ['style-loader', 'css-loader'],
        test: /\.css$/
      },
      {
        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'
    })
  ],
  devtool: 'inline-source-map',
  devServer: {
    contentBase: '/dist',
    historyApiFallback: true
  },
};
server.js:

const express = require('express');
const path = require('path');
const app = express();


if (process.env.NODE_ENV !== 'production') {
  app.use(express.static(path.join(__dirname, 'dist')));
  const webpack = require('webpack');
  const webpackDevMiddleware = require('webpack-dev-middleware');
  const config = require('./webpack.config.js');
  const compiler = webpack(config);
  app.use(webpackDevMiddleware(compiler, {
    publicPath: config.output.publicPath
  }));
} else {
  app.use(express.static('dist'));
}

app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, 'dist', 'index.html'));
});


app.listen(process.env.PORT || 3050, () => console.log('Listening'));
routes.js:

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

import App from './components/app';
import Home from './components/home';

const componentRoutes = (
  <Route component={App} path='/'>
    <Route component={Home} path='/test' />
  </Route>
);

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

export default Routes;
从“React”导入React;
从“react Router”导入{Router,Route,IndexRoute,browserHistory};
从“./components/App”导入应用程序;
从“./components/Home”导入Home;
常量组件路由=(
);
常数路由=()=>{
返回
};
导出默认路径;
应用程序组件呈现一个单独的div,表示它已加载,并且与主组件相同。如果您想在Github上看到整个内容,请点击以下链接:

主要目标是能够在开发模式下加载“/test”,而不使用hashHistory

Wepback文档:

主要目标是能够在开发模式下加载“/test”,而不使用hashHistory

React router
类型为
static
browser
hash
,因此可以通过生成jsx函数轻松选择,该函数由控制流或
webpack
预定义常量选择。当返回带有应用路由的
jsx
时,这种技术用于SSR(服务器端渲染),具体取决于环境

const RootComponent = () => {/* root component */};
const EntryPoint = process.env.NODE_ENV === 'production'
    ? (props) => (<BrowserRouter><RootComponent {...props} /></BrowserRouter>)
    : (props) => (<HashRouter><RootComponent {...props} /></HashRouter>)
export default EntryPoint 
constrootcomponent=()=>{/*根组件*/};
const EntryPoint=process.env.NODE_env==“生产”
? (道具)=>()
:(道具)=>()
导出默认入口点

您正在提供的
dist/index.html
没有其他路线匹配,包括:

app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, 'dist', 'index.html'));
});
但这会在您的文件系统中查找该文件,该文件应该在您的生产构建中工作(当您构建捆绑包并提供服务时)。如果查看转到
/test
时出现的错误,您将看到此文件不存在

Error: ENOENT: no such file or directory, stat '/path/to/nodeWebpackSupport/dist/index.html'
发生这种情况的原因是,您正在使用
html网页包插件
生成
index.html
,而
webpack-dev-middleware
将其保存在内存中,而不会将其写入文件系统。在开发中,您不能提供该文件,而是需要从内存中提供该文件。您可以使用
编译器.outputFileSystem.readFile
访问网页包内存中的文件

在开发路线中,您需要添加以下内容(最初取自):


我说过我不想使用哈希历史记录,但您的解决方案使用它…@user2465134当然,上面的答案是要配置
react router
,在一般情况下依赖
webpack
模式。它在任何情况下都可以是
BrowserRouter
,但参数不同,例如,如果您的产品外观支持特定的URL路由。另外,
SSR
在其上配置
StaticRouter
也很有用。这确实会消除错误,并在我点击“/test”时显示我的页面,但是,它没有显示正确的组件。如果您在点击“/test”时查看route.js,它应该提供主组件,但您的解决方案应用程序正在显示,您是对的。您使用的是嵌套路由,我认为在react router v3中,您需要在外部路由中显式地呈现
props.children
app.js
)。我早就知道。。哈哈,无论如何,谢谢你,非常感谢你。几个小时前我就因为这个问题而头疼。
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();
  });
});