四、配置webpack-dev-server
(1) 理解为什么要使用 webpack-dev-server
在上面一篇文章中,我们已经可以通过webpack去打包整个项目了,但是每次写完代码,都需要手动运行一下webpack执行打包,才能看到修改后的效果,这对于我们前端开发来说是十分不方便的。还有一点就是如果我们想发送一个ajax请求,那么必须要使用http协议,而直接打开本地文件使用的则是file协议。因此,我们可以使用webpack自带的devServer来在前端开启一个小型服务器,这个服务器可以监听我们的文件改动然后自动刷新页面,可以帮助我们实现ajax请求的发送。
我们在第一篇文章的开头就已经安装好了 webpack-dev-server 因此我们可以直接进入webpack.config.js去开启他!
(2)配置webpack-dev-server
在module.exports中增加如下配置:
devServer: {
open: true, // 开启服务器后是否自动打开浏览器
port: 9090, // 服务器所占端口
contentBase: path.resolve(__dirname, 'dist'), // 服务器打开本地文件的地址
hot: true,
historyApiFallback: true,//找不到页面默认跳index.html
},
注意 contentBase 这个属性,当不写这个属性的时候,devServer会去webpack.config.js所在的目录也就是根目录下找index.html文件,如果找不到则无法显示网页。如果写了话,devServer会去指定的目录找index.html文件。
写好以上配置后,我们需要启动webpack-dev-server,可以通过在package.json文件中的scripts属性配置快捷启动的方法。
(3)配置package.json的scripts属性
打开package.json文件,找到scripts属性,配置如下:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack-dev-server"
},
这样,当我们在终端输入,npm run dev 时, 就会执行 webpack-dev-server 了,同理我们配置下webpack打包的快捷命令。最终如下:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack-dev-server",
"bulid": "webpack"
},
然后我们打开终端,输入npm run dev
注意: 如果出现错误:
Error: listen EADDRINUSE 127.0.0.1:9090
则代表9090端口被占用了,去devServer中改一下端口号即可。
(4)启动服务器后的一些错误处理
启动成功后,我们会发现浏览器自动打开,但是页面上会提示:
Cannot GET /
这个问题我们应该很明了,服务器启动正常了,但是找不到index.html文件。原因上面也提到过,那就是我们在配置devServer时,contentBase设置的是 dist 文件夹下面的,然而我们dist文件夹下并没有index.html !
所以我们这里先修改一下contentBase,将其注释掉!然后在终端重启 webpack-dev-server。
会发现浏览器自动弹出,并显示 hello vue
接着我们打开App.vue,随意修改下内容,加个你好,然后保存。 然后回到浏览器,发现,,,,,,,,网页内容并没有任何变化! 怎么了,配置错了吗?
其实并不是,注意,打开index.html,我们会发现:
<script src="./dist/bundle.js"></script>
我们一直引用的是dist文件夹下面的bundle.js,这个是我们在第二节通过webpack打包生成出来的js文件,其内容是打包时的内容,并不是webpack-dev-server打包生成的js文件。
那webpack-dev-server打包生成的 js 文件在哪?
答案是: 在内存中! 由于我们每次保存页面都会导致重新打包文件,因此为了更快速的构建,webpack-dev-server 把生成的js文件放到内存中,众所周知在内存中的速度是十分快的。那么我们怎么引用这个在内存中的文件呢?webpack-dev-server在内存中构建好这个文件后,会把它放到根目录下,这个文件我们是看不到的,但是可以正常的引用!因此我们需要在index.html中更改一下代码,改为:
<script src="./bundle.js"></script>
重启后发现,页面上的内容已经显示我们更改后的内容了。然后我们回到App.vue再更改内容,保存后我们会发现,页面上的内容已经自动刷新了。
拓展引用:使用插件 html-webpack-plugin
插件: html-webpack-plugin
这个插件的通常用法是根据指定的index.html模板生成一个存在于内存中的index.html,它会自动引入webpack-dev-server打包出的在内存中的bundle.js文件,在我们开发的时候,可以去请求这个存在于内存中的index.html,这样可以有效的减少读取物理磁盘中内容而导致的刷新滞后。
(1)安装、使用html-webpack-plugin
在终端中输入以下命令:
npm i --save-dev html-webpack-plugin
然后到webpack.config.js文件中
let htmlWebpackPlugin = require('html-webpack-plugin')
// 生成内存中的页面
new htmlWebpackPlugin({
template: path.resolve(__dirname, 'index.html'),
filename: 'index.html'
})
上面的 template 指的就是模板文件所在的位置,而filename则代表生成文件的名字。
如果不进行配置的话,html-webpack-plugin默认生成的index.html的位置与我们在output中配置的是一样的。我们查看output中的path的位置在dist文件夹下,那么生成的index.html文件将会在dist文件夹中,但是我们查看不到,因为它是在内存中。
(2)更改devServer的contentBase配置
在上面我们把contentBase注释掉,因为当时在dist文件中并没有index.html文件,但是现在html-webpack-plugin的输出文件跟output一样,把index.html输出到了dist里面,那么我们可以把注释掉的代码解开了!重启devServer服务器,更改App.vue里面的代码,保存后发现浏览器也已经更新了!