vue-loader not processing images in dynamic component

Created on 16 May 2017  ·  8Comments  ·  Source: vuejs/vue-loader

Vue Team,

Thanks for all that you do for the dev community.

I'm not sure if this is an issue or a configuration problem. One of the contributors to webpack has been helping me sort an issue but we are at a point where he thinks it may be a vue-loader issue.

I have a dynamic component/slot that is called via the data captured and passed by an Event Bus. This all work great and in development mode everything works as expected. When I build out the production folder the dynamic .vue template files are processed and placed in the correct directory (in the assets/modals folder) but none of the hard/static coded src links or src images in the template files are processed (no image hash and link hash updates are applied).

I have a setup on github that's working via a hack (I am using Copy Webpack Plugin to copy over all the files in the directory) but this is just a quick fix for the above outlined issue.

Here is the github repository:
https://github.com/jh-thank-you/webpack-w-gsap

Thanks again.

All the best,

Jim

Most helpful comment

<img :src="require(``@/assets/${posts.img}``)" alt="">

Care for back ticks , must have only 1.

This is it.

All 8 comments

Can you tell me a specific component that this is happening for so I don't havd to look through your whole project?

That would be helpful, thanks :)

Thank you (very much) for the help.

Yes, in the assets/modals folder any of the three modals ( for example modalPrintAdvil.vue) have src files (which are hard coded/not dynamic links) that are not being processed and hashed like the other non-dynamic components.

I hope this clears things up.

Thanks again.

You need to use relative paths (start with ./) or start the url with ~ for it to be considered a module request.

Update
Note there are workarounds BUT Webpack aliases are not honored. See notes below.

First issue solved with a slight change to Evan's comment above.
Second issue solved by a different approach found on Stack Overflow and kindly referenced in https://github.com/vuejs/Discussion/issues/202

Evan,

Thank you for taking the time to look into this.

My webpack aliases are set to./and ~ — alias (shortened) paths only work in CSS files with ~

      alias: { 
      'vue$': 'vue/dist/vue.esm.js',
      assets: path.resolve(__dirname, './assets'),
      components: path.resolve(__dirname, './assets/components'),
      css: path.resolve(__dirname, './assets/css'),
      fonts: path.resolve(__dirname, './assets/fonts'),
      img: path.resolve(__dirname, './assets/img'),
      js: path.resolve(__dirname, './assets/js'),
      modals: path.resolve(__dirname, './assets/modals'),
      scss: path.resolve(__dirname, './assets/scss'),
    },

In the modalPrintAdvil.vue template component - I'm not sure why (for the production build):

This path alias does not work:
src="~assets/modalPrintAdvil1c.jpg"

This relative path does not work:
src="./assets/img/modalPrintAdvil1c.jpg"

This works:
src="~assets/img/modalPrintAdvil1c.jpg"

I will also share this with Juho, one of the webpack contributors, and see if he can shine a bit of light on why the path aliases within a vue template component are not working. I will report back.

======== Second Issue Solved - See StackOverflow link Below ========
Also, I forgot to point out, the modal-button.vue component/template file has a programmatic link
:src="'assets/img/' + this.id + '1a-sm.png'"

This works great for the dev build but for production it does not process the images. As a workaround I have placed all of these thumbnail images in assets/img-dynamic and use copy-webpack-plugin to copy over the files/directory.

    new CopyWebpackPlugin([
        { from: 'assets/img-dynamic', to: 'assets/img-dynamic/[name].[ext]' }
    ]),

This partially solves the issue but it does not take advantage of hashed image names and links for caching.

I tried the ./ and ~ options with this modal-button component but none of these options worked.

I am researching:
https://github.com/vuejs-templates/webpack/issues/126 - Does not work
https://github.com/vuejs/vue-loader/issues/193 - Does not work
https://github.com/vuejs-templates/webpack/issues/609 - Does not work

https://github.com/vuejs/Discussion/issues/202 the Stack Overflow link in this discussion is the solution that worked for dynamic URLs in the Vue Template files:
https://stackoverflow.com/questions/40491506/vue-js-dynamic-images-not-working
and the fiddle with the working code:
https://jsfiddle.net/q2rzssxr/

in case the link dies here is the fiddle code:

<div id="app">
  <div class="col-lg-2" v-for="(pic, index) in pics">
    <img :src="getPic(index)" v-bind:alt="pic"> {{getPic(index)}}
  </div>
</div>
new Vue({
  el: '#app',
  methods: {
    getPic(index) {
      return '../assets/' + this.pics[index] + '.png';
    }
  },
  data() {
    return {
      pics: ['dog', 'cat', 'fish']
    }
  }
});

This approach has the programmatic links for the thumbnail images called my modal-button.vue component being processed and hashed through the appropriate loader without the need for the subdirectory/Copy Webpack Plugin workaround.

The repo has been updated with the above fixes:
https://github.com/jh-thank-you/webpack-w-gsap

I hope this helps others.

Thanks again.

Try this link 👉🏻this works for me.

<img :src="require(``@/assets/${posts.img}``)" alt="">

Care for back ticks , must have only 1.

This is it.

@kaankucukx Works, thanks a lot.

@kaankucukx You're a life saver, thanks 😂

Was this page helpful?
0 / 5 - 0 ratings