javascript - Node、Webpack-Dev-Server、React 的开发模式 - 嵌套路由没有此类文件或目录

标签 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
  },
};

服务器.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'));

路由.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

主要目标是能够在不使用 hashHistory 的情况下在开发模式下加载“/test”。

回贴文档:https://webpack.js.org/guides/development/

最佳答案

当没有其他路由匹配时,您正在为 dist/index.html 提供服务,其中:

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

但这会在您的文件系统中查找该文件,该文件应该在您的生产构建中工作(当您构建 bundle 然后提供它时)。如果您查看在转到 /test 时遇到的错误,您会发现该文件不存在。

Error: ENOENT: no such file or directory, stat '/path/to/nodeWebpackSupport/dist/index.html'

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

在您的开发 route ,您需要添加以下内容(最初取自 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();
  });
});

关于javascript - Node、Webpack-Dev-Server、React 的开发模式 - 嵌套路由没有此类文件或目录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47259027/

相关文章:

node.js - 在我们的库中,如何告诉 webpack 跳过依赖项?

javascript - 有没有办法防止位于 <head> 中的第三方 JS 代码在不可用的情况下关闭网站?

javascript - 如何在页面上随机放置多个元素?

javascript - 如何将 JSON 数据从 Node js 脚本发送到不同服务器上的 HTML 文件

webpack - 为什么我无法通过传递变量来确定 karma shim 中 require.context 的路径?

使用 Vuejs+Webpack 时的 Symfony 3 项目结构

javascript - 从 "AddEventListener"启动函数?

javascript - 如何使用 jquery/AJAX 加载外部 Css 文件?

json - 即使从 package.json 中删除它,node-gyp 也会尝试建立依赖关系

javascript - 使用nodejs意外 token 在bash脚本for循环中执行java程序