首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >React - webpack hmr

React - webpack hmr
EN

Stack Overflow用户
提问于 2017-08-15 14:21:14
回答 1查看 517关注 0票数 0

第一次修修补补地摆弄webpack和相关的东西。我正在尝试将开发服务器和浏览器同步的优点结合起来,这样当我更新一个react组件时,我的浏览器不会重新加载,它只是简单地使用热模块替换。我猜有很多样板文件,但我是从头开始的。

我已经到了打开HMR并侦听更改的地步了。我编辑了一个组件,它会收到更改并显示App是最新的。但是视图没有改变,几秒钟后我得到了一个Web套接字错误。

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

我的webpack配置

代码语言:javascript
复制
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部分

代码语言:javascript
复制
  "babel": {
    "presets":["es2015","react"],
    "plugins": ["react-hot-loader/babel"]
}

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

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

代码语言:javascript
复制
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));
EN

回答 1

Stack Overflow用户

发布于 2017-08-16 08:10:49

只是为了跟进,我已经让事情正常工作,对上面的代码只做了很小的修改。首先是在index.js中。我遗漏了新更新组件的声明。所以:

代码语言:javascript
复制
if (module.hot) module.hot.accept('./Components/App', () => render(App));

将替换为以下内容:

代码语言:javascript
复制
if (module.hot) module.hot.accept('./Components/App', () => {
  const newApp = require("./Components/App").default;
  render(newApp);
});

由于我使用的是React和react-hot-loader,魔术已经完成,并且我的更改无需重新加载页面即可生效,从而丢失状态。我发现的一个警告是,如果我的更改涉及为组件创建构造函数和状态,这将导致页面重新加载,但这是有意义的。

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

代码语言:javascript
复制
{
                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路由器。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45687452

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档