# Webpack的webpack-dev-server运行原理分析
文章来源WecTeam (opens new window)
webpack-dev-server 可以看作一个服务者,它的主要工作就是接收浏览器的请求,然后将资源返回。当服务启动时,它会先让 Webpack 进行模块打包并将资源准备好。当 webpack-dev-server 接收到浏览器的资源请求时,它会首先进行 URL 地址校验。如果该地址是资源服务地址,webpack-dev-server 就会从 Webpack 的打包结果中寻找该资源并返回给浏览器。反之,如果请求地址不属于资源服务地址,则直接读取硬盘中的源文件并将其返回。
综上我们可以总结出 webpack-dev-server 的两大职能。
- 令
Webpack进行模块打包,并处理打包结果的资源请求。 - 作为普通的
Web Server,处理静态资源文件请求。
webpack将我们的项目源代码进行编译打包成可分发上线的静态资源,在开发阶段我们想要预览页面效果的话就需要启动一个服务器伺服webpack编译出来的静态资源。webpack-dev-server就是用来启动webpack编译、伺服这些静态资源。除此之外,它还默认提供了liveReload的功能,就是在一次webpack编译完成后浏览器端就能自动刷新页面读取最新的编译后资源。为了提升开发体验和效率,它还提供了hot选项开启hotReload,相对于liveReload,hotReload不刷新整个页面,只更新被更改过的模块。
# 入口
作为命令行启动,webpack-dev-server/bin/webpack-dev-server.js就是整个命令行的入口。
// webpack-dev-server/bin/webpack-dev-server.js
function startDevServer(config, options) {
let compiler;
try {
// 2. 调用webpack函数返回的是 webpack compiler 实例
compiler = webpack(config);
} catch (err) {
}
try {
// 3. 实例化 webpack-dev-server
server = new Server(compiler, options, log);
} catch (err) {
}
if (options.socket) {
} else {
// 4. 调用 server 实例的 listen 方法
server.listen(options.port, options.host, (err) => {
if (err) {
throw err;
}
});
}
}
// 1. 对参数进行处理后启动
processOptions(config, argv, (config, options) => {
startDevServer(config, options);
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
TIP
webpack-dev-server 作为命令行启动,首先是调用了 webpack-cli 模块下的两个文件,分别配置了命令行提示选项、和从命令行和配置文件收集了 webpack 的 config,这样复用了webpack-cli 的代码,保持行为一致,上面贴出来的代码省略了这部分代码,有兴趣的可以自己翻阅源码。
之后调用 processOptions 对收集的参数进行一些默认处理后得到需要传给 webpack 的 config 和需要传给 webpack-dev-server 的 options。传入这两个配置参数调用 startDevServer,startDevServer 这个函数主要是先调用 webpack 函数实例化了 compiler,注意这里没有给 webpack 函数传入回调函数,根据 webpack 源码实现,不传入回调函数就不会直接运行 webpack 而是返回 webpack compiler 的实例,供调用方自行启动 webpack 运行。拿到 webpack compiler 实例和先前的 webpack-dev-server 的 options 就去实例化 Server,这个 Server 类就是实现webpack-dev-server 的核心逻辑。
最后调用 Server 类的 listen 方法,就正式开启监听请求,listen 方法后面会再解析具体逻辑。这就是webpack-dev-server大致的启动过程,后面来看下 Server 类具体做了什么。
网页和
webpack-dev-server是通过websocket协议互联的。当监听到文件变化的时候,会通过websocket通知网页调用reload接口刷新页面。
← plugin 原理 webpack模块联邦 →