[javascript] webpack-dev-server가 react-router의 진입 점을 허용하도록 허용하는 방법

React-router와 함께 개발에서 webpack-dev-server를 사용하는 앱을 만들고 있습니다.

webpack-dev-server는 한곳에 공개 진입 점 (예 : “/”)이 있다는 가정하에 구축 된 것으로 보이지만 react-router는 무제한 진입 점을 허용합니다.

webpack-dev-server의 이점, 특히 생산성에 좋은 핫 리로딩 기능을 원하지만 여전히 react-router에 설정된 경로를로드 할 수 있기를 원합니다.

함께 작동하도록 어떻게 구현할 수 있습니까? 이를 허용하는 방식으로 webpack-dev-server 앞에서 익스프레스 서버를 실행할 수 있습니까?



답변

이를 위해 프록시를 설정했습니다.

자산 경로 인 경우를 제외하고 모든 경로에서 index.html을 제공하는 정규 익스프레스 웹 서버가 있습니다. 자산 인 경우 요청은 web-dev-server로 프록시됩니다.

반응 핫 진입 점은 여전히 ​​웹팩 개발 서버를 직접 가리 키므로 핫 리로딩은 여전히 ​​작동합니다.

8081에서 webpack-dev-server를 실행하고 8080에서 프록시를 실행한다고 가정합니다. server.js 파일은 다음과 같습니다.

"use strict";
var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var config = require('./make-webpack-config')('dev');

var express = require('express');
var proxy = require('proxy-middleware');
var url = require('url');

## --------your proxy----------------------
var app = express();
## proxy the request for static assets
app.use('/assets', proxy(url.parse('http://localhost:8081/assets')));

app.get('/*', function(req, res) {
    res.sendFile(__dirname + '/index.html');
});


# -----your-webpack-dev-server------------------
var server = new WebpackDevServer(webpack(config), {
    contentBase: __dirname,
    hot: true,
    quiet: false,
    noInfo: false,
    publicPath: "/assets/",

    stats: { colors: true }
});

## run the two servers
server.listen(8081, "localhost", function() {});
app.listen(8080);

이제 webpack 구성에서 다음과 같이 진입 점을 만드십시오.

 entry: [
     './src/main.js',
     'webpack/hot/dev-server',
     'webpack-dev-server/client?http://localhost:8081'
 ]

hotreload를 위해 8081로 직접 호출하십시오.

또한 절대 URL을 output.publicPath옵션에 전달했는지 확인하십시오 .

 output: {
     publicPath: "http://localhost:8081/assets/",
     // ...
 }


답변

당신은 설정해야합니다 historyApiFallbackWebpackDevServer일이 마찬가지한다. 다음은 작은 예입니다 (목적에 맞게 조정).

var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');

var config = require('./webpack.config');


var port = 4000;
var ip = '0.0.0.0';
new WebpackDevServer(webpack(config), {
    publicPath: config.output.publicPath,
    historyApiFallback: true,
}).listen(port, ip, function (err) {
    if(err) {
        return console.log(err);
    }

    console.log('Listening at ' + ip + ':' + port);
});


답변

아직이 답변을 찾고있는 다른 사람을 위해. 많은 번거 로움없이 이것을 달성하는 간단한 프록시 우회를 모으고 구성은 webpack.config.js에 들어갑니다.

정규식을 사용하여 로컬 콘텐츠를 테스트하는 훨씬 더 우아한 방법이 있다고 확신하지만 이것은 내 요구에 맞습니다.

devServer: {
  proxy: {
    '/**': {  //catch all requests
      target: '/index.html',  //default target
      secure: false,
      bypass: function(req, res, opt){
        //your custom code to check for any exceptions
        //console.log('bypass check', {req: req, res:res, opt: opt});
        if(req.path.indexOf('/img/') !== -1 || req.path.indexOf('/public/') !== -1){
          return '/'
        }

        if (req.headers.accept.indexOf('html') !== -1) {
          return '/index.html';
        }
      }
    }
  }
} 


