19

I'm trying to bind image src dynamically to a URL of the form ../assets/project_screens/image_name.jpg.

My directory structure looks like:

- src
 -- assets
   ---- project_screens
 -- profile
   ---- ProjectList.vue 
 -- store
   ---- profile.js

I know that I need to use webpack's require("path/to/image") to help webpack build those images, but the path doesn't resolve.

// store/profile.js
projects = [
  {
    ....
  },
  {
    ....
    img_url: "../assets/project_screens/im1.jpg"
    ....
  }
  ....
]
// profile/ProjectList.vue
<md-card
   class="md-layout-item project-card"
   v-for="(project, idx) in projects"
   :key="idx"
 >
    <md-card-media>
        <img :src="require(project.img_url)" alt="People" />
    </md-card-media>
</md-card>

If I used a URL string instead of dynamically passing the URL string it works. Looked around stack overflow and none of the solutions helped. Am I missing something else ?

Martin Brisiak
  • 3,872
  • 12
  • 37
  • 51
socket_var
  • 1,063
  • 2
  • 11
  • 18
  • I just use a method() in src attribute that calls a nodejs function that reads and responses it's contents. Works like a charm. – Marco Aug 04 '19 at 18:40
  • please try to reproduce your issue based on [this example](https://codesandbox.io/s/vue-examples-m1zgo) – Boussadjra Brahim Aug 04 '19 at 18:46
  • Made a little demo at https://codesandbox.io/s/vue-examples-7crvi in App.vue but it gives a different error that "file_name hasn't been transpiled yet" where as it errored out "Cannot find module '../assets/project_screens/image.jpg'" when I ran locally..! – socket_var Aug 04 '19 at 19:00

2 Answers2

42

I finally figured it out!! Webpack cannot import the file if its name is completely given as a variable like:

require(imageUrl) // doesn't work

This is because it doesn't know the path at compile time if the path is stored in a variable.

But Webpack can detect files to bundle when it is given a string interpolation in require() like:

require(`../assets/profile_screens/${filename}`) // Works

This works because Webpack knows the path "../assets/profile_screens" at compile time so it can include all the files inside the folder.

socket_var
  • 1,063
  • 2
  • 11
  • 18
  • 1
    You could also use `require()` in your `projects` array definition as opposed to within your template – Phil Aug 05 '19 at 02:17
  • 2
    Sure @Phil, but if I move to a database later I need to refactor them again right? – socket_var Aug 05 '19 at 05:17
  • 3
    Thank you a thousand times! I was struggling with issues all morning using require() in a vue project, and it was when I finally saw this answer that it dawned on me, of course a variable wouldn't work because it's doing the processing at compile-time! – Bron Thulke May 12 '20 at 05:23
0

The syntax below worked for me:

<img :src="`${project.img_url}`" alt="People" />

It works with full url.

require() not required.

Martin Brisiak
  • 3,872
  • 12
  • 37
  • 51