美文网首页
webpack学习三(HMR)

webpack学习三(HMR)

作者: 梦行乌托邦 | 来源:发表于2020-07-11 17:24 被阅读0次

webpack-dev-server
安装

npm i webpack-dev-server -D

在package.json中新增配置:

"scripts": {
    "test": "webpack",
    "dev": "webpack --config webpack.dev.config.js",
    "server": "webpack-dev-server"
  },

在webpack.config.js中新增配置

...

module.exports = {
    ...
    devServer: {
        contentBase: './dist',
        open: true,
        port: 8081
    }
};

执行命令

npm run server

会自动在浏览器打开一个窗口url是:http://localhost:8081
你可以修改成http://localhost:8081/happy.html这样就能看到你自己的页面了。

现在你修改代码后,可以看到浏览器会自动刷新。你不需要再重新执行命令打包 --这便是webpack-dev-server的魔力

启动服务后,会发现dist目录没有了,这是因为devServer没有把打包后的模块放在dist⽬录下,⽽是放到内存中,从⽽提升速度

本地mock,解决跨域
联调期间,前后端分离,直接获取数据会跨域,上线后我们使用nginx转发,开发期间,webpack就可以搞定这件事

启动一个服务器,mock一个接口
安装

npm i express -D

项目根目录下创建一个server.js

const express = require('express')
const app = express()
app.get('/api/info', (req,res)=>{
    res.json({
        name:'开心吗',
        age:16, 
        msg:'欢迎来到开心不花钱世界'
    }) 
})
app.listen('9092')

执行命令

node server.js

在浏览器打开http://localhost:9092/api/info
接口内容正常获取
安装

npm i axios -D

修改/src/index.js

import axios from 'axios'
axios.get('http://localhost:9092/api/info').then(res=>{
    console.log(res)
})

执行 npm run server(这里注意不要把刚才开的node服务关了,开两个终端)


img1

报错,有跨域问题
怎么解决?
在webpack.config.js中增加服务器代理

...
module.exports = {
    ...
    devServer: {
        ...
        proxy: { // 设置服务器代理
            '/api': {
                target: 'http://localhost:9092'
            }
        }
    }
};

修改/src/index.js中的
http://localhost:9092/api/info
改为
'/api/info'
再启动服务,接口内容在控制台正常打出,解决跨域问题。

Hot Module Replacement

热模块替换

启动
webpack.config.js中新增配置

...
 const webpack = require('webpack');

module.exports = {
    ...
    plugins: [ // 插件,作用于webpack构建的整个生命周期
        ...
        new webpack.HotModuleReplacementPlugin()
    ],
    ...
    devServer: {
        ...
        hot:true, 
        hotOnly:true //即便HMR不生效,浏览器也不自动刷新
    }
};

修改/src/index.css

div:nth-of-type(odd) {
  background: black;
}

修改/src/index.js

import('./index.css');

var btn = document.createElement('button');
btn.innerHTML = '新增';
document.body.appendChild(btn);

btn.onclick = function(){
    var div = document.createElement('div');
    div.innerHTML = 'item';
    document.body.appendChild(div);
};

执行 npm run server ,打开浏览器查看页面,点击按钮“新增”,偶数项的div背景色是黑色的,我们现在想改成红色,于是去修改index.css,改完之后发现浏览器没有刷新,但是刚才黑色背景的div现在变成红色了,这就是HMR的魔力!

HMR,其本质是模块刷新,而不是整页刷新
注意,HMR支持style-loader,但是不支持抽离成独立文件的方式(mini-css-extract-plugin)

我们再来试试修改index.js。将“新增”修改成“新增div”,改完之后发现浏览器没变?
在src目录下新增counter.js

function counter(){
    var div = document.createElement('div');
    div.setAttribute('id', 'counter');
    div.innerHTML = 1;
    div.onclick = function(){
        div.innerHTML = parseInt(div.innerHTML, 10) + 1;
    };
    document.body.appendChild(div);
}
export default counter;

在src目录下新增number.js

function number(){
    var div = document.createElement('div');
    div.setAttribute('id', 'number');
    div.innerHTML = 200;
    document.body.appendChild(div);
}
export default number;

修改/src/index.js

import counter from './counter.js';
import number from './number.js';
counter();
number();

重启服务,浏览器显示

1
200

修改number.js中的200为400,浏览器没反应,还是和上面一样,js的修改不触发HMR

js模块 HMR 需要手动监听需要HMR的模块,当该模块内容发生改变,会触发回调

在index.js中增加

if(module.hot){
    module.hot.accept(['./number.js'], () => {
        console.log('这个模块改变了');
        document.body.removeChild(document.getElementById('number'));
        number();
    });
}

现在重启服务,再去修改number.js中的数字,浏览器就会马上更新了。
你肯定会说,这样来实现热更新太麻烦了吧!确实,原生js需要手动来处理代价太大,不过现在一般用框架vue或react,它们俩的loader都内置HMR的功能哦!

相关文章

网友评论

      本文标题:webpack学习三(HMR)

      本文链接:https://www.haomeiwen.com/subject/mdgbcktx.html