webpack4.0 html和css里图片资源加载问题

用webpack打包文件时候发现应用路径总是对不上,html和css中img的引用总是会出错。
这是整个文件目录结构
clipboard.png

这是要打包的html
clipboard.png

这是要打包的css

clipboard.png

这是webpack.config.js中对于图片的处理

clipboard.png

这是打包后的结果

clipboard.png

html中的img文件路径对了。但是css的路径的变成了 css目录下的img,

阅读 7.6k
3 个回答

先说一下我的问题吧,以下是我的目录结构(以下用test命名的文件/文件夹就是此次测试所用)

图片描述

这个是一开始的webpack配置
图片描述
图片描述

这个是在sass中引用到的图片
图片描述

我希望的是打包后,src/img/test/test.png能够变成dist/img/test/test.png,然而,当我打包之后,却发现变成了这样子
图片描述
图片描述

图片直接打包到了dist/img目录之下,并且css之中引用的也是dist/css/img下的图片,没办法,看文档,结果我看到了这一句图片描述

我寻思着,这应该就是对应目录的配置了吧(原谅我理解有问题),赶紧写上去,结果是这样

图片描述

毛线啊,只不过是多了个src的相对路径啊,问题根本没变啊
之后还是到了找资料的过程,发现publicPath这个东西,
图片描述

重点来了,publicPath说是自定义发布的目录,其实就是将你打包后的css中引用的文件路径给替换成publicPath的值,并且因为publicPath与name这两个属性可以是函数,并且两者有一定的联系,所以我们可以从这里下文章。

{
            test: /\.(png|jpg)$/,
            use: {
                loader: "url-loader",
                options:{
                    name: function(file){
                        console.log('----------111-------',file);
                    },
                    // name: '[name].[ext]',
                    limit: '8192',
                    publicPath: function(url){
                        console.log('----------222-------',url)
                    },
                    outputPath: 'img/',
                }
            }
        }

当然,这样子打包的是不完整的,打包后的图片也是直接就在dist/img文件夹下,我们需要的是看看参数file与url是什么
图片描述

一次是看不出什么的,我们再来一次

{
            test: /\.(png|jpg)$/,
            use: {
                loader: "url-loader",
                options:{
                    name: function(file){
                        console.log('----------111-------',file);
                        return 'QAQ/[name].[ext]'
                    },
                    // name: '[path][name].[ext]',
                    limit: '8192',
                    publicPath: function(url){
                        console.log('----------222-------',url)
                    },
                    outputPath: 'img/',
                }
            }
        }

图片描述

emm,dist/img文件夹下多了个QAQ,file是引用图片的绝对路径,并且url就是这个name函数返回的值(我们假装它是真的QAQ/test.png),那么接下来我们就可以继续进行下一步

{
            test: /\.(png|jpg)$/,
            use: {
                loader: "url-loader",
                options:{
                    name: function(file){
                        var reg = /img\\(.*)\\([^\\]*)\.(png|jpg)$/,
                        dirStr = reg.exec(file)[1]
                        dirStr = dirStr?dirStr.replace(/\\/g,'/')+'/':''; 
                        return dirStr + '[name].[ext]'
                    },
                    // name: '[path][name].[ext]',
                    limit: '8192',
                    publicPath: function(url){
                        return path.resolve(__dirname,'dist/img',url).replace(/\\/g,'/')
                    },
                    outputPath: 'img/',
                }
            }
        }

在name这边我使用了正则好从file中提取出对应的文件夹比如'QAQ/',拼合成打包图片的路径返回,这样子根据图片生产对应的文件夹这个问题就解决了,然后在publicPath这边根据传进来的url进行路径拼接,得到打包后的图片位置,并返回出去,结果如下图
图片描述
可以看到这已经得到了我预期的效果,并且打包后的css中图片引用路径也是没问题的。
希望这个能给楼主提供一些帮助,另外如果有错误的话还请各位指出,毕竟第一次写东西语言有点混乱(躺)

图片路径问题是修改build==>utils.js:
if (options.extract) {
      return ExtractTextPlugin.extract({
        use: loaders,
        fallback: 'vue-style-loader',
        publicPath:'../../'  //加上这个
      })
    } else {
      return ['vue-style-loader'].concat(loaders)
    }
    
 css、js路径问题是修改config==>index.js:
build: {
    env: require('./prod.env'),
    index: path.resolve(__dirname, '../dist/index.html'),
    assetsRoot: path.resolve(__dirname, '../dist'),
    assetsSubDirectory: 'static',
    assetsPublicPath: './',  //把'/'改成'./'
    productionSourceMap: false,
    ...
   }
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题