【问题标题】:React - webpack hmr反应 - webpack hmr
【发布时间】:2017-08-15 06:21:13
【问题描述】:

第一次修补 webpack 和相关的东西。我正在尝试结合 webpack-dev-server 和 browser-sync 的优点来实现它,因此当我更新反应组件时,我的浏览器不会重新加载,它只是使用热模块替换。我想有很多样板,但我是从头开始的。

我到了 HMR 开启并监听变化的地步。我编辑了一个组件,它收到了更改并说应用程序是最新的。但是几秒钟后视图没有改变,我得到一个 Web Socket 错误。

如果这很难阅读,它基本上是说 Web Socket 错误,套接字在完成握手之前关闭...

我的 webpack 配置

const webpack = require("webpack");
const path = require("path");
const SRC_DIR = path.resolve(__dirname,'src');
const DIST_DIR = path.resolve(__dirname,'dist');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const BrowserSyncPlugin = require('browser-sync-webpack-plugin');

module.exports = {

    entry: [
        'react-hot-loader/patch',
        'webpack/hot/only-dev-server',
        `${SRC_DIR}/index.js`
    ],
    output: {
        path: DIST_DIR,
        publicPath: '',
        filename: 'bundle.js'

    },

    module: {
        rules: [
            {
                test: /\.scss$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: ['css-loader','sass-loader']
                })
            },
            {
                test: /\.(png|svg|jpg|gif)$/,
                use: ['file-loader']
            },
            {
                test: /\.js?$/,
                use: ['babel-loader'],
                include: SRC_DIR
            }
            ]
    },

    plugins: [
        new CleanWebpackPlugin(['dist']),
        new HtmlWebpackPlugin({
            inject: false,
            template: require('html-webpack-template'),
            appMountId: 'root',
            devServer: '0.0.0.0' +':'+ 8081,
            title: "Webpack 4 React"
        }),
        new ExtractTextPlugin("styles.css"),
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NamedModulesPlugin(),
        new BrowserSyncPlugin({
            host: process.env.IP,
            port: process.env.PORT,
            //server: { baseDir: ['dist'] },
            ui: {
                port: 8082
            },
            proxy: process.env.IP +':'+ 8081
        },
        {
            reload: false
        }
        )
        ],

    devtool: 'source-map',

    devServer: {
        publicPath:'',
        host: process.env.IP,
        port: 8081,
        hot: true
    }
};

package.json 的 babel 部分

  "babel": {
    "presets":["es2015","react"],
    "plugins": ["react-hot-loader/babel"]
}

许多移动的部分和方法使这很难确定。但我觉得即使这不是最佳设置,我也快让它工作了。毕竟,我的浏览器同步页面正在从 WDS 获取 HMR json。也许我只是错过了一些简单的事情。一个奇怪的事情是公共路径的概念,例如,我似乎无法让它工作,除非它是一个空字符串。就像我说的,这是使用 webpack 的第一天,我还有很多东西要学。谢谢。

我可能应该添加我的 index.js,webpack 的入口点

import { AppContainer } from 'react-hot-loader';
import React from 'react';
import ReactDOM from 'react-dom';
import App from './Components/App';
import './styles.scss';

const root = document.getElementById("root");
//ReactDOM.render(<App/>,root);

const render = Component =>
  ReactDOM.render(
    <AppContainer>
      <Component />
    </AppContainer>,
    root
  );

render(App);

if (module.hot) module.hot.accept('./Components/App', () => render(App));

【问题讨论】:

    标签: webpack-dev-server browser-sync


    【解决方案1】:

    只是为了跟进,我已经开始工作了,只是对上面的代码进行了微小的更改。首先是index.js。我错过了新更新组件的声明。所以:

    if (module.hot) module.hot.accept('./Components/App', () => render(App));
    

    替换为以下内容:

    if (module.hot) module.hot.accept('./Components/App', () => {
      const newApp = require("./Components/App").default;
      render(newApp);
    });
    

    由于我使用的是 React 和 react-hot-loader,所以魔法完成了,我的更改生效,无需重新加载页面并因此丢失状态。我发现的一个警告是,如果我的更改涉及为将导致页面重新加载的组件创建构造函数和状态,但这是有道理的。

    我还必须改变处理scss 文件的方式。我使用的是ExtractTextPlugin。经过一些研究,我发现这更适合生产,并且不支持 HMR。这直接来自 Webpack Docs。所以我不得不改变我的webpack.config.js。我在我的插件部分注释掉插件的使用,并将我的scss 规则更改为以下内容。

    {
                    test: /\.scss$/,
                    use: [
                        {
                            loader: 'style-loader'
                        },{
                            loader: 'css-loader'
                        },{
                            loader: 'sass-loader'
                        }
                        ]
                    /* no HMR better for production
                    use: ExtractTextPlugin.extract({
                        fallback: 'style-loader',
                        use: ['css-loader','sass-loader']
                    })*/
                },
    

    上面是整个scss 规则,我的旧东西刚刚被注释掉,所以我可以在将来将它添加到 webpack 生产配置文件中。现在是下一个,引入 redux 和 react 路由器。

    【讨论】:

      猜你喜欢
      • 2017-06-24
      • 2019-08-24
      • 2017-05-25
      • 2017-06-26
      • 2017-09-16
      • 2017-01-21
      • 2016-02-18
      • 2017-05-11
      • 1970-01-01
      相关资源
      最近更新 更多