답변

CLI를 사용하여 webpack-dev-server를 실행하는 경우 devServer 객체를 전달하는 webpack.config.js를 통해 구성 할 수 있습니다.

module.exports = {
  entry: "index.js",
  output: {
    filename: "bundle.js"
  },
  devServer: {
    historyApiFallback: true
  }
}

404가 발생할 때마다 index.html로 리디렉션됩니다.

참고 : publicPath를 사용하는 경우 devServer에도 전달해야합니다.

module.exports = {
  entry: "index.js",
  output: {
    filename: "bundle.js",
    publicPath: "admin/dashboard"
  },
  devServer: {
    historyApiFallback: {
      index: "admin/dashboard"
    }
  }
}

출력의 처음 몇 줄을 살펴보면 모든 것이 올바르게 설정되었는지 확인할 수 있습니다 ( “404s는 다음으로 대체됩니다 : 경로 “).

여기에 이미지 설명 입력


답변

최신 답변 인 webpack (4.1.1)의 현재 버전은 다음과 같이 webpack.config.js에서 설정할 수 있습니다.

const webpack = require('webpack');

module.exports = {
    entry: [
      'react-hot-loader/patch',
      './src/index.js'
    ],
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                use: ['babel-loader']
            },
            {
                test: /\.css$/,
                exclude: /node_modules/,
                use: ['style-loader','css-loader']
            }
        ]
    },
    resolve: {
      extensions: ['*', '.js', '.jsx']
    },
    output: {
      path: __dirname + '/dist',
      publicPath: '/',
      filename: 'bundle.js'
    },
    plugins: [
      new webpack.HotModuleReplacementPlugin()
    ],
    devServer: {
      contentBase: './dist',
      hot: true,
      historyApiFallback: true
    }
  };

중요한 부분은 historyApiFallback: true입니다. 사용자 정의 서버를 실행할 필요없이 cli를 사용하기 만하면됩니다.

"scripts": {
    "start": "webpack-dev-server --config ./webpack.config.js --mode development"
  },


답변

동형 앱을 실행할 때 (즉, React 컴포넌트 서버 측 렌더링) 경우에 대한 답변에 추가하고 싶습니다.

이 경우 React 구성 요소 중 하나를 변경할 때 서버를 자동으로 다시로드 할 수도 있습니다. piping패키지 로이 작업을 수행 합니다. 당신이해야 할 일은 그것을 설치하고 server.jsrequire("piping")({hook: true}) 시작 부분에 추가 하는 것 입니다. 그게 다야. 서버에서 사용하는 구성 요소를 변경하면 서버가 다시 시작됩니다.

그러나 이것은 또 다른 문제를 야기합니다. 위의 대답에서와 같이 익스프레스 서버와 동일한 프로세스에서 웹팩 서버를 실행하면 웹팩 서버도 다시 시작되고 매번 번들을 다시 컴파일합니다. 이를 피하려면 파이핑이 익스프레스 서버 만 다시 시작하고 웹팩을 건드리지 않도록 다른 프로세스에서 메인 서버와 웹팩 서버를 실행해야합니다. concurrently패키지로 할 수 있습니다 . react-isomorphic-starterkit 에서 이에 대한 예를 찾을 수 있습니다 . 에서 package.json 그는이있다 :

"scripts": {
    ...
    "watch": "node ./node_modules/concurrently/src/main.js --kill-others 'npm run watch-client' 'npm run start'"
  },

두 서버를 동시에 실행하지만 별도의 프로세스에서 실행합니다.


답변

historyApiFallback 경로를 포함하는 부울 대신 개체가 될 수도 있습니다.

historyApiFallback: navData && {
  rewrites: [
      { from: /route-1-regex/, to: 'route-1-example.html' }
  ]
}