「这是我参与11月更文挑战的第26天,活动详情查看:2021最后一次更文挑战」
1. webpack-dev-server 的基本使用
上一小节我们讲了 webpack 的 watch 模式,你可能会觉得“哇~这个的话好舒服”,其实,我们还有更舒服的方式😁,即使用 webpack-dev-server 的方式,这也是我们开发中最常用的方式(其实,在 webpack3 及之前的版本中,我们会从这个 webpack-dev-server 开始启动 webpack,而现在有了 webpack-cli,我们就可以不从 webpack-dev-server 开始启动了。但都需要单独安装 webpack-dev-server)。
watch 模式确实可以监听文件的变化,但它并没有自动帮助我们刷新浏览器的功能,目前自动刷新浏览器页面是 VS Code 中的扩展 Live Server 帮助我们实现的功能,而不是使用的 webpack 自带的功能。如果我们希望在不使用 Live Server 这一扩展的情况下,实现 **live reloading(实时重新加载)**的功能(就是自动刷新浏览器页面),就可以通过 webpack 的 webpack-dev-server 实现。webpack-dev-server 可以给我们提供对应的开发时服务器,我们可以利用这个服务器开启一个本地服务,这样一来,我们就可以不使用 Live Server 了。下面,我们先来安装它(因为这个东西还是只在开发时使用的,所以我们使用 -D 标志):
npm install webpack-dev-server -D
安装完成后,我们
在真实的 Vue 或者 React 项目开发中,我们一般会有两个脚本:
npm run build:对当前项目中的代码进行打包;npm run serve或者npm run dev:用来开启一个本地服务,让我们进行本地的开发;
当前,在我们的项目中,package.json 文件中只设置了 npm run build 脚本,用来直接对当前的项目做打包。现在,我们再来添加一个脚本:
然后,我们运行 npm run serve 命令,就相当于执行了 npx webpack serve 命令,它会找到 devServer,来帮助我们启动一个本地服务器:
这里,webpack-cli 提示我们不需要将 serve 命令和 { watch: true } 配置一起使用,这没有意义。那么我们用了 webpack-dev-server 之后,就不需要再配置 watch: true 了,因为 serve 命令内部会帮我们监听文件的变化,当文件发生变化时,就会重新对当前项目的源代码进行编译。所以我们把 webpack.config.js 中的 watch 配置注释掉:
再来运行 npm run serve 命令:
这次,就没有刚才的提示了,而且,你会发现 webpack-dev-server 有打印出有关信息,告诉我们项目已经运行在了 http://localhost:8080/ 这个地址上,也就是说,webpack-dev-server 已经帮我们开启了本地服务。之后,编译源代码也成功了,成功之后就意味着我们现在可以访问这个 http://localhost:8080/ 地址了,我们可以直接在命令行终端中按住 Ctrl 键的同时点击这个地址在浏览器中打开它:
可以看到,我们现在访问的是 localhost:8080,这个东西就不是 Live Server 帮助我们开启的,而是当前 devServer 自动给我们搭建的一个本地服务器(它其实是基于 Node.js 的 express 框架搭建的本地服务器,我们现在访问 localhost:8080 这个地址时就会来到这个服务器中,找到我们刚才打包的那些静态资源,然后返回给浏览器,浏览器就能对这些静态资源做一个展示了)。
以上,就是 webpack-dev-server 最基本的使用方式。
下面要讲的是关于 webpack-dev-server 的一些细节:
-
当前,我们没有对
webpack-dev-server做任何配置,只是在脚本中添加了serve命令,到时候webpack-dev-server就会自动启动。那为什么它会自动启动呢?其实,webpack serve这一脚本在执行时还是会通过webpack-cli进行解析,然后发现有serve这一参数时,就会利用webpack-dev-server来帮助我们启动一个本地服务了。 -
如果我们启用了
webpack-dev-server,那么它是不会对src目录下的源代码进行打包之后生成目标代码文件的(这里即不会生成build文件夹,或者原来存在的build文件夹会被清空内容)。你可能会有疑问:没有输出打包之后的文件的话,我们待会访问的静态资源从哪来啊?其实,webpack-dev-server也是有对源代码进行编译和打包的,只不过它没有对编译打包后的代码做文件的输出(没有将代码写入文件),而是直接将编译打包后的代码放到了内存中,之后再通过express服务器去访问这些放到了内存中的代码(静态资源)。这时如果浏览器需要访问,就是直接从内存中读取对应的静态资源,然后再返回到浏览器中的。那它为什么不进行输出呢?做一个输出不是更干脆吗?因为是这样的,假如我们现在打包完之后先把代码输出到文件中,那么如果这时用户来访问了,就得先等express服务器从文件中把对应的资源读取到内存中,再从内存中读取到浏览器中(即先从文件系统中读取到内存中,再从内存中读取后转化成对应的数据流返回给浏览器)。因此,webpack-dev-server为了提高我们的开发效率,它会直接把打包之后的静态资源放到了内存里面,这样就少了一个从文件读取到内存的过程,这样提供服务的服务器的效率会更高一点,浏览器在访问时访问得也会更快一点。事实上,
webpack-dev-server使用了一个叫memfs的库(相当于是一个内存的文件系统),通过它把打包之后的静态资源直接放到了内存(内存的文件系统)中。memfs的github地址:github.com/streamich/m…而在早期,
webpack使用的不是这个memfs库,而是自己的一个库:memory-fs,当然,现在这个库已经很久没更新了,并且已经被弃用了:总结一下就是:
webpack-dev-server在编译之后不会写入到任何输出文件中,而是将打包后的文件保留在内存中(通过使用memfs库实现的)。