webpack配置文件中publicPath和contentBase傻傻分不清

      平时现成的webpack配置文件用多了,真到自己去配置的时候就蒙蔽了,这不最近在做一个关于多页面的webpack配置的时候就遇见了各种问题,比如publicPath和devServer中的publicPath,contentBase搞不灵清,这里就来搞清楚。

  1. publicPath
  2. contentBase
publicPath

在前端webpack的配置项中publicPath主要出现的两个地方:

  • output 资源输出配置项中
  • devServer 静态资源服务配置项中

      这个两个publicPath有什么区别呢?一句话,output中的publicPath影响资源生成路径,devServer中的publicPath影响资源在本地开发环境中的访问。

在output资源输出配置项中通常我们能看到类似下面这样的配置

config.js

module.exports=  {
  dev:{
    ...,
    publicPath:"/assets/"
  },
  build:{
    publicPath:"https://csdn.cdn.cn/"
  }
}

webpack.config.js

module.exports = {
   entry:{
      ...
   },
   output:{
      ...,
      publicPath:process.env.NODE_ENV=='development'?config.dev.publicPath:config.build.publicPath
   }
}

这样配置好后打包出来后静态资源在html文件中的效果就像这样:

本地开发环境下:
在这里插入图片描述

在生产环境如下:
在这里插入图片描述
可以看出来publicPath的效果最终体现在静态资源的uri中,在这里区分了运行环境。在本地开发环境用静态资源所在目录相对地址,这里需要注意在写publicPath是我们应该写成/publicPath/,不然html页面在访问生成静态资源路径时可能会出现找不到资源的问题。在生产环境时,有时候我们需要将我们的静态资源进行CDN托管,这个时候我们只需要将config.build.publicPath换成CDN地址就好了。这样能很好的区分开生产环境和本地开发环境静态资源的路径问题。

      这样配置好后,往往伴随而来的是另外一个问题,那就是在启动本地服务进行开发调试的时候,会出现静态资源找不到的问题。在解决这个问题之前先来看一下本地服务在webpack中的配置项:

const path = require("path");
module.exports = {
   ...,
   devServer:{
     ...,
     port:8080,
     contentBase:path.join(__dirname,'..',dist),
     publicPath:''}
 }

      如果我们不配置publicPath,我们在启动本地服务后访问http://127.0.0.1:8080/,能访问到我们的默认首页,发但是我们打开调试窗口的时候发现静态资源会出现404的问题,但如果将这里的publicPath配置成output中的publicPath,这个时候静态资源就能成功加载了,这是怎么回事呢?
      这里先来看一段用express构建静态资源服务的代码如下

const express = require("express");
const app = express();
const path = require("path");
app.use(express.static('public',path.join(__dirname,'/static')));
app.listen(8080,(err)=>{
   if(err) throw err;
   console.log('server is listening on port 8080')
})

      这个时候,访问http://127.0.0.1:8080/public/***.js,能访问到对应static目录下的静态资源。熟悉express的小伙伴一眼就出关键点就在app.use(express.static('public',path.join(__dirname,'/static')));这里使用了一个静态资源中间件static。中间件的作用这里就不探讨了,这句话的作用就是本地服务会先拦截所有public开头的uri,然后到static目录下去寻找静态资源,找到就返回。实际上在服务器上是没有public目录的,这里的public可以很好的隐藏我们静态资源在服务器上的实际目录。另一方面,也可以对静态进行分类存放。
说了这么多,这和我们的webapck中的devServer有什么关系吗?嘿嘿,还真有关系,而且关系还大着呢,因为webpack-dev-server的实现就是用的express实现的。这就豁然开朗了吧,devServer中的publicPath其实就是相当于上面express代码中public值的变量。
      so!这两个publicPath基本上时连体兄弟,如果在本地开发环境中配置了output的publicPath,那么在devServer中也要做相应的配置。

contentbase:

      contentbase代表html页面所在的相对目录,如果我们不配置项,devServer默认html所在的目录就是项目的根目录,这个时候启动服务,访问地址通常会出现下面这样的场面:
在这里插入图片描述
并不会看见html页面,相反展现在我们面前的时项目根目录文件夹,因为我们根目录下根本没有html文件。这个时候html在编译后实际是在dist目录下,所以我们需要这样配置:

...
devServer:{
  contentBase:'dist',
  ...
}

这样我们就能正常访问我们的页面了。

      这里需要注意一点,contentBase的路径是相对与webpack.config.js文件所在的目录的,有的时候,我们习惯将webpack配置文件统一放着一个build文件下,这个时候我们在写contentBase路径的时候就需要注意了。

总结:

  1. output的publicPath是用来给生成的静态资源路径添加前缀的;
  2. devServer中的publicPath是用来本地服务拦截带publicPath开头的请求的;
  3. contentBase是用来指定被访问html页面所在目录的;
  • 14
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值