Vue-loader: 'src' of img tag become src="[object Module]" in browser

Created on 28 Nov 2019  路  15Comments  路  Source: vuejs/vue-loader

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.

bug contribution welcome

Most helpful comment

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.

All 15 comments

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.

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

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

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

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

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

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

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

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)

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!

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 }));

You can also add this to your Vue config:

```js
/* 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,
},
}
})
// ...
}
}

Is this a non-issue in Vue 3?

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

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

@sodatea

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lijialiang picture lijialiang  路  3Comments

snoopdouglas picture snoopdouglas  路  3Comments

chrisvfritz picture chrisvfritz  路  4Comments

yozman picture yozman  路  4Comments

matt-sanders picture matt-sanders  路  4Comments