vuejs / vue-loader

📦 Webpack loader for Vue.js components
MIT License
4.99k stars 915 forks source link

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

Open zhangwang945 opened 5 years ago

zhangwang945 commented 5 years ago

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.

haoqunjiang commented 5 years ago

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.

zhangwang945 commented 5 years ago

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

amitsaxena commented 4 years ago

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]".

Moongazer commented 4 years ago

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]"

itsmepetrov commented 4 years ago

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
      }
    }
  ]
}
phlegx commented 4 years ago

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
carlos-avila commented 4 years ago

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

ederuiter commented 4 years ago

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

ondrejbartas commented 4 years ago

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)

aqeebimtiaz commented 4 years ago

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!

kinoli commented 4 years ago

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 }));
phlegx commented 4 years ago

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,
          },
        }
      })
    // ...
  }
}  
icleolion commented 4 years ago

Is this a non-issue in Vue 3?

shirhen commented 3 years ago

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

Airkro commented 3 years ago

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

@sodatea

staticish commented 2 years ago

i need help with this using React

luishnzg commented 1 year ago

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