前端必备技能 webpack - 7. webpack开发模式devServer
每篇文章纯属个人经验观点,如有错误疏漏欢迎指正。转载请附带作者信息及出处。
点这里查看 webpack 系列文章目录
博客中的代码位于 码云Git仓库,如有需要可自行前往下载。
前端必备技能 webpack - 7. webpack开发模式devServer
我们在前面已经对 devServer
进行了一个简单的介绍,主要是因为每次更改代码都需要借助 webpack
重新打包才能预览效果,所以我们需要建立一个开发环境,使我们的开发变得更容易一些。
devServer 的主要作用:
- 搭建一个简单的开发环境,提供服务器预览方式而不是使用本地文件预览;
- 监听代码的变化并自动刷新网页,提供实时预览;
- 提供
Source Map
,以便于开发人员进行调试;
一、相关概念
监听模式
webpack
在启动时可以选择开启监听模式,开启监听模式后会监听本地文件的变化,发生变化时会自动重新进行编译。
监听模式默认是关闭的,要开启监听模式,需要在启动时带上 --watch
。
实时预览
通过 devServer
启动时, webpack
会开启监听模式,当监听的文件发生变化时,会在重新构建后通知 devServer
。 devServer
会在构建出的代码里注入一个代理客户端用于控制网页。
网页和 devServer
之间通过 webSocket
协议通信, 以方便 devServer
在收到来自 webpack
的文件变化时主动向客户端发送命令,通知时通过注入的客户端控制网页刷新。
热替换
除了通过重新刷新整个网页来实现实时预览,devServer
还有一种被称作模块热替换的刷新技术。 模块热替换能做到在不重新加载整个网页的情况下,通过将被更新过的模块替换老的模块,再重新执行一次来实现实时预览。 模块热替换相对于默认的刷新机制能提供更快的响应和更好的开发体验。
模块热替换默认是关闭的,要开启模块热替换,需要在启动时带上 --hot
。
Source Map
在浏览器中运行的 js
代码都是经过 webpack
编译后的代码,这些代码的可读性很差。但 webpack
支持生成 Source Map
以便于映射代码,从而在源代码上进行断点调试。
需要在启动时带上 --devtool source-map
,此时就可在 Sources
选项卡中看到可调试的源代码了。
inline 和 iframe 模式
inline
模式:devServer
会在构建完变化后的代码时通过代理客户端控制网页刷新;iframe
模式:devServer
无法直接控制要开发的网页,这时它会通过iframe
的方式去运行要开发的网页,当构建完变化后的代码时通过刷新iframe
来实现实时预览;
二、使用 devServer
首先为我们的项目添加依赖,安装 DevServer
:
npm i webpack-dev-server -D
我们先为 devServer
添加一些基本配置来保证项目可以正常运行即可:
devServer 的启动命令:
npx webpack-dev-server
输入命令后,命令框会提示我们一些相关信息,需要注意,打包后至少需要有一个 html
文件用于提供预览,且 devServer
默认打开 output
目录下的 index.html
,如果输出的文件不是 index.html
,需要手动修改路径进行访问。
devServer
启动后会一直持续运行下去,这时候在我们对项目进行修改时,devServer
都会在内存中帮我们实时编译,将预览效果自动显示在浏览器中。
我们新建一个 index.css
文件,写入一些样式:
body{
background: #006cb7;
}
h1{
color: #fff;
}
之后将其引入到 index.js
中,保存之后我们发现命令行自动进行了编译,并且无须我们手动刷新,浏览器直接就显示最新的效果:
但需要注意的是,必须是与入口文件有关的文件,才会参与编译。假设新建了一个入口文件,需要重新编写 webpack
的相关配置,重新运行 devServer
。
这是因为 webpack
在启动时会以配置里的 entry
为入口去递归解析出相关的依赖文件,只有 entry
本身和相关的依赖文件才会被添加到监听列表里。
三、相关配置
这里按照我们在工作中使用的频率将相关配置分为三类:
常用配置项:
-
compress: { Boolean }
:是否启动gzip
压缩;gzip
压缩可以让代码体积更小 运行速度更快。 -
contentBase: { Boolean | String | Array }
:设置额外的本地静态文件的绝对目录;默认情况下为当前目录,即项目根目录,除非需要额外的本地文件,否则无须设置。
// 禁用 contentBase: false, // 设置额外暴露的本地文件目录 contentBase: path