Vue-loader: Incorrectly translate the included resources in the HTML template

Created on 28 Jul 2015  路  7Comments  路  Source: vuejs/vue-loader

For example, suppose we have a .vue file as follows

<template>
  <div><img src="img/logo.png">{{company}}</div>
</template>
<script>
module.exports = {
  data: {
    company: "My Company"
  }
};
</script>

Use the webpack with vue-loader to compile this file will cause an error: it said that the ".png" file is not recognizable. It seems the vue-loader tries to translate the resources in the HTML template into a "require" command, which is incorrect.

A temporal solution is to use the "v-attr" directive,

<template>
  <div><img v-attr="src:'img/logo.png'">{{company}}</div>
</template>

Most helpful comment

@yyx990803 I couldn't find a solution for this issue in the doc. Luckily, @airtonix helped me solve this issue.

### html
<template><img :src="source"></template> 

### js
<script>
export default { 
  props: ['src'], 
  computed: { 
    source () { 
      return require(asset-images/${this.src}); 
    } 
  } 
};
 </script>

### webpack config
  resolve: {
    extensions: ['', '.js', '.vue', '.less', '.gif'],
    alias: {
      'src': path.resolve(__dirname, '../src'),
      'asset-images': path.resolve(process.cwd(), './src/assets/images')
    }
  }
...
  module: {
    loaders: [
      {
        test: /\.(jpe?g|png|gif)$/i,
        loaders: [
          'file?hash=sha512&digest=hex&name=[name].[hash].[ext]',
          'image-webpack?bypassOnDebug&optimizationLevel=7&interlaced=false'
        ]
      }
...
    ]
  }

It's obviously a Webpack issue(or a way of bundling). But it's such basic thing. I like vue's concept of simplicity and straightforward. I hope vue-loader can make this src load issue one step instead of work around.

All 7 comments

This is because vue-loader loads HTML with html-loader which converts src references into require calls, so that you can use other loaders to do path rewrite / base64 inlining, etc.

If you want to preserve raw URLs, overwrite default html-loader with raw-loader in your webpack config (also npm install raw-loader --save-dev):

var vue = require('vue-loader')

module.exports = {
  // other options ...
  module: {
    loaders: [
      {
        test: /\.vue$/,
        loader: vue.withLoaders({
          html: 'raw'
        })
      },
    ]
  }
}

OK, I got it. Thank you very much.

BTW: could you please add this trick to the document? I think many people will encounter the same problem as mine.

Error: vue.withLoaders has been deprecated in vue-loader 6.0. Add a "vue" section to the webpack config instead.

@yyx990803 What's the update on this issue?

@GitYong please read the docs.

@yyx990803 I couldn't find a solution for this issue in the doc. Luckily, @airtonix helped me solve this issue.

### html
<template><img :src="source"></template> 

### js
<script>
export default { 
  props: ['src'], 
  computed: { 
    source () { 
      return require(asset-images/${this.src}); 
    } 
  } 
};
 </script>

### webpack config
  resolve: {
    extensions: ['', '.js', '.vue', '.less', '.gif'],
    alias: {
      'src': path.resolve(__dirname, '../src'),
      'asset-images': path.resolve(process.cwd(), './src/assets/images')
    }
  }
...
  module: {
    loaders: [
      {
        test: /\.(jpe?g|png|gif)$/i,
        loaders: [
          'file?hash=sha512&digest=hex&name=[name].[hash].[ext]',
          'image-webpack?bypassOnDebug&optimizationLevel=7&interlaced=false'
        ]
      }
...
    ]
  }

It's obviously a Webpack issue(or a way of bundling). But it's such basic thing. I like vue's concept of simplicity and straightforward. I hope vue-loader can make this src load issue one step instead of work around.

@GitYong Yeah, this is somewhat annoying, but I think the solution you found above is a decent workaround. When using webpack + file-loader, you are treating static files as module dependencies, and you need a way to let webpack translate the pre-build relative path into the after-build public path (which can be at a different location and with hashes). Static paths inside templates can be translated at build time by vue-html-loader, but in JavaScript you need to use the require call to let webpack do the translation.

@ElementLi Saved my day 馃憤

Was this page helpful?
0 / 5 - 0 ratings