React-hot-loader 不适用于 React-router-dom



所以我终于用以下方法设置了一个工作项目:

  • 电子 (2.0.2(

  • 反应 (16.4.0(

  • React-router-dom (4.2.2(

  • 网络包 (4.11.0(

  • 反应热加载机 (4.2.0(

就在我开始开发一些反应组件时,我注意到我的项目无法正确热重载。如果我在基本 url (/( 上调整某些内容,它会正确更新,但是如果我在辅助 url 上更新某些内容,比如说 webpack 编译/test,但我收到消息Cannot GET /test.

我尝试了很多,但我似乎无法弄清楚我做错了什么。我研究了react-router-dom,因为热重载是版本3.x中的一个问题,但他们说现在应该解决(在4.x中 --> 它在这里工作..(。此外,我在index.html中添加了<base href="/"/>,所以不是这样。

谁能告诉我我做错了什么?


Webpack.common.js(这已合并到 Webpack.dev.js(

module.exports = {
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].bundle.js'
},
resolve: {
modules: [path.resolve(__dirname), 'node_modules']
},
module: {
rules: [
{
test: /.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
options: {
cacheDirectory: true,
presets: ['env', 'react'],
plugins: ['transform-runtime'],
env: {
development: {
plugins: ['react-hot-loader/babel']
},
production: {
presets: ['react-optimize']
}
}
}
}
]
}
};

Webpack.dev.js

module.exports = merge(common, {
mode: 'development',
devtool: 'eval-source-map',
entry: {
'app': [
'babel-polyfill',
'react-hot-loader/patch',
path.join(__dirname, 'src', 'index.js')
]
},
plugins: [
new webpack.HotModuleReplacementPlugin() // Enable hot module replacement
]
});

索引.js

import React from "react";
import ReactDOM from "react-dom";
import { AppContainer } from "react-hot-loader";
import { App } from "./app";
const render = Component => {
ReactDOM.render(
<AppContainer>
<Component/>
</AppContainer>,
document.getElementById("root")
);
};
render(App);
if (module.hot) {
module.hot.accept("./app", () => {
render(App);
});
}

App.js(我的应用的主要入口点,因此我定义基本路由(

import React, { Component } from 'react';
import { BrowserRouter, Route, NavLink } from 'react-router-dom';
import { Test } from './components/test';
import { Test2 } from './components/test2';
export class App extends Component {
render() {
return (
<BrowserRouter>
<div>
<NavLink to="/">Home</NavLink>
<NavLink to="/test">Test</NavLink>
<div>
<Route exact path="/" component={Test}/>
<Route path="/test" component={Test2}/>
</div>
</div>
</BrowserRouter>
);
}
}

组件"test"和"test2"只是简单的反应组件,带有"hello world"文本。

有人看到我遗漏或做错了什么吗?

多亏了本教程,我找到了一种方法来调整我的项目并使热加载工作。它甚至使我的代码更简洁,我的构建脚本更简单。


Webpack.common.js

我需要改变的第一件事是 babel-loader。我从某个教程中偷了它,它有效,但我不知道它到底做了什么,所以我摆脱了该代码。我还通过webpack.DllReferencePlugin使代码的编译速度更快。

以下是更新的webpack.common.js:

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');
module.exports = {
entry: {
app: [
'babel-polyfill',
'./src/index.js',
],
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
options: {
plugins: ['react-hot-loader/babel'],
cacheDirectory: true,
presets: ['env', 'react'],
},
}
],
},
plugins: [
new webpack.DllReferencePlugin({
context: path.join(__dirname),
manifest: require('../dist/vendor-manifest.json'),
}),
new HtmlWebpackPlugin({
title: '<my-app-name>',
filename: 'index.html',
template: './public/index.html',
}),
new AddAssetHtmlPlugin({
filepath: path.resolve(__dirname, '../dist/*.dll.js'),
includeSourcemap: false // add this parameter
})
],
};

AddAssetHtmlPlugin是必需的,因为index.html是为开发服务器动态创建的(由 HtmlWebpackPlugin(,并且您无法为vendor.dllapp.bundle硬编码正确的捆绑包导入(更多内容在这里(。


webpack.dev.js

const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const webpack = require('webpack');
const path = require('path');
module.exports = merge(common, {
mode: 'development',
devtool: 'eval-source-map',
devServer: {
hot: true,
contentBase: path.resolve(__dirname, 'dist'),
historyApiFallback: true // Allow refreshing of the page
},
plugins: [
new webpack.HotModuleReplacementPlugin(), // Enable hot reloading
]
});

我改变了什么:

  1. 我将入口点向上移动到webpack.common.

  2. 我从entry中删除了'react-hot-loader/patch'

  3. (可选(我为webpack-dev-server添加了一些配置选项。


索引.js

这是导致热重载失败的文件。尤其是if(module.hot)部分导致它失败。所以我把它改成以下内容:

import React from 'react';
import ReactDOM from 'react-dom';
import { AppContainer } from 'react-hot-loader';
import { App } from './app';
const render = () => {
ReactDOM.render(
<AppContainer>
<App/>
</AppContainer>,
document.getElementById('app'),
);
};
render(App);
if (module.hot) {
module.hot.accept('./app', () => {
const NextApp = require('./app').default; // Get the updated code
render(NextApp);
});
}

它现在工作的原因是现在我获取新应用程序并替换旧应用程序,从而告诉热加载器发生了更改。我也可以只使用module.hot.accept(),但这会使react-hot-loader无用(您使用 webpack 热重装器(,这样每次更新一些代码时,我也会丢失组件中的状态。

所以你去吧。我希望这会帮助任何人(除了我自己(。

最新更新