1.4.5 webpack-dev-server
到这里,其实我们已经把Webpack的初始环境配置完毕了。你可能会发现,单纯使用Webpack以及它的命令行工具来进行开发调试的效率并不高。以往只要编辑项目源文件(JS、CSS、HTML等),刷新页面即可看到效果。现在多了一步打包,我们在改完项目源码后要执行npm run build更新bundle.js,然后才能刷新页面生效。有没有更简便的方法呢?
其实Webpack社区已经为我们提供了一个便捷的本地开发工具——webpack-dev-server。用以下命令进行安装:
npm install webpack-dev-server --save-dev
安装指令中的--save-dev参数是将webpack-dev-server作为工程的devDependencies(开发环境依赖)记录在package.json中。这样做是因为webpack-dev-server仅仅在本地开发时才会用到,在生产环境中并不需要它,所以放在devDependencies中是比较恰当的。假如工程上线时要进行依赖安装,就可以通过npm install--production过滤掉devDependencies中的冗余模块,从而加快安装和发布的速度。
为了便捷地启动webpack-dev-server,我们在package.json中添加一个dev指令:
…… "scripts": { "build": "webpack", "dev": "webpack-dev-server" }, ……
最后,我们还需要对webpack-dev-server进行配置。编辑webpack.config.js如下:
module.exports = { entry: './src/index.js'fsad output: { filename: './bundle.js', }, mode: 'develpoment', devServer: { publicPath: '/dist', }, };
可以看到,我们在配置中添加了一个devServer对象,它是专门用来放webpack-dev-server配置的。webpack-dev-server可以看作一个服务者,它的主要工作就是接收浏览器的请求,然后将资源返回。当服务启动时,会先让Webpack进行模块打包并将资源准备好(在示例中就是bundle.js)。当webpack-dev-server接收到浏览器的资源请求时,它会首先进行URL地址校验。如果该地址是资源服务地址(上面配置的publicPath),就会从Webpack的打包结果中寻找该资源并返回给浏览器。反之,如果请求地址不属于资源服务地址,则直接读取硬盘中的源文件并将其返回。
综上我们可以总结出webpack-dev-server的两大职能:
·令Webpack进行模块打包,并处理打包结果的资源请求。
·作为普通的Web Server,处理静态资源文件请求。
最后,在启动服务之前,我们还是更改一下add-content.js:
export default function() { document.write('I\'m using webpack-dev-server!'); }
一切就绪,执行npm run dev并用浏览器打开http://localhost:8080/,可以看到如图1-5所示的输出结果。
图1-5 index.html内容变为了“I’m using webpack-dev-server!”
这里有一点需要注意。直接用Webpack开发和使用webpack-dev-server有一个很大的区别,前者每次都会生成budnle.js,而webpack-dev-server只是将打包结果放在内存中,并不会写入实际的bundle.js,在每次webpack-dev-server接收到请求时都只是将内存中的打包结果返回给浏览器。
这一点可以通过删除工程中的dist目录来验证,你会发现即便dist目录不存在,刷新页面后功能仍然是正常的。从开发者的角度来看,这其实是符合情理的。在本地开发阶段我们经常会调整目录结构和文件名,如果每次都写入实际文件最后就会产生一些没用的垃圾文件,还会干扰我们的版本控制,因此webpack-dev-server的处理方式显得更加简洁。
webpack-dev-server还有一项很便捷的特性就是live-reloading(自动刷新)。让我们保持本地服务启动以及浏览器打开的状态,到编辑器去更改add-content.js:
export default function() { document.write('This is from live-reloading!'); }
此时切回到浏览器,你会发现浏览器的内容自动更新了,这就是live-reloading的功能。当webpack-dev-server发现工程源文件进行了更新操作就会自动刷新浏览器,显示更新后的内容。该特性可以提升我们本地开发的效率。在后面我们还会讲到更先进的hot-module-replacement(模块热替换),我们甚至不需要刷新浏览器就能获取更新之后的内容。