webpack中devserver遇坑

323 阅读3分钟

DevServer踩坑

最近在学习webpack中的devserver时,出现了一个让我十分头疼的小问题。我的原意是使用devserver在本地开放静态资源和尝试一下hmr。

截屏2022-03-19 下午3.11.44.png 但是却发现只是显示了静态目录所对应的位置。我很费解,难道不应该是在本地展示我打包后bundle.js的内容吗?比如这样:

截屏2022-03-19 下午3.14.55.png 然后我就纠结了,难道是我开启了静态文件的访问,但是没有开启对原本内容的显示? 然后我又想,原本webpack5之前devserver中有一个配置属性叫:contentBase,但是在webpack5中被移除了。难道是。。。。(小菜鸡的烦恼) 先发一下我本地服务的配置:和官网的一致

// 本地服务
module.exports = {
    ...
  devServer: {
    static: {
      directory: path.join(__dirname, "public"),
    },
    compress: true, // 是否启动压缩 gzip
    port: 8080, // 端口号
    open: true, // 是否自动打开浏览器
    hot: true, // HMR
  },
}

后来我想到了我之前把 output中的 publicPath设置成了"./",为的是可以直接打开dist目录下的出口文件展示效果,而这玩意的默认配置是:""

module.exports = {
    ...
  output: {
    filename: "[name].js",
    path: path.resolve(__dirname, "./dist"),
    clean: true,
    // publicPath: "./",
}

给publicPath注释了以后,发现可以展示正常内容了······ 学习的时候就对publicPath理解的很差,这把遇坑了决定还是好好研究一下publicPath把

publicPath

output中有这样两个属性:path 和 publicPath

  • path:用来指定文件的输出路径。一般在项目中我们把输出路径命名为dist,在项目根目录上。
  • publicPath: 作为项目资源的公共路径 其中对publicPath的描述看起来很简单,但还是难以理解。于是我又找了一些资料。发现:
  1. path需要接受一个绝对定位,它的默认值是 process.cwd(),即 node.js 工作的目录,与__dirname的区别是,__dirname就是指当前文件所在的目录。 大部分时候这两个值是一样的,但是如果我们以这种方式调用:
node src/index.html

这两个值就不一样了,所以大部分时候我们使用__dirname。

  1. publicPath默认值是空字符串,所谓的公共路径就是指饮用css,js,img等文件的时候的一个基础路径,要和其他路径一起结合使用:
静态资源的最终访问路径 = output.publicPath + 资源loader或插件等配置路径

比如这里

module.exports = {
    ...
  output: {
    filename: "[name].js",
    path: path.resolve(__dirname, "./dist"),
    clean: true,
    // publicPath: "./",
}

在我们生成的dist/index.html中,资源的引用位置就是 publicPath + filename:

<script defer="defer" src="chunk-vendors.js"></script>

如果我们的 publicPath设置成了 "/dist",那么就是

<script defer="defer" src="/dist/chunk-vendors.js"></script>

所以这也就解释了为什么我把publicPath设置成了"./"的时候,直接用浏览器打开dist目录下生成的index.html是可以看到打包的结果的。因为即使是浏览器直接打开,"./"相当于当前目录,index.html可以在当前目录找到其他的打包结果引入进来,并展示。

使用"./"时,因为是相对路径,所以我们本地在dist/index.html中直接打开浏览器时是可以找到对应资源的位置的。但是devServer启动时,在他的环境的本地是找不到资源的。简单理解就是,devServer打开资源的根路径和"./"不匹配。

而使用"/"时,相当于我们资源启动时的路径,比如我们项目启动在: http://localhost:8080 上,对应资源的位置在 http://localhost:8080/dist 上时,我们使用/dist可以访问到对应资源,这里/就相当于资源启动的根路径。

引发的思考

在项目中,我们需要路径时,除非是resolve(),可以使用相对路径之外,其余的地方应该一致使用绝对路径,不然就可能会存在资源找不到的情况。