vue-loader icon indicating copy to clipboard operation
vue-loader copied to clipboard

'src' of img tag become src="[object Module]" in browser

Open zhangwang945 opened this issue 5 years ago • 17 comments

Version

15.7.2

Reproduction link

https://github.com/zhangwang945/vue-test.git

Steps to reproduce

webpack 4.41, url-loader 3.0.0 . Clone code https://github.com/zhangwang945/vue-test.git. Then npm run start. img src="./assets/jinnang.png" become img src="[object Module]"

What is expected?

src="base64 image"

What is actually happening?

src="[object Module]"


Img tag in template will be compiled into: {attrs:{"src":webpack_require(/*! ./assets/jinnang.png */ "./src/assets/jinnang.png"),"alt":""}} The reult of webpack_require(....) is Object Module ,so it go wrong. Is it right?

Url in css will be compiled into getUrl(webpack_require(/*! ./assets/jinnang.png */ "./src/assets/jinnang.png"),that go well.

zhangwang945 avatar Nov 28 '19 03:11 zhangwang945

Workaround: set the esModule option in url-loader to false.

It's because in @vue/component-compiler-utils we transformed the asset urls to require statements, which expect CommonJS modules, while the recent major release of url-loader emits ES modules by default.

haoqunjiang avatar Nov 28 '19 06:11 haoqunjiang

Oh...! I see. I'm careless!

zhangwang945 avatar Nov 28 '19 10:11 zhangwang945

Was this issue fixed and released? I seem to have run into a similar scenario when using rails (v6.0.2.2) with webpacker (5.0.1) and vue-loader (v15.9.1). Existing images which were previously rendered fine now show source as src="[object Module]".

amitsaxena avatar Apr 12 '20 01:04 amitsaxena

I seem to have run into a similar scenario when using rails (v6.0.2.2) with webpacker (5.0.1) and vue-loader (v15.9.1).

Same for me, I've just started a project and v15.9.1 was loaded from repro. My image sources showing src="[object Module]"

Moongazer avatar Apr 12 '20 09:04 Moongazer

If you use file-loader, upgrade it to 6.0.0 version and specify esModule: false in options:

{
  test: /\.(png|jpe?g|gif|svg)$/,
  use: [
    {
      loader: 'file-loader',
      options: {
        name: '[name].[contenthash].[ext]',
        outputPath: 'static/img',
        esModule: false // <- here
      }
    }
  ]
}

itsmepetrov avatar Apr 16 '20 09:04 itsmepetrov

For Rails with Vue developer

@rails/webpacker: 5.0.1

Add the following line in file config/webpack/environment.js:

/* Fix a bug for file inclusion like <img :src="require()"/> */
environment.loaders.get('file').use.find(item => item.loader === 'file-loader').options.esModule = false

before

module.exports = environment

phlegx avatar Apr 16 '20 18:04 phlegx

This issue is also present in Nuxt 2.12.0

You can still access the string value through the 'default' property: require('@/assets/images/logo-1.png').default

carlos-avila avatar Apr 24 '20 23:04 carlos-avila

Downgrading to file-loader to ^2.0.0 (which is the version laravel mix depends on) seems to "fix"/prevent the problem as well.

ederuiter avatar May 04 '20 09:05 ederuiter

For Rails with Vue developer

@rails/webpacker: 5.0.1

Add the following line in file config/webpack/environment.js:

/* Fix a bug for file inclusion like <img :src="require()"/> */
environment.loaders.get('file').use.find(item => item.loader === 'file-loader').options.esModule = false

before

module.exports = environment

I spend with this problem 4 hours until I found your solution. (BTW it worked for me for loading fonts and images in SASS files)

ondrejbartas avatar Jun 26 '20 00:06 ondrejbartas

If you use file-loader, upgrade it to 6.0.0 version and specify esModule: false in options:

{
  test: /\.(png|jpe?g|gif|svg)$/,
  use: [
    {
      loader: 'file-loader',
      options: {
        name: '[name].[contenthash].[ext]',
        outputPath: 'static/img',
        esModule: false // <- here
      }
    }
  ]
}

weirdly enough, this simple fix helped on my React project too lol!

aqeebimtiaz avatar Jul 16 '20 05:07 aqeebimtiaz

After installing Storybook in my vue app, this same error came up. My fix within chainWebpack inside vue.config.js was to add this.

config.module
      .rule('svg')
      .use('file-loader')
      .loader('file-loader')
      .tap(options => Object.assign(options, { esModule: false }));

kinoli avatar Oct 20 '20 23:10 kinoli

You can also add this to your Vue config:

/* vue.config.js */

module.exports = {
  chainWebpack: (config) => {
    config.module
      .rule('vue')
      .use('vue-loader')
      .tap((options) => {
        const transformAssetUrls = options.transformAssetUrls || {}
        return {
          ...options,
          transformAssetUrls: {
            video: ['src', 'poster'],
            source: 'src',
            img: 'src',
            image: 'xlink:href',
            // Add any other pre defined custom asset items
            ...transformAssetUrls,
          },
        }
      })
    // ...
  }
}  

phlegx avatar Oct 21 '20 06:10 phlegx

Is this a non-issue in Vue 3?

icleolion avatar Oct 27 '20 16:10 icleolion

Is there any update on this bug? that is not a workaround 🤔

shirhen avatar Apr 12 '21 07:04 shirhen

I create https://github.com/vuejs/vue-loader/pull/1824 to fix it but need help for test suit compact.

@sodatea

Airkro avatar Jul 22 '21 09:07 Airkro

i need help with this using React

staticish avatar Jul 14 '22 16:07 staticish

hi, you can import it and add ".src" at the end like this:
image

luishnzg avatar May 23 '23 23:05 luishnzg