尽管文件监视工作正常,但无法在浏览器中启用带有 react-hot 的 HotModuleReplace 插件

Cannot get HotModuleReplace plugin with react-hot to be enabled in the browser, though file watching is working

我正在尝试使用 webpack 的 Hot Module Replacement 插件。我设法随机让它工作,但它仍然没有达到我希望的效果。

基本上,我的控制台没有消息表明它甚至处于活动状态,尽管它正在构建而没有问题并且文件监视工作正常,因为我收到消息webpack: bundle is now VALIDwebpack: bundle is now INVALID 当我更新时。

webpackwebpack-dev-serverreact-hot都是本地安装的。

但是在浏览器的控制台中,我唯一看到的是:

Download the React DevTools for a better development experience: https://fb.me/react-devtools

我正在使用 Laravel 根据环境变量更新我的索引文件,它工作正常。

这是 index.php 文件:

<!DOCTYPE html>
<html>
    <head>
        <title></title>
    </head>
    <body>
        <div id="content"></div>

        @if(env("APP_HOTRELOAD"))
            <script src="http://localhost:8080/js/vendor.js"></script>
            <script src="http://localhost:8080/js/app.js"></script>
        @else
            <script src="js/vendor.js"></script>
            <script src="js/app.js"></script>
        @endif
    </body>
</html>

这是 webpack 配置文件 (webpack.hot-reload.config.js):

var path = require("path");
var webpack = require("webpack");
var node_modules = path.resolve(__dirname, "node_modules");
var public_dir = path.resolve(__dirname, "public");

module.exports = {

    debug: (process.env.NODE_ENV === "production"),

    entry: {
        vendor: [
            "es5-shim",
            "es5-shim/es5-sham",
            "babel-core/polyfill",
            "babel-core/external-helpers",
            "react",
            "react-router-component"
        ],
        app: [
            "webpack-dev-server/client?http://localhost:8080",
            "webpack/hot/only-dev-server",
            path.resolve(__dirname, "resources/assets/js/index.js")
        ]
    },

    contentBase: public_dir,

    output: {
        path: path.resolve(public_dir, "js"),
        filename: "app.js",
        publicPath: "/"
    },

    plugins: [
        new webpack.optimize.CommonsChunkPlugin("vendor", "vendor.js"),
        //This is necessary for React to know whether it's supposed to strip out
        //addons and extra stuff when being minified.  Essentially, it becomes dead
        //code and webpack will take it out.
        new webpack.DefinePlugin({
            "process.env": {"NODE_ENV": JSON.stringify(process.env.NODE_ENV)}
        }),
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NoErrorsPlugin()
    ],

    module: {
        loaders: [
            {
                test: /\.(sa|c)ss$/,
                loader: "css!style!sass"
            },
            {
                test: /\.jsx?$/,
                exclude: /(node_modules|bower_components)/,
                loaders: [
                    "react-hot",
                    "strip-loader?strip[]=debug,strip[]=console.log,strip[]=console.error",
                    "babel-loader"
                ]
            }
        ]
    },

    resolve: {
        root: path.resolve(__dirname, "resources/assets/js"),
        extensions: ["", ".js", ".json"]
    }
};

为了启动 webpack-dev-server,我使用一个单独的 server.js 文件,使用 node server.js:

执行
var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var config = require('./webpack.hot-reload.config');

new WebpackDevServer(webpack(config), {
    publicPath: config.output.publicPath,
    contentBase: config.contentBase,
    hot: true,
    historyApiFallback: true,
    quiet: false,
    noInfo: false,
    stats: {
        colors: true
    }
}).listen(8080, 'localhost', function (err, result) {
        if (err) {
            console.log(err);
        }
        console.log('Listening at localhost:8080');
    });

等待一段时间后似乎随机工作,但如果我更改文件或手动刷新页面,它似乎就中断了。我试过同时使用 Firefox 和 Chrome,但没有任何区别,所以我认为它在构建中。

有什么问题吗?

我明白了。页面上 was a comment about it 说明了如何使用 webpack-dev-server,但我设法阅读了它。

如果您查看我的配置,您会看到:

...
output: {
    path: path.resolve(public_dir, "js"),
    filename: "app.js",
    **publicPath: "/"**
},
...

我误解了 publicPath 密钥及其路径。

但是the docs中给出的例子显示:

module.exports = {
  entry: {
    app: ["./app/main.js"]
  },
  output: {
    path: "./build",
    publicPath: "/assets/",
    filename: "bundle.js"
  }
};

并指出:

This modified bundle is served from memory at the relative path specified in publicPath (see API). It will not be written to your configured output directory. Where a bundle already exists at the same url path the bundle in memory will take precedence.

但是,对于此示例,此捆绑包将从 / 而不是 /assets/ 提供,因为再往下 the content base is given as build/。没有任何东西指出脚本所在的目录可能根本别名为 /assets/,所以这就是为什么我将 / 路径放置为 publicPath 而不是 the我的 JS 实际上是从子目录提供的。.

文档指出:

To teach webpack to make requests (for chunk loading or HMR) to the webpack-dev-server you need to provide a full URL in the output.publicPath option.

所以我改变了:

    publicPath: "/"

至:

    publicPath: "http://localhost:8080/js/"

现在我的文件已正确提供。我添加了 /js/ 因为那是我的 JavaScript 在实际服务器上提供服务的地方。