首页 文章

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

提问于
浏览
1

我试图让我的应用程序在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文档:https://webpack.js.org/guides/development/

2 回答

  • 5

    当没有其他路线匹配时,您正在服务 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-webpack-plugin 生成 index.html 并且 webpack-dev-middleware 将其保留在内存中并且不会使用 compiler.outputFileSystem.readFile 来存储't write it to the file system. In development you cannot serve that file, but instead you need to serve the one from memory. You can access the files in 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();
      });
    });
    
  • 0

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

    React-router 类型为 staticbrowserhash ,因此可以通过生成的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
    

相关问题