webpack一般是用来打包的,但是webpack里面还有一个可以配置服务器的东东,叫webpack-dev-server,它可以为我们本地开发提供端口服务,并且还可以很好的支持webpack打包服务,今天就来看看这个怎么玩。

开始配置

新建一个项目,运行npm init,创建一个package.json。再新建一个webpack.config.js用来写打包的配置。

现在我们新建一个src目录和dist目录,src目录里面是我们开发的目录,dist是我们打包后的目录。我们在src目录里面写一个小demo:一个index.html,入口为index.js,包含两个js,引用一个css,css里面引用一张图片。配置完成后大概如下:

先来看看index.html:

因为待会运行的时候,webpack会通过入口index.js将相关文件打包成bundle.js,所以我们只要在index.html中引入bundle.js就好了。

现在来看看各个js:

入口index.js中引入了a.js和b.js,同时还引入了css,现在我们来看看css里面的内容:

好,完成了页面部分的编写,我们现在来写一下webpack.config.js:

现在我们利用npm install来安装各种包,首先要安装webpack和webpack-dev-server:

因为我们这里要解析css,同时css里面还引用了图片,因此我们安装一下style-loader和url-loader。

现在我们来用webpack命令打包一下,看可不可以打包成功:

提示安装webpack-cil,那我们安装后再试一次,可以看到已经打包成功了。

我们可以看到dist里面多了一个bundle.js,说明我们已经把index.js,a.js,b.js,index.css都打包到一起了。

webpack-dev-server

上面讲了webpack打包流程,现在我们开启webpack-dev-server服务器功能:在控制台输入node_modules/.bin/webpack-dev-server,可以看到我们的服务在8080端口运行:

我们打开localhsot:8080,可以看到如下页面:

因为我们没有指定访问哪个目录,默认访问根目录,我们通过contentBase设置默认访问dist目录,关键代码如下:

设置了contentBase之后,我们重新运行node_modules/.bin/webpack-dev-server,会发现如下页面:

别着急,没有错,我们将src下的index.html复制到dist目录就可以了,就可以看到我们的页面了。

这里有两个很容易混淆的概念,一个是webpack打包出来的生成的bundle.js,这个是真实的,在dist目录下;一个是webpack-dev-server服务器生成的一个bundle.js,这个是存在内存中的,看不到的,也存在于dist目录下:

webpack-dev-server服务器跑起来后,会优先调用内存中的build.js。

每次输入node_modules/.bin/webpack-dev-server比较麻烦,我们将这个写入到package.json中的scripts下面:

配置完成以后,我们只要输入npm start即可运行服务器,注意,上面有一个--mode development,这个表示在webpack-dev-server运行时打包的时候利用开发模式,而不是生产模式。开发模式不会代码压缩等,只是将代码拼接,速度快很多。如果不配置的话,默认是开发模式。

自动刷新和热模块替换

webpack-dev-server为了方便开发,提供了自动刷新机制,自动刷新就是在客户端利用socket监听来自服务端的消息,例如文件改动了,服务器会先打包,在内存中生成了新的bundle.js后,告诉客户端:嘿,该刷新了!然后客户端就reload页面。

自动刷新有内外两种模式,外部模式就是利用iframe,我们可以输入http://localhost:8080/webpack-dev-server/index.html,看到如下效果:

页面顶部的App ready就是一个外层页面,我们的页面被嵌在里面。外部页面会加入一个live.bundle.js,这个里面有socket监听来自服务器的消息:

如果有消息或者编译信息,都会显示在顶部(App ready那个位置)。

内部刷新是需要在webpack-dev-server打包的bundle.js里面注入webpack-dev-server/client?http://localhost:8080/,并在devServer中配置inline:true。所谓的注入就是在webpack.config.js中的entry多加一个入口:

不过我发现即使我没有注入webpack-dev-server/client?http://localhost:8080/,webpack-dev-server打包的bundle.js也是有webpack-dev-server/client?http://localhost:8080/这个的:

不确定是不是高版本就默认带有inline模式,如果你的打包信息里面没有默认自带的话,可以采用刚才说的注入方式。

其实这种内部模式就是注入的webpack-dev-server/client?http://localhost:8080/代码里面包含socket监听,可以监听到来自服务器的消息:

收到消息之后就刷新页面。

自动刷新模式虽然可以每次刷新页面,但是对于一个大型项目还是比较麻烦的,因此有了热更新,热更新只是更新模块,不更新整个页面。

启动热更新需要devServer中的hot:true,inline:true,plugins加上new webpack.HotModuleReplacementPlugin(),入口注入webpack/hot/dev-server.js。不过我发现只要配置devserver中hot:true和在plugins加上new webpack.HotModuleReplacementPlugin()就可以达到热更新的效果,设置了hot:true后,会自动注入webpack/hot/dev-server.js。

热更新到这里只是完成了一半,还有一半需要我们在代码里面写,我们在index.js里面写上如下代码:

代码里面的module.hot.accept();表示所有的模块都在收到热更新的消息后都会同意更新。其实这个热更新的accpet是应该写在各个模块js里面的(写在a.js和b.js里面),但是它这里面有一个冒泡机制,就是当前模块没有发现accept,那么就会找上层,因此我们在顶层(index.js)允许所有的模块热更新。

除了全部accpet之外,还可以单个accept以及回调;decline不接受哪个模块的更新;dispose表示模块热更新后消除一些资源或保存一些状态的(可以和module.hot.data一起使用)。

热模块启动,更新会有相应的log,[HMR]是热更新的log,[WDS]是wepback-dev-server监听socket的log。

代理

代理功能很重要,因为前端开发起的服务器一般和后端开发的服务器不相同,这个时候需要代理给我们转换接口了。

更多关于代理的配置可以查阅http-proxy-middleware。

hotUpdateChunkFilename vs hotUpdateMainFilename

当我们采用热更新模式的时候,js可以采用accpet的方法来接受,但是css不行,我们先来看一看修改一css会发生什么:

同时还多了一个json文件:

hotUpdateChunkFilename用来配置那个update.js的名字,hotUpdateMainFilename用来配置那个json的文件。

不过注意,这个是在output中配置的:

其他关于webpack-dev-server中的配置

historyApiFallback是设置页面404展现页面:

上面是全局404,就是所有页面找不到都跳那个页面,如果想指定页面跳转,如下:

host和port可以用来设置访问的主机和端口号。

用HtmlWebpackPlugin插件自动在dist目录生成index.html

刚刚我们讲的index.html必须自己手动在dist目录下新建一个,但是可以用HtmlWebpackPlugin直接将文件在内存中生成:

注意,如果你设置了devserver,那么HtmlWebpackPlugin中的filename是基于contentBase的。也就是说这个会把src中的index.html生成到dist中,这个也是在内存中,看不到的。

DEMO下载

点击下载 [0积分]一共下载0

其他文章

0
我要评论

评论

返回
×

我要评论

回复:

昵称:(昵称不超过20个字)

图片:

提交
还可以输入500个字