16

本文主要介绍以下两方面的内容:

  1. webpack-dev-server自动刷新

  2. 热加载(Hot Module Replacement

自动刷新

webpack-dev-server提供了两种自动刷新的模式

  1. iframe模式

  2. inline模式

这两种模式都支持Hot Module Replacement(热加载),所谓热加载是指当文件发生变化后,内存中的bundle文件会收到通知,同时更新页面中变化的部分,而非重新加载整个页面。

我们先介绍自动刷新,再来谈热加载。

iframe模式

前两篇文章中提到,我们在控制台输入

$ webpack-dev-server

就启动了服务,并且支持自动刷新,其实,这种方式就是iframe模式。查看页面元素可以发现:

clipboard.png

如图中黑框所示,可以看到其实是通过iframe内使我们实际的页面。
这种方式有一点需要注意:浏览器地址栏的url地址不会受页面跳转的影响,将一直保持为http://localhost:8080/webpack-dev-server
比如,现在给index.html页面加上一个跳转链接,跳转到foo.html
foo.html

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>webpack demo</title>
    </head>
    <body>
        <p>this is another page</p>
    </body>
</html>

index.html中加入跳转链接如下:

<body>
    <div class="main" id="main">
        <p>webpack demo</p>
    </div>
    <a href="./foo.html">click here to go to foo.html</a>
</body>

当点击链接跳转到foo.html页面时,可以看到浏览器的地址栏中仍然是http://localhost:8080/webpack-dev-server。如下:

clipboard.png

inline模式

这里要说一下,目前我们启动webpack-dev-server都是通过命令行实现的。实际上,还可以通过nodeAPI WebpackDevServer实现。
先看命令行如何实现inline模式,有两种方法:
1、启动时配置

$ webpack-dev-server --inline

2、配置文件配置,在webpack.config.js中加入

devServer: { inline: true }

这样我们就可以通过http://localhost:8080/<path>来访问我们的文件了。比如这样http://localhost:8080/index.html来访问index.html,且页面跳转回反映在浏览器的地址栏中。

接下来说明如何使用WebpackDevServer来实现inline模式。
在项目根目录下创建server.js,通过这个文件来起服务。
server.js

var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');

var config = require('./webpack.config.js');
config.entry.unshift("webpack-dev-server/client?http://localhost:8080/");
var compiler = webpack(config);
var server = new WebpackDevServer(compiler, {
    publicPath: '/dist/'
});
server.listen(8080);

有几个问题需要说明:
1、这里加载了webpackwebpack-dev-server两个模块,这个require默认会从node-modules中去加载。由于我们之前安装时为了方便在命令行下使用,采用了全局安装的方式-g,所以本地并没有安装这个模块。这里需要在当前项目中再进行安装

$ npm install webpack webpack-dev-server

2、在配置文件webpack.config.js中无需再对devServer进行配置,因为我们这样启动服务的话,WebpackDevServer是访问不到webpack中的配置的。但是,我们需要对配置文件的entry进行修改:

entry: ["./src/entry.js"]

以数组方式来写,这样就可以支持多个入口文件。同时在server.js中加入

config.entry.unshift("webpack-dev-server/client?http://localhost:8080/");

3、WebpackDevServer支持两个参数,其中第二个参数对WebpackDevServer进行了配置,刚刚提到,WebpackDevServer是访问不到webpack中的配置的,所以这里我们要再设置publicPath
当然,为了方便处理,一般我们可以统一将WebpackDevServer的配置在webpack.config.js中的devServer中设置,再将devServer作为第二个参数传给WebpackDevServer。如下:
webpack.config.js

module.exports = {
    devServer: {  //这里配置webpack-dev-server
        publicPath: '/dist/'
        //这里还可以加入其它你需要的参数
    },
    entry: ["./src/entry.js"],
    output: {
        path: path.join( __dirname, '/dist'),
        publicPath: '/dist/',
        filename: "bundle.js"
    },
    module: {
        loaders: [
            //....
        ]
    }
};

server.js

var config = require('./webpack.config.js');
config.entry.unshift("webpack-dev-server/client?http://localhost:8080/");
var compiler = webpack(config);
var server = new WebpackDevServer(compiler, config.devServer);  //这里将其作为参数传进来

最后运行server.js就可以启动服务了。

$ node server.js

到这里为止,自动刷新的内容基本讲完了。注意到一点,目前自动刷新都是刷新整个页面。下面来说下热加载,也就是只有变化的内容更新,而非刷新整个页面。

Hot Module Replacement(热加载)

方法一:直接通过命令行设置

$ webpack-dev-server --hot

clipboard.png

打开页面可以在控制台看到以上内容,说明热加载配置成功。其中HMS表示热加载模块,WDS表示webpack-dev-server

方法二:通过nodejsapi配置
这个方法需要对webpack.config.js做出一些配置。
第一步:在webpack配置文件入口参数中加入webpack/hot/dev-server

server.js中作如下修改即可:

config.entry.unshift("webpack-dev-server/client?http://localhost:8080/", "webpack/hot/dev-server");  //这里在入口参数中又添加了一项,为热加载的dev-server

第二步:添加plugin,添加热加载模块

plugins: [
    new webpack.HotModuleReplacementPlugin()
]

第三步:在devServer中配置hottrue

devServer: {
    publicPath: '/dist/',
    hot: true  //这里配置了热加载模式为true
    //这里还可以加入其它你需要的参数
}

最终,webpack.config.js如下:

let path = require('path');
let webpack = require('webpack');

module.exports = {
    devServer: {
        publicPath: '/dist/',
        hot: true
        //这里还可以加入其它你需要的参数
    },
    entry: ["./src/entry.js"],
    output: {
        path: path.join( __dirname, '/dist'),
        publicPath: '/dist/',
        filename: "bundle.js"
    },
    module: {
        loaders: [
            {
                test: /\.css$/, 
                loader: "style!css"
            },
            {
                test: /\.less$/,
                loader: "style!css!less"
            },
            {
                test: /\.js$/,
                exclude: /node_modules/,
                loader: "babel-loader"
            }
        ]
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin()
    ]
};

server.js如下:

var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');

var config = require('./webpack.config.js');
config.entry.unshift("webpack-dev-server/client?http://localhost:8080/", "webpack/hot/dev-server");
var compiler = webpack(config);
var server = new WebpackDevServer(compiler, config.devServer);
server.listen(8080);

启动服务:

$ node server.js

可以看到配置成功,如下图所示:
clipboard.png

结语

至此,本文对webpack-dev-server的自动刷新和热加载做了详细介绍,当然,它的原理还有待更深一步的探索。后续我还会进行更深入的学习,希望和大家共同进步。

参考资料

http://webpack.github.io/docs...

(本文完)


bupthly
385 声望39 粉丝

竹杖芒鞋轻胜马,一蓑烟雨任平生