最新消息:20210917 已从crifan.com换到crifan.org

【已解决】ReactJS-AdminLTE中的webpack-dev-server的HMR热更新不生效

ReactJS crifan 2728浏览 0评论

折腾:

【已解决】ReactJS-AdminLTE中如何调试和哪部分代码是首页的源码

和:

【整理】ReactJS-AdminLTE中的代码调用逻辑

后,去修改了源文件

比如:

ReactJS-AdminLTE/src/pages/dashboardV1/js/components/navigation-menu.js

改个中文文字:

然后虽然可以看到命令行中:

webpack: Compiling

但是实际上页面:

http://localhost:8000/

还是没有更新:

目前此处的配置是:

/ReactJS-AdminLTE/server.js

let webpackListenPort = 3000;
var webpack = require(‘webpack’);
var WebpackDevServer = require(‘webpack-dev-server’);
var config = require(‘./webpack.config’);
new WebpackDevServer(webpack(config), {
    publicPath: config.output.publicPath,
    hot: true,
    inline: true,
    historyApiFallback: true
}).listen(webpackListenPort, ‘localhost’, function (err, result) {
    if (err) {
        console.log(err);
    }
      console.log(`Listening at localhost:${webpackListenPort}`);
});

ReactJS-AdminLTE/webpack.config.js

    plugins: [
        new webpack.HotModuleReplacementPlugin(),
    module: {
        noParse: [
            //new RegExp(node_dir + ‘/react’),
            new RegExp(lib_dir + ‘./react-dom.js’)
        ],
        loaders: [
            {
                test: /\.jsx?$/,
                loaders: [‘react-hot’],
                include: path.join(__dirname, ‘public’),
                exclude: /(node_modules|bower_components)/
            },

webpack-dev-server 配置

[webpack] webpack-dev-server介绍及配置 – <!–hhhyaaon–> – 博客园

webpack-dev-server使用方法,看完还不会的来找我~ – JSer – SegmentFault

关于 webpack 和 webpack-dev-server 配置的个人小结 – 前端 – 掘金

WEBPACK DEV SERVER – 简书

Webpack DevServer配置 – 简书

Webpack-Chinese-Translation/README.md at master · jackyon/Webpack-Chinese-Translation

webpack dev server

怀疑是不是目前只能支持到依赖的js文件的第一层,第一层所引用的其他js就无法解析到了?

结果:

第一层都没法通知到。

总之,现在的现象就是:

js文件更新后,webpack是可以检测到,并重新编译compile的

但是浏览器端,并没有被通知到。

webpack compile but not hot reload

Running the server does not compile files or reload page in windows. · Issue #155 · webpack/webpack-dev-server

Hot Reload not responding to changes on components · Issue #378 · vuejs-templates/webpack

需要加上:

content-base

参数?

Webpack HMR Tutorial

用webpack-dev-server有两种方式:

命令行CLI中运行:

webpack-dev-server 加上参数

比如之前的:

webpack-dev-server –open –inline —hot

或者是:

调用接口WebpackDevServer

且还需要webpack.config.js中加上额外的配置。

去尝试加:

        ‘webpack/hot/dev-server’,
        ‘webpack-dev-server/client?http://localhost:8080/’,

webpack.config.js的entry中:

但是感觉好像语法不对:

webpack-hmr-starter-dev-server-api/webpack.config.js at master · ahfarmer/webpack-hmr-starter-dev-server-api

entry是个list

我这里entry是个dict

webpack-hmr-starter-dev-server-api/server.js at master · ahfarmer/webpack-hmr-starter-dev-server-api

Webpack-dev-server compiles files but does not refresh or make compiled javascript available to browser – Stack Overflow

hot module replacement with webpack

抽空好好看看webpack的配置:

Concepts

Entry Points

看了看之前正常能工作的Preact项目中的写法

src/index.js

// in development, set up HMR:
if (module.hot) {
  //require(‘preact/devtools’);   // turn this on if you want to enable React DevTools!
  module.hot.accept(‘./container/app’, () => requestAnimationFrame(init) );
}

之后能在浏览器中看到:

dev-server.js?30c5:49 [HMR] Waiting for update signal from WDS…

ReactJS-AdminLTE hmr not work

Can’t get it to work with ReactJS-AdminLTE · Issue #1380 · facebookincubator/create-react-app

Can’t get it to work with ‘react create app’ · Issue #34 · booleanhunter/ReactJS-AdminLTE

Possible fix for #34 · booleanhunter/ReactJS-AdminLTE@d6375a4

webpack-dev-server hmr not work

Webpack HMR Tutorial

webpack hot reload doesnt work · Issue #741 · webpack/webpack-dev-server

Hot module / hrm not working anymore? · Issue #862 · webpack/webpack-dev-server

抽空试试:

entry: {
。。。
    ‘vendor’: [
        ‘react-hot-loader/patch’,
        ‘webpack-dev-server/client?http://0.0.0.0:9000’,

和:

javascript – Webpack dev server hot mode not working – Stack Overflow

中的:

<script src=”http://localhost:8080/webpack-dev-server.js”></script>

Hot Reload not responding to changes on components · Issue #378 · vuejs-templates/webpack

Running the server does not compile files or reload page in windows. · Issue #155 · webpack/webpack-dev-server

关于 webpack 和 webpack-dev-server 配置的个人小结 – 前端 – 掘金

Webpack’s HMR & React-Hot-Loader — The Missing Manual

解释的很详细,抽空好好看看。

然后给:

/ReactJS-AdminLTE/views/dashboard.html

加上:

        <script src=”http://localhost:3000/webpack-dev-server.js”></script>

然后好像WDS的HMR真的生效了?

[WDS] Hot Module Replacement enabled. webpack-dev-server.js:1

然后去修改文字,结果console输出了

Recompiling

但是结果还是没有变化:

对于此处的webpack 1.x(而不是最新的2.x)来说,去试试:

webpack dev server

添加:

config.entry.vendors.unshift(`webpack-dev-server/client?http://localhost:${webpackListenPort}/`);

注意,此处不是:

config.entry.app.unshift

否则会提示不支持unshift,因为此处没有app,而是vendors:

即:

ReactJS-AdminLTE/webpack.config.js

    entry: {
        dashboardV1: ‘./src/pages/dashboardV1/js/dashboard’,
        widgets: [‘./src/pages/widgets-page/js/widgets-page’],
        timeline: ‘./src/pages/timeline-page/js/timeline-page’,
        generalUIElements: ‘./src/pages/ui-elements-page/general/js/page-ui-elements’,
        vendors: [‘react’, ‘react-dom’, ‘jquery’, ‘velocity-animate’, ‘jqueryUi’, ‘bootstrap’, ‘moment’, ‘bootstrapDatepicker’],
        chartVendors: [‘jquery’, ‘raphael’, ‘morris’, ‘jvectormap’, ‘jvectormapWorld’],
        // ‘webpack/hot/dev-server’,
        // ‘webpack-dev-server/client?http://localhost:8080/’,
    },

结果:

虽然hot update但是内容还是没变:

(源码的内容已改为:HMR继续测试)

通过配置文件:

ReactJS-AdminLTE/webpack.config.js

加上:

    entry: {
。。。
        vendors: [
            ‘webpack/hot/dev-server’,
            ‘webpack-dev-server/client?http://localhost:3000/’,
            ‘react’,
           。。。
        ],
        。。。
    },

试试:

(后续贴的图)修改了内容后,terminal终端和Chrome的console都会看到

Recompiling…

然后终于可以HMR可以刷新页面,显示最新修改后的内容了:

源码内容是:

【总结】

此处想要实现inline+HMR,即:

当代码有改动后,自动重新编译,然后自动打包输出,且浏览器自动热更新,自动去刷新页面。

对于此需求,对应着webpack中,好像就是两个属性:inline和HMR。

对应的实现方式,webpack的官网其已经解释的其实很清楚了。

注:

关于inline+HRM的webpack官网:

此处主要解释1.x的做法:

【inline模式】

先解释inline模式的效果:

(1)状态信息会输出到console命令行(此处是Mac的中iTerm),简要的信息会输出到浏览器(此处的是Mac的Chrome)的console命令行

(2)app内部的URL变化后,会反应到浏览器中的url地址

再说如何去实现:

【webpack中的inline模式】

对于Webpack 1.x来说,3种方式:

(1)命令行模式:

webpack-dev-server –inline

自动帮你加上对应的配置。

(2)webpack.config.js中加上配置:

    devServer: {
        inline: true
    }

【Node.js API中的inline模式】

先解释,什么是Node.js API:

此处指的是:webpack-dev-server

其是一个基于Node.js的(还是Express的)服务器?

总之就是和类似于这样的代码:

new WebpackDevServer()

有关系,指的是,从API接口的代码中,如何实现inline。

再说:

由于webpack-dev-server中没法访问webpack的配置,所以webpack-dev-server中是没有inline模式的选项控制的。所以用户必须手动的去加webpack-dev-server的client客户端的入口entry到webpack的配置中。具体做法:

webpack-dev-server/client?http://«path»:«port»/

加到所有的入口中。

官网示例代码:

var config = require(“./webpack.config.js”);
config.entry.app.unshift(“webpack-dev-server/client?http://localhost:8080/”);
var compiler = webpack(config);
var server = new WebpackDevServer(compiler, {…});
server.listen(8080);

【HTML中的inline】

也可以通过把:

<script src=”http://localhost:8080/webpack-dev-server.js”></script>

加入到HTML中,去实现inline模式。

【HMR热更新】

想要实现热更新的话,直接在CLI命令行中加上参数:

webpack-dev-server –hot

即可。其内部会把HotModuleReplacementPlugin加到webpack的配置中。

【inline模式+HMR】

如果实现了inline+HMR,就是之前所希望的效果:

然后在浏览器的console中会看到类似于:

[HMR] Waiting for update signal from WDS…
[WDS] Hot Module Replacement enabled.

的输出。

其中:

[HMR]开头的:来自webpack/hot/dev-server,HMR=Hot Module Replacement

[WDS]开头的:来自webpack-dev-server,WDS=Webpack Dev Server

而想要实现inline+HMR,也有多种方式:

最简单的去实现 inline+HMR的方式,就是:

【命令行CLI中使用inline+HMR】

webpack-dev-server –inline –hot

即可,其自动的内部帮你把相关的:

webpack/hot/dev-server

加到webpack的entry配置中。

且要注意设置正确的output.publicPath,否则HMR热更新无法加载对应的打包出来的chunks文件。

【Node.js API中实现 inline+HMR】

要做三件事:

  1. 把webpack/hot/dev-server加到配置文件的entry中

  2. 把new webpack.HotModuleReplacementPlugin()加到配置文件中

  3. 把配置属性hot: true加到webpack-dev-server中

举例:

var config = require(“./webpack.config.js”);
config.entry.app.unshift(“webpack-dev-server/client?http://localhost:8080/”, “webpack/hot/dev-server”);
var compiler = webpack(config);
var server = new webpackDevServer(compiler, {
  hot: true
  …
});
server.listen(8080);

解释完毕之后,附上此处ReactJS-AdminLTE的实际的设置和解释:

其中,关于ReactJS-AdminLTE的代码调用逻辑,此处不再赘述,详见:

【整理】ReactJS-AdminLTE中的代码调用逻辑

此处只接着说关于webapck的inline+HMR如何设置。

ReactJS-AdminLTE/server.js

var http = require(“http”);  //1
var url = require(“url”);  //2
var express = require(“express”);
var consolidate = require(‘consolidate’);
var handlebars = require(‘handlebars’);
var bodyParser = require(‘body-parser’);
var routes = require(‘./routes’);
var app = express();
let appPort = 8000;
app.set(‘views’, ‘views’); //Set the folder-name from where you serve the html page. ]
app.set(‘view engine’, ‘html’);
app.engine(‘html’, consolidate.handlebars);
app.use(express.static(‘./public’)); //Set the folder from where you serve all static files like images, css, javascripts, libraries etc
app.use(bodyParser.urlencoded({ extended: true }));
var portNumber = process.argv[2] || appPort;
http.createServer(app).listen(portNumber, function(){
    console.log(‘Server listening at port ‘+ portNumber);
    routes.initialize(app);
});
let wdsListenPort = 3000;
var webpack = require(‘webpack’);
var WebpackDevServer = require(‘webpack-dev-server’);
var config = require(‘./webpack.config’);
// add HMR module into entry point
config.entry.vendors.unshift(`webpack/hot/dev-server`);
// add inline mode module into entry point
config.entry.vendors.unshift(`webpack-dev-server/client?http://localhost:${wdsListenPort}/`);
//config.entry.vendors.unshift(`webpack/hot/dev-server`, `webpack-dev-server/client?http://localhost:${wdsListenPort}/`);
// add HMR plugin
let hmrModule = new webpack.HotModuleReplacementPlugin();
// console.log(hmrModule); // HotModuleReplacementPlugin {}
// console.log(`server.js: config.plugins=${JSON.stringify(config.plugins)}`);
// config.plugins.push(hmrModule); // add to list end
config.plugins.unshift(hmrModule); // add to list first
// console.log(`server.js: config.plugins=${JSON.stringify(config.plugins)}`);
var compiler = webpack(config);
// more info refer http://webpack.github.io/docs/webpack-dev-server.html
new WebpackDevServer(compiler, {
    // contentBase: ‘public/dist’,
    publicPath: config.output.publicPath,
    // Enable special support for Hot Module Replacement
    // Page is no longer updated, but a “webpackHotUpdate” message is sent to the content
    // Use “webpack/hot/dev-server” as additional module in your entry point
    // Note: this does _not_ add the `HotModuleReplacementPlugin` like the CLI option does.
    // Note: after test has verified: if not add hot: true here, HMR also work
    hot: true,
    // WebpackDevServer() API NO inline option
    // inline: true,
    // Set this as true if you want to access dev server from arbitrary url.
    // This is handy if you are using a html5 router.
    historyApiFallback: true,
    // proxy: {
    //   “*” : `http://localhost:${wdsListenPort}` // <– Proxy everthing!
    // }
}).listen(wdsListenPort, ‘localhost’, function (err, result) {
    if (err) {
        console.log(err);
    }
      console.log(`WDS Listening at localhost:${wdsListenPort}`);
});

解释:

(1)代码整体逻辑

上半段是设置app的代码,包括端口号8000

下半段时设置WDS=WebpackDevServer的,对应端口号是3000

其中的:

var config = require(‘./webpack.config’);
// add HMR module into entry point
config.entry.vendors.unshift(`webpack/hot/dev-server`);
// add inline mode module into entry point
config.entry.vendors.unshift(`webpack-dev-server/client?http://localhost:${wdsListenPort}/`);

(2)含义:

通过webpack/hot/dev-server去添加HMR的,实现热更新的

通过webpack-dev-server/client?http://localhost:3000,实现inline模式的

(3)上面这两句,其实可以写成一句:

config.entry.vendors.unshift(`webpack/hot/dev-server`, `webpack-dev-server/client?http://localhost:${wdsListenPort}/`);

且这两个配置等价于:

ReactJS-AdminLTE/webpack.config.js

中的:

    entry: {
        dashboardV1: ‘./src/pages/dashboardV1/js/dashboard’,
。。。
        vendors: [
            // ‘webpack/hot/dev-server’,
            // ‘webpack-dev-server/client?http://localhost:3000/’,
            ‘react’,
            ‘react-dom’,
            。。。
        ],
        chartVendors: [‘jquery’, ‘raphael’,。。。],
    },

其中:

entry下面的是各个入口,表示要输入的文件,用于转换后输出到output的path。

entry中的webpack/hot/dev-server和webpack-dev-server/client?http://localhost:3000/和上面的WDS的API代码中的写法,效果是一样的。

(4)HotModuleReplacementPlugin

// add HMR plugin
let hmrModule = new webpack.HotModuleReplacementPlugin();
config.plugins.unshift(hmrModule); // add to list first

这部分是通过代码方式去添加HotModuleReplacementPlugin

其实等价于:

ReactJS-AdminLTE/webpack.config.js

中的:

    plugins: [
        new webpack.HotModuleReplacementPlugin(),
    ],

两种写法都可以,效果一样。

ReactJS-AdminLTE/webpack.config.js

。。。
var webpack = require(‘webpack’);
var UglifyJsPlugin = webpack.optimize.UglifyJsPlugin;
var path = require(“path”);
。。。
var config = {
    resolve: {
        。。。
    plugins: [
        // new webpack.HotModuleReplacementPlugin(), // moved this in server.js
       。。。
        new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/) // to not to load all locales
    ],
    devtool: ‘cheap-module-source-map’,
    entry: {
        dashboardV1: ‘./src/pages/dashboardV1/js/dashboard’,
        。。。
        vendors: [
            // ‘webpack/hot/dev-server’,
            // ‘webpack-dev-server/client?http://localhost:3000/’,
            ‘react’,
            ‘react-dom’,
            ‘jquery’,
            。。。
        ],
        chartVendors: [‘jquery’, ‘raphael’, 。。。],
    },
    output: {
        path: path.join(__dirname, “public”),
        // path: path.resolve(__dirname, “public”),
        filename: “dist/js/[name].bundle.js”,
        libraryTarget: “umd”,
        umdNamedDefine: true,
    },
    module: {
        。。。
        loaders: [
            {
                test: /\.jsx?$/,
                loaders: [‘react-hot’],
                include: path.join(__dirname, ‘public’),
                exclude: /(node_modules|bower_components)/
            },
            。。。
        ]
    }
    // devServer: {
    //     hot: true,
    //     inline: true
    // }
};
module.exports = config;
。。。

说明:

(1)此处没有用到devServer的配置,而且据说对于此处用server.js中WDS的API的写法的话,devServer即使设置了也不起效果。

(2)如前所述,entry中的webpack/hot/dev-server和webpack-dev-server/client?http://localhost:3000/和代码中的:

var config = require(‘./webpack.config’);
// add HMR module into entry point
config.entry.vendors.unshift(`webpack/hot/dev-server`);
// add inline mode module into entry point
config.entry.vendors.unshift(`webpack-dev-server/client?http://localhost:${wdsListenPort}/`);

是一样的。

(3)如前所述,plugins中的new webpack.HotModuleReplacementPlugin(),和代码中的:

let hmrModule = new webpack.HotModuleReplacementPlugin();
config.plugins.unshift(hmrModule); // add to list first

效果是一样的。

/ReactJS-AdminLTE/views/dashboard.html

    <!– AdminLTE App –>
    <script src=”https://code.jquery.com/jquery-3.1.1.min.js” integrity=”sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=” crossorigin=”anonymous”></script>
    <!– <script src=”dist/js/app.js”></script> –>
    <!– <script src=”dist/js/pages/dashboard.js”></script>
    <script src=”dist/js/demo.js”></script> –>
        <!– <script src=”/dist/js/vendors.js”></script>
        <script src=”/dist/js/chartVendors.bundle.js”></script>
        <script src=”/dist/js/dashboardV1.bundle.js”></script> –>
    
     <!–Use this only in development, while using React Hot Loader –>
        <!– <script src=”http://localhost:3000/dist/js/app.js”></script> –>
        <!– Note here 3000 is WDS port, not app port !!! –>
        <script src=”http://localhost:3000/dist/js/vendors.js”></script>      
        <script src=”http://localhost:3000/dist/js/chartVendors.bundle.js”></script>
        <script src=”http://localhost:3000/dist/js/dashboardV1.bundle.js”></script>
         <!– <script src=”http://localhost:3000/webpack-dev-server.js”></script> –>
    </body>
</html>

说明:

(1)此处是使用了development开发模式+HMR,所以注释掉了之前的代码:

        <!– <script src=”/dist/js/vendors.js”></script>
        <script src=”/dist/js/chartVendors.bundle.js”></script>
        <script src=”/dist/js/dashboardV1.bundle.js”></script> –>

和:

        <!– <script src=”http://localhost:3000/dist/js/app.js”></script> –>

否则浏览器的console中会报错找不到dist/js/app.js

然后加上WDS(端口3000)的地址:

        <script src=”http://localhost:3000/dist/js/vendors.js”></script>      
        <script src=”http://localhost:3000/dist/js/chartVendors.bundle.js”></script>
        <script src=”http://localhost:3000/dist/js/dashboardV1.bundle.js”></script>

且这几个文件:

dist/js/vendors.js

dist/js/chartVendors.bundle.js

dist/js/dashboardV1.bundle.js

对应着:

ReactJS-AdminLTE/webpack.config.js中的entry中的:vendors,chartVendors,dashboardV1

(2)webpack-dev-server.js

此处的:

        <script src=”http://localhost:3000/webpack-dev-server.js”></script>

的写法是和

/ReactJS-AdminLTE/server.js

中的:

config.entry.vendors.unshift(`webpack-dev-server/client?http://localhost:${wdsListenPort}/`);

是等价的。

同理和:

ReactJS-AdminLTE/webpack.config.js

中的:

entry的vendors中的’webpack-dev-server/client?http://localhost:3000/’

    entry: {
 。。。
        vendors: [
            ‘webpack-dev-server/client?http://localhost:3000/’,

是等价的。

【后记】

后来参考:

webpack-hmr-starter-dev-server-api/webpack.config.js at master · ahfarmer/webpack-hmr-starter-dev-server-api

webpack-hmr-starter-dev-server-api/server.js at master · ahfarmer/webpack-hmr-starter-dev-server-api

-》

webpack dev server · webpack/docs Wiki

去设置:

ReactJS-AdminLTE/server.js

new WebpackDevServer(compiler, {
    stats: {
        colors: true,
    }

然后效果是:

Mac的Terminal中,显示的内容是彩色的:

正常内容是白色的,输出文件是绿色的,警告是黄色的:

也知道了:

对于WebpackDevServer的API的所有参数,都可以去:

webpack dev server · webpack/docs Wiki

找到具体的解释,和看看到底支持哪些参数。

转载请注明:在路上 » 【已解决】ReactJS-AdminLTE中的webpack-dev-server的HMR热更新不生效

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
92 queries in 0.187 seconds, using 23.46MB memory