获取全套webpack 4.x教程,请访问瓦力博客
webpack-dev-server是一个用来快速搭建本地运行环境的工具。在实际开发中调试接口需要打http请求,我们用之前的方式本地直接打开html文件是不行的,本地直接打开html文件,在浏览器中显示的协议是file协议不是http协议。
使用devServer的好处:
- 自动打开浏览器页面
- 调试接口
- 实时刷新
- 热更新
- 使用代理
- 局域网访问
1.安装插件
yarn add webpack-dev-server
2.devServer配置
package.json
{
"scripts": {
"dev": "npx webpack-dev-server --mode=development --colors",
"dist": "npx webpack --mode=production"
}
}
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin'); //生成html文件
const CleanWebpackPlugin = require('clean-webpack-plugin'); //清除
module.exports = {
mode:'development',
entry:'./src/index.js',
module:{
rules:[
{
test:/\.css$/,
use:[
'style-loader',
{
loader:'css-loader',
options:{
importLoaders:1
}
},
'postcss-loader'
]
},
{
test:/\.scss$/,
use:[
'style-loader',
{
loader:'css-loader',
options:{
importLoaders:2
}
},
'sass-loader',
'postcss-loader'
]
},
{
test: /\.less$/,
use: [
'style-loader',
{
loader:'css-loader',
options:{
importLoaders:2
}
},
'less-loader',
'postcss-loader'
]
},
{
test:/\.(png|svg|jpeg|jpg|gif)$/,
use:[
{
loader:'file-loader',
options:{
name:'[name].[ext]', //[path] 上下文环境路径
publicPath:'./assets/image/', //公共路径
outputPath:'assets/image/', //输出路径
}
},
{
loader: 'image-webpack-loader',
options: {
bypassOnDebug: true, // webpack@1.x
disable: true, // webpack@2.x and newer
},
},
]
},
{
test: /\.html$/,
use:[
{
loader:'html-loader',
options:{
arrts:['img:src','img:data-src'],
minimize:false //是否压缩html
}
}
]
},
{
test: /(iconfont.svg)|\.(woff|woff2|eot|ttf|otf)$/,
use:[
{
loader:'file-loader',
options:{
name:'[name].[ext]', //[path] 上下文环境路径
publicPath:'./assets/iconfont/', //公共路径
outputPath:'assets/iconfont/', //输出路径
}
}
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
title: '瓦力博客',
template: './src/index.html' //以src/index.html为编译模板
}),
new CleanWebpackPlugin()
],
+ devServer:{
+ contentBase: path.join(__dirname, 'dist'),
+ clientLogLevel: 'info',
+ open:true, //启动时默认打开浏览器
+ host:'localhost', //域名 0.0.0.0局域网可访问
+ port:'9009',
+ inline:true, //实时更新
+ proxy:{
+ '/':{
+ target:'http://www.waliblog.com'
+ },
+ '/upload':{
+ target:'http://www.waliblog.com'
+ }
+ }
+ },
output:{
path: path.resolve(__dirname,'dist')
}
}
运行webpack
yarn run dev
3.使用代理
proxy:{
'/':{
target:'http://www.waliblog.com'
},
'/upload':{
target:'http://www.baidu.com'
}
}
小菜这里想提到一点就是proxy可以根据匹配路径来设置不同的host。举个例子,小菜要上传一个文件到服务器,请求的url是http://www.yagm.com/upload
,如果配置代理,请求的url就会变成http://www.baidu.com/upload
。proxy会匹配到/uploade
这个路径,将host替换成target的值。
4.设置局域网访问
不知道大家有没有遇到过这种需求,当你开发完一个功能时,其他人想先在自己电脑上浏览一下,但是你还没有更新部署。如果在局域网内,可以设置host
这个属性。将上面配置的host:'localhost'
修改为host:'0.0.0.0'
然后重启webpack。在浏览器上访问需要输入IP地址加端口号。例如小菜的电脑在局域网的IP:192.168.3.21,那么其他人访问页面的url:‘http://192.168.3.21:9009’。9009
端口号是小菜在上面配置自己设置的,大家要替换成自己设置的端口号。
5.热模块替换
webpack.config.js
const path = require('path');
+ const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin'); //生成html文件
const CleanWebpackPlugin = require('clean-webpack-plugin'); //清除
module.exports = {
mode:'development',
entry:'./src/index.js',
module:{
rules:[
{
test:/\.css$/,
use:[
'style-loader',
{
loader:'css-loader',
options:{
importLoaders:1
}
},
'postcss-loader'
]
},
{
test:/\.scss$/,
use:[
'style-loader',
{
loader:'css-loader',
options:{
importLoaders:2
}
},
'sass-loader',
'postcss-loader'
]
},
{
test: /\.less$/,
use: [
'style-loader',
{
loader:'css-loader',
options:{
importLoaders:2
}
},
'less-loader',
'postcss-loader'
]
},
{
test:/\.(png|svg|jpeg|jpg|gif)$/,
use:[
{
loader:'file-loader',
options:{
name:'[name].[ext]', //[path] 上下文环境路径
publicPath:'./assets/image/', //公共路径
outputPath:'assets/image/', //输出路径
}
},
{
loader: 'image-webpack-loader',
options: {
bypassOnDebug: true, // webpack@1.x
disable: true, // webpack@2.x and newer
},
},
]
},
{
test: /\.html$/,
use:[
{
loader:'html-loader',
options:{
arrts:['img:src','img:data-src'],
minimize:false //是否压缩html
}
}
]
},
{
test: /(iconfont.svg)|\.(woff|woff2|eot|ttf|otf)$/,
use:[
{
loader:'file-loader',
options:{
name:'[name].[ext]', //[path] 上下文环境路径
publicPath:'./assets/iconfont/', //公共路径
outputPath:'assets/iconfont/', //输出路径
}
}
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
title: '瓦力博客',
template: './src/index.html' //以src/index.html为编译模板
}),
new CleanWebpackPlugin(),
+ new webpack.HotModuleReplacementPlugin()
],
devServer:{
contentBase: path.join(__dirname, 'dist'),
clientLogLevel: 'info',
open:true, //启动时默认打开浏览器
host:'localhost', //域名 0.0.0.0局域网可访问
port:'9009',
inline:true, //实时更新
+ hot:true, //热替换
+ hotOnly:true,
proxy:{
'/':{
target:'http://www.waliblog.com'
},
'/upload':{
target:'http://www.waliblog.com'
}
}
},
output:{
path: path.resolve(__dirname,'dist')
}
}
src/assets/css/index.css
h1{
color: red;
}
src/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>title</title>
</head>
<body>
<h1>欢迎来到瓦力博客</h1>
</body>
</html>
src/index.js
import "./assets/css/index.css"
运行webpack
yarn run dev
webpack启起来后,我们修改样式将字体颜色变成蓝色
h1{
color: blue;
}
这个时候浏览器中欢迎来到瓦力博客
字体也会变蓝,这里值得注意的是浏览器并未刷新,只是将样式替换而已。这个热替换对样式有用,但是对js脚本就没有用了。接下来我们做个演示
文件结构
myProject
|-dist
|-node_modules
|-src
|-assets
|-css
|-index.css
|-less
|-index.less
|-sass
|-index.scss
|-images
|-wali_logo.png
|-iconfont
|-demo.css
|-demo_index.html
|-iconfont.css
|-iconfont.eot
|-iconfont.js
|-iconfont.svg
|-iconfont.ttf
|-iconfont.woff
|-iconfont.woff2
|-index.html
|-index.js
+ |-print.js
|-package.json
|-webpack.config.js
|-postcss.config.js
src/index.js
import printMe from './print.js';
function component() {
var element = document.createElement('div');
var btn = document.createElement('button');
element.innerHTML = 'hello webpapck';
btn.innerHTML = 'Click me and check the console!';
btn.onclick = printMe;
element.appendChild(btn);
return element;
}
document.body.appendChild(component());
上面代码什么作用呢?创建一个div标签,创建一个按钮,在div标签里填充hello webpapck
。按钮上的文案改为Click me and check the console!
,给按钮绑定一个点击事件,将按钮放在div标签里,将div元素返回出去。最后将div元素挂在body元素里。
src/print.js
export default function printMe() {
console.log('hello !');
}
导出一个函数,这个函数的功能是在控制台输出一句hello !
启动webpack
yarn run dev
启动起来,打开控制台,在浏览器中点击按钮,控制台会输出hello !
修改src/print.js
export default function printMe() {
+ console.log('欢迎来到瓦力博客');
}
保存后,这个时候不要刷新浏览器,继续点击按钮,此刻控制台输出的依然是hello !
而不是我们想要的欢迎来到瓦力博客
。
修改src/index.js
import printMe from './print.js';
function component() {
var element = document.createElement('div');
var btn = document.createElement('button');
element.innerHTML = 'hello webpapck';
btn.innerHTML = 'Click me and check the console!';
btn.onclick = printMe;
element.appendChild(btn);
return element;
}
document.body.appendChild(component());
+if (module.hot) {
+ module.hot.accept('./print.js', function() {
+ var btn = document.querySelector('button');
+ btn.onclick = printMe;
+
+ })
+}
保存后刷新浏览器,然后点击按钮。看到控制台输出欢迎来到瓦力博客
这个时候我们回过头将print.js的内容重新修改为
export default function printMe() {
+ console.log('hello !');
}
保存后不要刷新浏览器,在点击按钮,这个时候控制就会输出hello !
。我们来看看在index.js中添加的代码作用,当开启了热替换后,我们手动监听print.js
文件如果发生更改,在回调中更新按钮的点击事件。小菜举这个例子是想说明,当我们在devServer中开启热替换,只有样式会被热替换,js文件不会被热替换,想要js也被热替换需要手动编写代码。事实上,样式文件也不会被热替换,而是开发人员在代码中帮我们做了这个功能,我们才不需要去写。
演示完毕后我们删除print.js文件
myProject
- |-print.js