webpack publicPath作用原理

详解一下webpack中publicPath的作用。

output中的publicPath是给其它loader或plugin使用的,它们会把publicPath拼在某些路径上。

比如file-loader,该loader的作用是遇到文件,就把文件复制到打包目录,并返回一个路径A,如果配置了publicPath,返回的路径就是publicPath+A。

比如HTMLWebpackPlugin,该plugin的作用是在打包文件夹下生成一个html,并引入打包好的js文件,如果配置了publicPath,引用js路径前就会加上publicPath。

publicPath本质就是一个字符串,它是给其它loader或plugin这样使用的,除此之外没有其它的功能。

那么,这样做有何深意,能解决什么问题?下面看一个这样的例子:

例子很简单,主要有三个文件:webpack.config.js配置文件,index.js业务文件,和一张图片文件file.png。

index.js文件的功能也很简单,只是导入图片,放到body中,代码如下:

js 复制代码
import png from "./file.png";
var img = document.createElement("img");
img.src = png;
document.body.appendChild(img);

重点在于webpack.config.js配置文件,那张图片需要file-loader解析,然后用到了HTMLWebpackPlugin插件,在打包目录中生成html文件,配置如下:

webpack.config.js 复制代码
module: {
    rules: [
        {
          test: /\.(png|jpe?g|gif)$/i,
          loader: "file-loader",
        },
    ],
},
plugins: [new HtmlWebpackPlugin(), new CleanWebpackPlugin()],

这样生成的打包结果,dist文件夹目录如下:

打开index.html,图片正常展示,说明路径没出问题:

现在我想换个配置,我希望打包后的图片在imgs文件夹下,index.html在html文件夹下,于是我修改了webpack配置:

webpack.config.js 复制代码
module: {
      rules: [
        {
          test: /\.(png|jpe?g|gif)$/i,
          loader: "file-loader",
          options: {
            name: "imgs/[name].[ext]",
          },
        },
      ],
},
plugins: [
      new HtmlWebpackPlugin({
        filename: "html/index.html",
      }),
      new CleanWebpackPlugin(),
],

这样生成打包结果,dist文件夹目录如下:

打开index.html,图片找不到,且在控制台看到图片的访问路径是:http://127.0.0.1:5500/html/imgs/file.png

这个图片的访问路径明显是有问题的,因为按照dist目录结构来看,正确的访问路径应该是http://127.0.0.1:5500/imgs/file.png

为什么会这样?

原因是,html页面访问地址是http://127.0.0.1:5500/html/index.html

经loader转换后的图片路径是相对路径是./imgs/file.png。

所以,图片最终路径为http://127.0.0.1:5500/html/imgs/file.png

注意: 浏览器中所有资源路径永远相对于"打开的HTML文件",不是JS文件!不管是在HTML直接引,还是在JS里引,全部以HTML所在文件夹为基准,因为js是寄生在HTML页面里运行的,JS执行上下文属于HTML页面)。

访问路径错了,那怎么解决这个问题呢?答案就是配置publicPath。

我们这样配置webpack:

webpack.config.js 复制代码
module: {
      rules: [
        {
          test: /\.(png|jpe?g|gif)$/i,
          loader: "file-loader",
          options: {
            name: "imgs/[name].[ext]",
          },
        },
      ],
},
plugins: [
      new HtmlWebpackPlugin({
        filename: "html/index.html",
      }),
      new CleanWebpackPlugin(),
],
output: {
      publicPath: "/",
},

publicPath设置"/"。

于是,总页面路径还是http://127.0.0.1:5500/html/index.html

但是图片路径从相对路径变成了绝对路径/imgs/file.png。

所以,绝对路径会以域名为起点查找,所以图片最终路径是http://127.0.0.1:5500/imgs/file.png ,这样就能找到图片。

总结

以上就是用output的publicPath配置解决文件丢失的用法,在多数情况下,**此选项的值是 / **。

相关推荐
HduSy1 小时前
帮 Claude Code 做了个菜单栏 Token 看板,聊聊里面的一些实现逻辑
前端
用户059540174461 小时前
用了6个月LangChain,才发现AI Agent的记忆存储一直有坑——写了23个Pytest用例才彻底修好
前端·css
奶油mm1 小时前
我偷偷把公司的祖传 jQuery 项目改成了 Vue3,CTO 没发现,但全组都来抄我的代码了
前端
用户2136610035721 小时前
Vue2非父子通信与动态组件
前端·vue.js
PedroQue991 小时前
Vite插件体系1.0.0:API稳定,生产就绪
前端·vite
用户059540174461 小时前
把LLM记忆测试从手工脚本换成Pytest参数化,回归时间从2小时降到10分钟
前端·css
donecoding2 小时前
3 条命令搞定闭环 Monorepo:Lerna 版本管理 + 拓扑构建 + 自定义分发
前端·前端框架·node.js
IT_陈寒2 小时前
Vue的这个响应式陷阱让我熬到凌晨三点
前端·人工智能·后端
爱勇宝10 小时前
大多数人不是在使用 AI 赚钱,而是在帮 AI 公司赚钱
前端·后端·程序员