[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/",
// ...
}
답변
당신은 설정해야합니다 historyApiFallback
의 WebpackDevServer
일이 마찬가지한다. 다음은 작은 예입니다 (목적에 맞게 조정).
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' }
]
}