我正在运行一个快速服务器,它将作为我的React应用程序的API,该应用程序由webpack-dev-server捆绑并提供服务。
我正在尝试让热模块替换工作,并且几乎在那里,当我对我的文件进行更改时,我在控制台中得到了这个:
但除非手动刷新,否则永远不会重新呈现该应用。不知道这是否相关,但是当我更新我的.scss
文件时,它会刷新而不会手动执行,并且会按照我的预期进行更新。
版本:
"webpack": "2.1.0-beta.22"
"webpack-dev-server": "2.1.0-beta.8"
"react-hot-loader": "3.0.0-beta.5"
我尝试了最新的webpack,但它给了我无法克服的验证错误。
我正在通过"webpack": "webpack-dev-server --port 4000 --env.dev"
运行webpack,我的快速服务器正在http://localhost:3000
上运行。
这是我的webpack.config.babel.js
:
const webpack = require('webpack');
const { resolve, join } = require('path');
const { getIfUtils, removeEmpty } = require('webpack-config-utils')
const getEntry = (ifDev) => {
let entry
if (ifDev) {
entry = {
app: [
'react-hot-loader/patch',
'webpack/hot/dev-server',
'webpack-dev-server/client?http://localhost:4000/',
'./js/index.js'
],
vendor: ['react']
}
} else {
entry = {
bundle: './js/index.js',
vendor: ['react']
}
}
return entry
}
const config = env => {
const { ifProd, ifDev } = getIfUtils(env)
return {
entry: getEntry(ifDev),
output: {
path: resolve('./public/dist/'),
publicPath: 'http://localhost:4000/',
filename: '[name].bundle.js',
},
context: resolve(__dirname, 'assets'),
devtool: env.prod ? 'source-map' : 'eval',
devServer: {
contentBase: resolve('./public/dist/'),
headers: { 'Access-Control-Allow-Origin': '*' },
publicPath: 'http://localhost:4000/',
hot: true,
noInfo: true,
inline: true
},
bail: env.prod,
module: {
loaders: [
{ test: /\.scss$/, loaders: [ 'style', 'css', 'sass' ], exclude: /node_modules|lib/ },
{ test: /\.(js|jsx)$/, exclude: /node_modules/, loaders: [ 'babel-loader' ] },
{ test: /\.(ttf|eot|svg|woff(2)?)(\?[a-z0-9=&.]+)?$/, loader: 'file-loader' }
]
},
resolve: {
extensions: ['.js', '.jsx']
},
plugins: removeEmpty([
ifDev(new webpack.NoErrorsPlugin()),
ifDev(new webpack.NamedModulesPlugin()),
ifDev(new webpack.HotModuleReplacementPlugin()),
new webpack.DefinePlugin({
'process.env': { NODE_ENV: JSON.stringify((env.prod) ? 'production' : 'development') }
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: Infinity,
filename: 'vendor.bundle.js'
}),
ifProd(new webpack.LoaderOptionsPlugin({
minimize: true,
debug: false
})),
ifProd(new webpack.optimize.UglifyJsPlugin({
compress: { warnings: false },
output: { comments: false },
sourceMap: false
}))
]),
}
}
module.exports = config
以下是我的.babelrc
,我致电react-hot-loader
{
"presets": [["es2015", { modules: false }], "stage-0", "react"],
"plugins": ["react-hot-loader/babel"],
"env": {
"test": {
"plugins": ["istanbul"],
"presets": ["es2015", "stage-0", "react"]
}
},
"sourceMaps": "inline"
}
答案 0 :(得分:5)
使用React Hot Loader v3和Babel转换,您希望在组件的根目录(渲染的位置或创建Redux提供程序的位置)执行此操作:
render(
<AppContainer>
<Root
store={ store }
/>
</AppContainer>,
document.getElementById('root')
);
if (module.hot) {
module.hot.accept('./containers/Root', () => {
const RootContainer = require('./containers/Root').default;
render(
<AppContainer>
<RootContainer
store={ store }
/>
</AppContainer>,
document.getElementById('root')
);
});
}
使用新版本的Hot Loader,您必须明确接受module.hot.accept
的热门更新。
在一个更复杂的Redux项目中(使用路由和热重载减速器),您可以执行以下操作:
/**
* Starts the React app with the Router, and renders it to the given DOM container
* @param {DOMElement} container
*/
export default function app(container) {
const store = createStore(
combineReducers({
...reducers,
routing: routerReducer,
form: formReducer,
}),
compose(
applyMiddleware(
routerMiddleware(hashHistory),
thunkMiddleware,
promiseMiddleware
),
process.env.NODE_ENV !== 'production' && window.devToolsExtension ? window.devToolsExtension() : (param) => param
)
);
if (module.hot) {
module.hot.accept('./reducers', () => {
const nextReducers = require('./reducers');
const nextRootReducer = combineReducers({
...nextReducers,
routing: routerReducer,
form: formReducer,
});
store.replaceReducer(nextRootReducer);
});
}
const history = syncHistoryWithStore(hashHistory, store);
render({ store, history, container });
store.dispatch(loadEventsWhenLoggedIn());
if (module.hot) {
module.hot.accept('./render', () => {
const newRender = require('./render').default;
newRender({ store, history, container });
});
}
}
(和render.js)
/**
* Starts the React app with the Router, and renders it to the given DOM container
* @param {DOMElement} container
*/
export default function render({ store, history, container }) {
ReactDOM.render(
<Provider store={store}>
<div className='container'>
<Routes history={history} store={store} />
</div>
</Provider>,
container
);
}
有关更多示例,您应该查看Dan Abramov的Redux devtools示例仓库,例如此文件:https://github.com/gaearon/redux-devtools/blob/master/examples/todomvc/index.js
答案 1 :(得分:2)
HMR自动为CSS工作,因为style-loader
支持开箱即用。
React并非如此。您需要react-hot-loader。
使用npm安装它,然后更改:
{ test: /\.(js|jsx)$/, exclude: /node_modules/, loaders: [ 'babel-loader' ] },
要:
{ test: /\.(js|jsx)$/, exclude: /node_modules/, loaders: [ 'react-hot-loader', 'babel-loader' ] },
如果您想了解更多信息,建议您阅读“Webpack’s HMR & React-Hot-Loader — The Missing Manual”。