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>
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 馃憤
Most helpful comment
@yyx990803 I couldn't find a solution for this issue in the doc. Luckily, @airtonix helped me solve this issue.
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.