file-loader的踩坑

踩坑一:当我配置好file-loader之后运行npm run build,构建完成之后打开index.html,发现图片显示不出来,然后dist文件夹中还会多出一个显示不了的图片

html代码

.bg-image {
  background-image: url("../img/jx.png");
}

 原因:当你对资源进行打包,因为你配置了file-loader所以会有对应的file-loader来帮你处理,但是webpack5里面又会默认帮你使用asset 模块进行处理,所以原因就是他们两个就冲突了

解决方案:
当在 webpack 5 中使用旧的 assets loader(如 file-loader/url-loader/raw-loader 等)和 asset 模块(即使你没有配置)时,你可能想停止当前 asset 模块的处理,并再次启动处理,这可能会导致 asset 重复,你可以通过将 asset 模块的类型设置为 'javascript/auto' 来解决。 来自官方文档 webpack 中文文档 (docschina.org)

{
        test: /\.(png|jpe?g|gif|svg)$/,
        use: [
          {
            loader: 'file-loader',
          }
        ],
        type: 'javascript/auto'
      }

 

踩坑二:就算上面的配置完成之后,打包后的图片依旧显示不了,而且对资源的引用后面的路径变成了 /[object%20Module]

 

原因:

file-loader新版本默认使用了esModule语法,造成了引用图片文件时的方式和以前的版本不一样,而我们css-loader对url的处理又是将其转换成require()语句(commonjs语法)

注:css-loader会默认帮你转换url -> url(image.png) => require('./image.png') 官网的解释 webpack 中文文档 (docschina.org)

下面是css通过css-loader打包后的伪代码 

const img=require('./image.png')
module.exports=`
div{
 background:url('${img}')
}
`
-------------------------------------------------------------------
经过webpack打包后的资源 通过cjs'引入' esm'导出'的代码如下
{
  _esModule:true,
  default:123
}

由于webpack打包后的esModule导出代码会变成一个对象,里面有一个default属性,default属性才是你真正导出的东西

解决:

 1.

//在require后面加上.default
  
const imgEl = new Image();
  imgEl.src = require('../img/dsj.png').default

2.

{
        test: /\.(png|jpe?g|gif|svg)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              //不使用esModule的语法导出
              esModule: false
            },
          }
        ],
        type: 'javascript/auto'
 }    

推荐使用第二种

 

posted @ 2022-04-11 14:39  Mr-Hou88888  阅读(372)  评论(0编辑  收藏  举报