这是webpack系列文章的 【第四期】,希望你在阅读前已经看过前几期的文章
前言
在前面几期介绍了webpack的基本概念,用法,流程,loader机制与plugin机制,其实看起来好像已经掌握webpack。但是我们只以这些认知去在实际中开发使用还是远远不够的。
在实际开发中还有一点很重要,那就是效率。通过前面几期的学习,每次打包都需要经历以下几个流程:修改代码→打包→运行→浏览器查看,每当我们进行一次修改都会经历这一些列操作,这占用了我们大量的时间,也导致了开发效率降低。
那设想一下一个理想的开发环境什么样的呢
- 可以使用http服务来进行文件预览,而不是手动的去打开文件
- 可以访问静态资源文件
- 每次次改完后可以自动打包,并自动刷新浏览器
- 可以使用AJAX之类的API
- 可以提供 Source Map 支持,可以让我们在出现错误时快速定位到源代码中的位置,便于调试
那接下来我们就一项一项的来实现
自动编译打包
我们之前打包使用的命令是
npx webpack
在webpack cli 中提供了另外一种watch工作模式,在这种模式下,会监听源文件中的内容,一旦发生任何改动,webpack就会自动重新运行打包任务。我们只需要在启动webpack时,在后面添加一个–watch参数即可,这样webpack就会以监视启动运行。
npx webpack --watch
当启动监视模式后,webpack在打包完成后不会自动退出,而是继续监视下一次修改然后重新打包,除非我们手动退出(ctrl + c)。
然后我们可以再打开一个命令行终端,把我们的项目以http的方式运行
npx serve dist
在浏览器中输入localhost:5000即可预览打包后的项目
到现在我们可以实现修改代码后自动打包,通过http的形式去预览,但是每次修改还是需要手动的去刷新浏览器。我们希望的是他可以像我们开发VUE项目一样,具有热更新的功能。
这里我们需要借助一个叫做 BrowserSync 的工具,现在全局进行安装
npm install browser-sync -g
使用 BrowserSync 工具替换 serve 工具来启动 http 服务,这里我们需要监听的是dist目录下的变化,一旦dist下的内容发生改变,就需要自动刷新浏览器。
browser-sync dist --watch
现在每当我们修改文件保存后,就会自动执行打包,相应的dist文件的内容就会发生改变,BrowserSync 监听dist改变后自动刷新浏览器。
通过上面的 watch模式+BrowserSync 已经可以实现我们的需求,但是这种方法存在很多的弊端:
- 操作繁琐,我们每次都需要打开两个终端来分别实现修改自动打包与自动刷新的操作。
- 执行效率低,这种方法涉及到大量的磁盘读写操作,webpack现将打包后的文件写入磁盘BrowserSync 再进行读取,每次都需要这样反复流程,必然会降低效率。
所以我们需要继续改善
Webpack Dev Server
Webpack Dev Server 是webpack官方推出的一款开发工具,他提供了一个开发服务器,将自动编译和自动刷新等一系列的功能都集成到了一起。
npm install webpack-dev-server --save
Webpack Dev Server 同样也是一个独立的 npm 模块,它提供了一个叫做webpack-dev-server的CLI程序,我们可以通过npx去直接运行它。
npx webpack-dev-server
它的工作流程是,它的内部会启动一个HTTP Server,为打包的结构提供静态文件服务,并自动使用webpack打包我们的应用,然后监听源代码的变化,一旦文件发生变化,它会立即重新打包。
这看起来和之前的流程差不过呀,其实有很大的不同,webpack-dev-server 为了提高工作速率,它并没有将打包结果写入到磁盘中,而是暂时存放在内存中,内部的 HTTP Server 也是从内存中读取这些文件的。这样一来,就会减少很多不必要的磁盘读写操作,大大提高了整体的构建效率。
我们还可以为 webpack-dev-server 命令传入一个 --open 的参数,用于自动唤起浏览器打开我们的应用。
npx webpack-dev-server --open
如果只是这样还完全不能 展示出它的能力,webpack为我们提供了可配置的选项
module.exports = {
devServer:{
port: 9000,
contentBase: 'public',
proxy:{
'/api':{
target: 'https://.....'
},
pathRewrite:{ //重写掉开头的api
'^/api': ''
},
changeOrigin: true //修改主机名
}
}
}
更多的配置可参考官方配置说明:https://webpack.js.org/configuration/dev-server/
这里我只提出一些常用的配置:
-
port
指定要侦听请求的端口号
-
proxy
由于 webpack-dev-server 是一个本地开发服务器,如果我们要请求其他的地址上的API时,会出现跨域的问题,他的用法与我们在VUE项目中使用proxy是一样的。
-
contentBase
访问静态资源,通过前面介绍的plugin机制可以知道,我们可以使用copy-webpack-plugins实现对静态资源的复制打包,也就是说在dist文件中也会包含静态资源文件。既然这样我们不是也可以直接访问吗,为什么要通过contentBase来访问为打包前的静态资源。
还是效率问题,对于copy-webpack-plugins这个插件,我们在开发阶段是不会使用的,只有当我们开发完成后进行最终打包的时候才会引入,在开发阶段,如果每次更改都要把静态资源copy一遍,这显然会浪费很多时间。contentBase它可以接受一个数组,用来访问多个不同目录下的静态资源,就像下面这样。
对于 Source Map 的支持将在下期进行讲解