写在前面
我们知道在开发中需要先将源代码进行打包后,再进行运行而后在浏览器打开,每次修改都要遵循这个步骤。那么,有没有什么方法可以省略这么多的繁琐步骤呢?有,但是必须遵守下面的要求:
- 必须能够使用HTTP服务运行而不是以文件形式预览。这样可以更加接近生产环境状态,而且项目中可能需要使用ajax类的api,以文件访问会产生诸多问题
- 在我们修改代码后,webpack能够实现自动完成构建,然后浏览器可以即时显示最新的运行结果,这样可以减少开发过程中额外的重复操作,同时可以让我们更加专注,效率得到提升
- 需要能够提供Source Map支持。这样,运行过程中出现的错误可以快速定位到源代码中的位置,而不是打包后结果中的位置,更便于我们快速定位错误、调试应用
Webpack自动编译
关于webpack自动编译可以完全符合以上要求,具体的用法是:启动webpack时,添加一个--watch的cli参数,webpack就会以监视模式启动运行,打包完成后cli不会立即退出,而是等待文件变化再次工作,知道我们手动结束它或出现不可控的异常。
- # 我们可以先npm 全局安装browser-sync模块,然后使用这个模块
- $ npm i browser-sync -g
- $ browser-sync dist --watch
- #或者使用npx直接使用远端模块
- $ npx browser-sync dist --watch
我们看到运行终端后的显示:
- npx browser-sync dist --watch
- [Browsersync] Access URLs:
- ---------------------------------------
- Local: http://localhost:3000
- External: http://192.168.99.161:3000
- ---------------------------------------
- UI: http://localhost:3001
- UI External: http://localhost:3001
我们看到这种webpack+browser-sync模式虽然实现了我们的需求,但是方法有很多的弊端:
- 操作繁琐,我们需要同时使用两个工具,需要了解内容更多、学习成本提高
- 效率低下,因为整个过程中webpack会将文件写入磁盘,browser-sync再进行读取,过程会设计到大量磁盘读写操作,导效率低下
对此,webpack官方推出了开发工具,能够提供一个开发服务器,并且自动编译和自动刷新浏览器等一系列对开发友好的功能全部集成在一起。推出初衷就是为了提高开发者日常的开发效率,使用这个工具就可以解决前面的问题。
- $ npm i webpack-dev-server -D
- $ npx webpack-dev-server
运行webpack-dev-server命令时,wbepack内部会自动启动http-server服务,为我们生成的静态文件提供server服务,并且为我们生成的文件提供打包服务。其工作流程大概是:
- 执行webpack-dev-server命令
- 启动http服务
- webpack构建
- 监视文件变化,有变化则进入新一轮webpack构建
要注意的是,webpack-dev-server为了提升打包效率,并未将文件写入磁盘中,而是将文件暂存到内存中,再通过http-server进行获取文件,减少了不必要的磁盘读写操作。
静态资源访问
webpack-dev-server会默认将构建结果和输出文件全部作为开发服务器的资源文件,只要通过webpack打包能够输出的文件就可以直接被访问使用。
在实际使用webpack时,一般会将copy-webpack-plugin这种插件留在上线前的那次打包使用,而在开发过程中一般不会使用。因为在开发过程中,我们会频繁执行打包任务,假设此目录文件需要拷贝的文件比较多、比较大,如果我们每次构建都需要执行插件的话,那么打包的开销就会比较大,构建速度会下降。
在实际生产环境中能够直接访问的api,回到开发环境后哦,再次访问这些api就会产生跨域请求问题。当然我们可以使用cors,但是必须后端支持。
为了解决这种开发阶段跨域请求问题最好的方法,就是在开发服务器中配置一个后端api的代理服务,把后端接口服务代理到本地的开发服务地址。我们可以添加pathRewrite属性来实现代理路径重写,重写规则就是把路径开头的/api替换为空。这样当我们请求代理接口http://localhost:9000/api/users就会代理请求目标接口http://api.github.com/users。
- devServer:{
- proxy:{
- "/api":{
- target:"http://api.github.com",
- pathRewrite:{
- "^/api":""//替换掉代理地址中的/api
- }
- }
- },
- contentBase:path.join(__dirname,"dist"),
- compress:true,
- port:9000
- }
参考文章
《webpack原理与实践》
《webpack中文文档》
写在最后
本文主要说明了如何配置DevServer提升我们的本地开发效率,其实就是使用了webpack的代理模式,在请求目标接口时通过本地代理请求,能够避免开发阶段的跨域问题。