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, // [email protected]
						disable: true,       // [email protected] 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, // [email protected]
						disable: true,       // [email protected] 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 !

ssl

修改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

webpack4.x 教程

webpack 准备工作(1) webpack 手写最基本的配置(2) webpack 打包样式(3) webpack 让打包更便捷(4) webpack 打包图片(5) webpack iconfont打包(6) webpack devServer本地开发(7) webpack 处理ES6语法(8) webpack SourceMap配置(9) webpack Tree Shaking(10) webpack js代码分割(11) webpack 懒加载(12) webpack 打包分析,Preloading,Prefetching(13) webpack 模块化区分开发和生产(14) webpack 样式文件的代码分割(15) webpack 浏览器缓存(16) webpack shimming(17) webpack 环境变量(18) webpack Esline(19)