代码之家  ›  专栏  ›  技术社区  ›  Matt

React热加载程序和Webpack开发服务器不重新加载更改

  •  2
  • Matt  · 技术社区  · 8 年前

    我试着跟着 react-hot-loader/getstarted 在我的webpack配置中启动并运行react热加载程序。当我在组件中进行一些更改时,react热加载程序不会重新加载更改。我更新了新版本的脚本,添加了热处理加载程序到巴别塔,并配置和添加。 module.hot.accept 进入之内 index.jsx 是的。

    包.json

    "scripts": {
        "dev": "webpack-dev-server -d --progress --colors --port 8090 --hot --inline",
      },
        "dependencies": {
            "aphrodite": "^2.2.1",
            "bootstrap": "^4.1.1",
            "bootstrap-select": "^1.13.1",
            "classnames": "^2.2.5",
            "d3": "^3.5.17",
            "fixed-data-table-2": "^0.8.13",
            "font-awesome": "^4.7.0",
            "jquery": "^3.3.1",
            "js-cookie": "^2.2.0",
            "lodash": "^4.17.10",
            "moment": "^2.22.1",
            "popper.js": "^1.14.3",
            "react": "^16.3.2",
            "react-bootstrap-typeahead": "^3.1.3",
            "react-datetime": "^2.14.0",
            "react-dom": "^16.3.2",
            "react-hot-loader": "^4.3.3",
            "react-loadable": "^5.4.0",
            "react-modal": "^3.4.4",
            "react-redux": "^5.0.7",
            "react-router": "^4.2.0",
            "react-router-dom": "^4.2.2",
            "react-router-redux": "^5.0.0-alpha.9",
            "react-slidedown": "^1.3.0",
            "react-tippy": "^1.2.2",
            "react-toastify": "^4.0.1",
            "react-transition-group": "^2.3.1",
            "redux": "^4.0.0",
            "redux-saga": "^0.16.0"
          },
          "devDependencies": {
            "autoprefixer": "^8.4.1",
            "babel": "^6.23.0",
            "babel-core": "^6.26.3",
            "babel-eslint": "^8.2.3",
            "babel-loader": "^7.1.4",
            "babel-plugin-syntax-dynamic-import": "^6.18.0",
            "babel-plugin-transform-async-to-generator": "^6.24.1",
            "babel-plugin-transform-class-properties": "^6.24.1",
            "babel-plugin-transform-object-rest-spread": "^6.26.0",
            "babel-polyfill": "^6.26.0",
            "babel-preset-env": "^1.6.1",
            "babel-preset-latest": "^6.24.1",
            "babel-preset-react": "^6.24.1",
            "css-loader": "^0.28.11",
            "eslint": "^4.19.1",
            "eslint-config-airbnb": "^16.1.0",
            "eslint-plugin-import": "^2.11.0",
            "eslint-plugin-jsx-a11y": "^6.0.3",
            "eslint-plugin-react": "^7.7.0",
            "file-loader": "^1.1.11",
            "http-server": "^0.11.1",
            "less": "^3.0.2",
            "less-loader": "^4.1.0",
            "node-sass": "^4.9.0",
            "npm-install-webpack-plugin": "^4.0.5",
            "postcss": "^6.0.22",
            "postcss-loader": "^2.1.4",
            "redux-devtools-extension": "^2.13.2",
            "sass-loader": "^7.0.1",
            "sass-resources-loader": "^1.3.3",
            "style-loader": "^0.21.0",
            "url-loader": "^1.0.1",
            "webpack": "^4.6.0",
            "webpack-cli": "^2.1.2",
            "webpack-dev-server": "^3.1.4",
            "webpack-merge": "^4.1.2",
            "webpack-notifier": "^1.6.0"
          }
    

    巴贝尔

    {
      "presets": [
        [
          "latest", {
            "es2015": {
              "modules": false
            }
          }
        ],
        "react"
      ],
      "plugins": [
        "transform-object-rest-spread",
        "transform-class-properties",
        "syntax-dynamic-import",
        "transform-async-to-generator",
        "react-hot-loader/babel"
      ]
    }
    

    webpack.config.js文件

    const webpack = require('webpack');
    const webpackMerge = require('webpack-merge');
    const path = require('path');
    const WebpackNotifierPlugin = require('webpack-notifier');
    
    const TARGET = process.env.npm_lifecycle_event;
    console.log(`target event is ${TARGET}`);
    
    let outputFileName = 'app';
    outputFileName += TARGET === 'prod' ? '.min.js' : '.js';
    
    const common = {
      entry: ['babel-polyfill', 'react-hot-loader/patch', './index.jsx'],
      output: {
        publicPath: '/',
      },
      module: {
        rules: [
          {
            test: /\.js[x]?$/,
            exclude: /(node_modules)/,
            use: {
              loader: 'babel-loader',
            },
          },
        ],
      },
      plugins: [
        new webpack.ProvidePlugin({
          jQuery: 'jquery',
          $: 'jquery',
          jquery: 'jquery',
          'window.jQuery': 'jquery',
        }),
        new WebpackNotifierPlugin(),
      ],
      resolve: {
        modules: [
          path.resolve('.'),
          path.resolve('script'),
          path.resolve('script', 'views'),
          'node_modules',
        ],
        extensions: ['.js', '.jsx', '.json'],
      },
    };
    
    if (TARGET === 'dev' || !TARGET) {
      module.exports = webpackMerge(common, {
        devtool: 'eval-source-map',
        output: {
          filename: 'bundle.js',
          sourceMapFilename: '[file].map',
        },
        module: {
          rules: [
            {
              test: /\.scss$/,
              loaders: [
                'style-loader',
                'css-loader',
                {
                  loader: 'postcss-loader',
                  options: {
                    config: {
                      path: 'postcss.config.js',
                    },
                  },
                },
                'sass-loader',
              ],
            },
            {
              test: /\.less$/,
              loaders: ['style-loader', 'css-loader', 'less-loader'],
            },
            {
              test: /\.css$/,
              use: ['style-loader', 'css-loader'],
            },
            {
              test: /\.(eot|ttf|svg|gif|png|jpg|otf|woff|woff2)$/,
              loader: 'url-loader',
            },
          ],
        },
        devServer: {
          contentBase: path.resolve(__dirname), // New
          historyApiFallback: true,
        },
        plugins: [
          new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify('development'),
          }),
          new webpack.HotModuleReplacementPlugin(),
        ],
      });
    }
    

    索引.jsx

    import React from 'react';
    import ReactDOM from 'react-dom';
    import createHistory from 'history/createBrowserHistory';
    import { createStore, combineReducers, applyMiddleware } from 'redux';
    import { ConnectedRouter, routerReducer, routerMiddleware } from 'react-router-redux';
    import { Provider } from 'react-redux';
    import { AppContainer } from 'react-hot-loader';
    import createSagaMiddleware from 'redux-saga';
    import { composeWithDevTools } from 'redux-devtools-extension/developmentOnly';
    
    import 'bootstrap';
    import 'styles/custom.scss';
    
    import App from 'App';
    import reducers from 'state';
    import sagas from 'sagas';
    
    const history = createHistory();
    const sagaMiddleware = createSagaMiddleware();
    
    const store = createStore(
      combineReducers({
        ...reducers,
        router: routerReducer,
      }),
      composeWithDevTools(applyMiddleware(routerMiddleware(history), sagaMiddleware)),
    );
    
    if (module.hot) {
      module.hot.accept('state', () => {
        store.replaceReducer(require('state').default);
      });
    }
    
    sagaMiddleware.run(sagas);
    
    const render = (Component) => {
      ReactDOM.render(
        <AppContainer>
          <Provider store={store}>
            <ConnectedRouter history={history}>
              <Component />
            </ConnectedRouter>
          </Provider>
        </AppContainer>,
        document.getElementById('app'),
      );
    };
    
    render(App);
    
    if (module.hot) {
      module.hot.accept('App', () => { render(App); });
    }
    

    index.html索引

    <!DOCTYPE html>
    
    <html lang="en">
    <head>
        <meta charset="utf-8">
    
        <title>Test</title>
    
        <meta name="description" content="">
    
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    
    </head>
    <body>
    
        <div id="app">
    
        </div>
    
      <script type="text/javascript" src="/bundle.js"></script>
    
    </body>
    </html>
    
    3 回复  |  直到 8 年前
        1
  •  2
  •   Andrej Gajdos    7 年前

    你定义了 Hot Module Replacement 两次。你定义了 --hot 论证 package.json 然后 new webpack.HotModuleReplacementPlugin() 在里面 webpack.config.js 是的。你应该只定义一次。

        2
  •  2
  •   ponury-kostek    8 年前
    1. 你可以使用 react-script react-app-rewire-hot-loader
    2. 你也许不用 react-hot-loader/babel

      { test: /\.(js|jsx)$/,
      include: paths.appSrc,
      loader: require.resolve("babel-loader"),
      options: {
        // This is a feature of babel-loader for webpack (not Babel itself).
        // It enables caching results in ./node_modules/.cache/babel-loader/
        // directory for faster rebuilds.
        cacheDirectory: true,
        plugins: ["react-hot-loader/babel"]
        },
      }
      
        3
  •  0
  •   Mehdi Aarab    7 年前

    是否尝试将根组件导出为热组件:

    import { hot } from "react-hot-loader"
    const App = () => <h3>Hello World</h3>
    export default hot(module)(App)
    
    推荐文章