HMR иногда не запускается для компонентов - PullRequest
0 голосов
/ 23 февраля 2020

Это сбивает меня с толку уже несколько часов, и я не могу понять, почему. Моя структура проекта ниже. Иногда изменение views/Dashboard/index.jsx вызывает горячую перезагрузку, а в других случаях - нет. Это странно, но когда это работает, примерно через час или около того, оно просто внезапно перестает работать ...

index. js

import 'react-hot-loader'
import 'bootstrap/dist/css/bootstrap.min.css'
import React from 'react'
import ReactDOM from 'react-dom'
import { AppContainer } from 'react-hot-loader'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faChartBar, faThList, faCogs, faClipboard, faFilter, faNotEqual } from "@fortawesome/free-solid-svg-icons"

import configureStore, { history } from './redux/store'
import App from './App'

library.add(faChartBar, faThList, faCogs, faClipboard, faFilter, faNotEqual)

let store

function render(Component) {
    ReactDOM.render(
        <AppContainer>
            <Component store={store} />
        </AppContainer>,
        document.getElementById('root')
    )
}

configureStore()
    .then(_store => {
        store = _store

        render(App)

        if (module.hot) {
            // Reload components
            module.hot.accept('./App', () => {
                render(App)
            })
        }
    })
    .catch(err => {
        console.log(err)
    })

App.jsx

import { hot } from 'react-hot-loader/root'
import React from 'react'
import { Provider } from 'react-redux'
import { BrowserRouter as Router } from 'react-router-dom'
import PropTypes from 'prop-types'

// Routes
import routes from './routes'

const App = ({ store }) => {
    return (
        <Provider store={store}>
            <Router>{routes}</Router>
        </Provider>
    )
}

App.propTypes = {
    history: PropTypes.object,
}

export default hot(module)(App)

маршруты / индексы. js

import React from 'react'
import { Route, Switch } from 'react-router'

// Components
import Dashboard from '../views/Dashboard'

// Views
import NoMatch from '../views/NoMatch'

export default (
    <Switch>
        <Route path="/" component={Dashboard} exact={true} />
        <Route component={NoMatch} />
    </Switch>
)

представления / Dashboard / index.jsx

import React, { Component } from 'react'

export default class Dashboard extends Component {
    constructor(props) {
        super(props)
    }

    render() {
        return (
            <div>
                Hello World
            </div>
        )
    }
}

Если я внесу какие-либо изменения в первые 4 перечисленных файла (index.js, App.jsx, routes/index.js, containers/Dashboard.js), то будет выполнена горячая перезагрузка, и страница перезагрузится. Однако, если я попытаюсь внести изменения, например, в views/Dashboard/index.jsx, сменив «Hello World» на «Foo Bar», тогда горячая перезагрузка не будет принята. Из редукса и изменил routers/index.js для использования прямого компонента из views/Dashboard/index.jsx, и он все еще не перезагружается.

Как это может быть? Если я установлю component на Route на контейнер, указанный выше, он будет перезагружен для этого файла, но не для этого JSX? Это связано со структурой внутри моего основного компонента views/Dashboard/index.jsx? Если так, то? Как это выглядит хорошо для меня.

РЕДАКТИРОВАТЬ

Моя полная конфигурация webpack:

webpack.common. js

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const DotenvPlugin = require('dotenv-webpack')

module.exports = {
    output: {
        path: path.resolve(__dirname, 'dist'),
        publicPath: '/',
        filename: 'js/[name].bundle.js',
    },
    resolve: {
        extensions: ['.js', '.jsx'],
    },
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                loader: 'babel-loader', // Using Babel to compile JS files
            },
            {
                test: /\.(css|scss|sass)$/,
                use: ['style-loader', 'css-loader', 'sass-loader'],
            },
            {
                test: /\.(png|svg|jpg|gif|woff|woff2|eot|ttf|otf)$/,
                use: [
                    {
                        loader: 'url-loader',
                        options: {
                            limit: 1000000,
                            name: 'img/[hash].[ext]',
                        },
                    },
                ],
            },
            {
                test: /\.html$/,
                loader: 'html-loader'
            }
        ],
    },
    plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, 'public', 'index.html'),
            filename: './index.html',
        }),
        new DotenvPlugin({
            systemvars: true,
        }),
    ],
    optimization: {
        runtimeChunk: 'single',
        splitChunks: {
            cacheGroups: {
                vendor: {
                    test: /[\\/]node_modules[\\/]/,
                    name: 'vendors',
                    chunks: 'all',
                },
            },
        },
    },
}

webpack.dev. js

const webpack = require('webpack')
const merge = require('webpack-merge')
const path = require('path')

const common = require('./webpack.common.js')

module.exports = merge(common, {
    mode: 'development',
    entry: path.resolve(__dirname, 'src', 'index.js'),
    // https://github.com/gaearon/react-hot-loader#source-maps
    devtool: 'eval',
    devServer: {
        contentBase: path.join(__dirname, 'dist'),
        open: true,
        compress: true,
        hot: true,
        historyApiFallback: true
    },
    resolve: {
        alias: {
            'react-dom': '@hot-loader/react-dom'
        }
    },
    plugins: [
        new webpack.NamedModulesPlugin(),
        new webpack.EnvironmentPlugin({
            NODE_ENV: 'development',
        }),
    ],
    optimization: {
        usedExports: true,
    },
})

.babelr c

{
    "presets": [
        [
            "@babel/preset-env",
            {
                "useBuiltIns": "entry",
                "corejs": "3.0.0",
                "targets": {
                    "esmodules": true
                }
            }
        ],
        "@babel/preset-react"
    ],
    "plugins": [
        "react-hot-loader/babel"
    ]
}

Я обновил перечисленные файлы, чтобы показать, что у меня есть в данный момент. Это очень странная ошибка, так как иногда горячая перезагрузка будет работать, а иногда - нет. Горячая перезагрузка всегда работает для файлов; index.js, App.jsx, & routes/index.jsx, но иногда это будет работать для views/Dashboard/index.jsx, а иногда нет.

Ранее я следовал руководству Getting Started , но эта ветка помогла мне понять, что это устарело. Я только что следовал за README , как уже упоминалось. Я также попытался взять фрагменты из этой статьи , а также при настройке HMR с Webpack 4.

Версии

  • webpack: 4.41.6
  • webpack-dev-server: 3.10.3
  • babel-loader: 8.0.6
  • @hot-loader/react-dom: 16.11.0
  • react: 16.12.0
  • react-hot-loader: 4.12.19

У меня есть следующий ответ в консоли, поэтому HMR явно включен

enter image description here

I я пытаюсь точно воспроизвести то, что в примерах как рекомендуется

...