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的功能哦!
网友评论