用express搭建过一个小型的服务器,用过监听模式来解决手动npm run build的麻烦,这次使用webpack-dev-server
来搭建一个服务器,且一并解决“手动编译、手动刷新浏览器”的麻烦。
小试牛刀
代码目录
详细代码
- index.html
<html>
<body>
<div id="root"></div>
</body>
</html>
- index.js
import {add,sub,mul,div} from "./math.js";
var sum = add(1,2);
var diff = sub(2,1);
var product = mul(1,2);
var quotient = div(2,1);
document.querySelector("#root").textContent = [sum,diff,product,quotient].join("||");
- math.js
const add = (x,y) => x+y;
const sub = (x,y) => x-y;
const mul = (x,y) => x*y;
const div = (x,y) => x/y;
export {
add,
sub,
mul,
div
}
- webpack.config.js
const path = require("path");
const {CleanWebpackPlugin} = require("clean-webpack-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode:"development",
devtool:"cheap-source-map",
entry:"./index.js",
devServer:{
contentBase:path.join(__dirname,'dist'),
port:3030
},
output:{
filename:"bundle.js",
path:path.resolve(__dirname,"dist")
},
plugins:[
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template:"./index.html",
title:"test"
})
]
}
- package.json
{
"scripts": {
"build": "webpack --config webpack.config.js",
"start": "webpack-dev-server --config webpack.config.js"
},
"devDependencies": {
"clean-webpack-plugin": "^3.0.0",
"html-webpack-plugin": "^4.3.0",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.11.0"
}
}
测试
npm run start
浏览器地址栏输入localhost:3030
,结果如下:
修改index.js
或math.js
后保存,会自动重新编译,且自动重新加载整个页面。
参数及说明
open
是否打开浏览器。true
则打开,false
则不打开,默认是false
。port
服务器监听的端口contentBase
contentBase:path.join(__dirname,'dist')
,将/dist
目录下的文件托管为静态文件。
编译得到的结果(bundle.js、bundle.js.map和index.html)在devServer上,本地没有,本地/dist目录是空的
也可以托管多个目录,用数组就行,比如:
contentBase:[path.join(__dirname,'dist'),path.join(__dirname,'imgs')],
hot
true
则启用模块热替换,false
则关闭。
在配置文件中实现
devServer:{
open:true,
contentBase:path.join(__dirname,'dist'),
port:3030,
hot:true
}
在命令行中实现
webpack-dev-server --open --config webpack.config.js
webpack-dev-server --port 3030 --config webpack.config.js
webpack-dev-server --content-base /dist --config webpack.config.js
webpack-dev-server --hot --config webpack.config.js
模块热替换
程序运行过程中直接用 新模块 替换 老模块,而不是 重新加载整个页面。
//package.json
devServer:{
contentBase:path.join(__dirname,'dist'),
port:3030,
hot:true
}
添加hot:true
,执行npm run start
。
浏览器告诉我们,启用了Live Reloading
(实时重新加载整个页面),也启用了Hot Module Replacement
(模块热替换)。
WDS,即webpack-dev-server
第一次尝试
给math.js
添加console.log("hello world")
并保存,自动编译了并实时重新加载了整个页面,没见着 热模块替换。
第二次尝试
- 首先,给
index.js
添加如下代码。
index.js
中引入了math.js
,我们就称index.js
依赖math.js
。
一旦math.js
的内容有变更,index.js
就会得到通知:“嘿~,你依赖的模块math.js发生变化了”。这时,index.js
有两个选择:
要么接受math.js
的变化,即这时就会 模块热加载;
要么拒绝math.js
的变化,这时就会 实时重新加载整个页面,默认拒绝。
module.hot.accept("./math.js",callback)
就是选择了 接受;
module.hot.decline("./math.js")
就显式拒绝了。
//index.js
if(module.hot){
module.hot.accept("./math.js",function(){
console.log("accept modified math.js");
})
}
- 然后,才给
math.js
添加console.log("hello world")
并保存。
这次,自动编译了,没有实时重新加载整个页面,而是 热模块替换 了。
哦,原来要实现 模块热替换,光hot:true
还不够,模块 还要调用module.hot.accept(dep,callback)
来 接受 它所依赖的模块的变化。
第三次尝试
上面,我们看到了 js模块 是怎么实现 模块热替换的。这次我们来看看 css模块。
添加index.css
,并在index.js
中引入index.css
,当然webpack.config.js
里还得用上style-loader
、css-loader
。
//index.css
body{
color:red;
}
//index.js
import "./index.css";
//package.json
module:{
rules:[
{
test:/\.css$/,
use:["style-loader","css-loader"]
}
]
}
是,index.js
中没有module.hot.accept("./index.css,callback)
,但style-loader
里有。