节点的开发模式,Webpack-Dev-Server,React - 没有嵌套路由的此类文件或目录

时间:2017-11-13 07:25:03

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

我正在尝试使用Node和Webpack-Dev-Server让我的应用程序在开发模式下工作。当我提供'/'时,我完全恢复了我想要的东西。但是,当我'/ test'时,我得到'没有这样的文件或目录'。我在Webpack的网站和React Router Training上阅读了很多文档,似乎没有人真正回答这个问题。我希望能够使用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;

App组件呈现一个div表示它已加载且与Home组件相同。如果你想在Github上看到整个东西,这里有一个链接:

https://github.com/jlag34/nodeWebpackSupport

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

Wepback docs:https://webpack.js.org/guides/development/

2 个答案:

答案 0 :(得分:6)

当没有其他路线匹配时,您正在服务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'

会发生这种情况,因为您使用index.html生成html-webpack-plugin并且webpack-dev-middleware将其保留在内存中并且不会将其写入文件系统。在开发中,您无法提供该文件,而是需要从内存中提供该文件。您可以使用compiler.outputFileSystem.readFile访问webpack内存中的文件。

在您的开发路线中,您需要添加以下内容(最初取自comment of html-webpack-plugin #145):

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();
  });
});

答案 1 :(得分:0)

  

主要目标是能够加载&#39; / test&#39;在开发模式下,不使用hashHistory。

React-router输入staticbrowserhash,因此可以通过生成jsx函数轻松选择一个,由控制流或{{1预定义常量。当返回具有应用路由的webpack时,此类技术用于SSR(服务器端呈现),具体取决于环境。

jsx