Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue.js 2: Vue cannot find files from /assets folder (v-for)

I am using Vue-cli 3 with Webpack, and my folder structure looks like this:

/public
/src
   /assets
      p1.jpg
      p2.jpg
App.vue
main.js

I read in several places that in order for Webpack to know where your /assets are, you should use require() if you are in Javascript land.

I have determined that this code works:

<template>
    <div>
        <ul>
            <li v-for="photo in photos" :key="photo.id">
                <img :src="photo.imageUrls.default" />
            </li>
        </ul>
    </div>
</template>


<script>
    /* For webpack to resolve URLs in javascript during the build, you need the require() function */
    export default {
        data() {
            return {
                photos: [
                    {
                        id: 1,
                        caption: 'P1',
                        series: '',
                        notes: '',
                        imageUrls: {
                            default: require('./assets/p1.jpg')
                        }
                    },
                    {
                        id: 2,
                        caption: 'P2',
                        series: '',
                        notes: '',
                        imageUrls: {
                            default: require('./assets/p2.jpg')
                        }
                    }
                ]
            }
        }
    }
</script>

But, this does not work. I am seeing an error in the console: "Error: Cannot find module './assets/p1.jpg'"

<template>
        <div>
            <ul>
                <li v-for="photo in photos" :key="photo.id">
                    <img :src="imagePath(photo)" />
                </li>
            </ul>
        </div>
</template>


<script>
    /* For webpack to resolve URLs in javascript during the build, you need the require() function */
    export default {
        data() {
            return {
                photos: [
                    {
                        id: 1,
                        caption: 'P1',
                        series: '',
                        notes: '',
                        imageUrls: {
                            default: './assets/p1.jpg'
                        }
                    },
                    {
                        id: 2,
                        caption: 'P2',
                        series: '',
                        notes: '',
                        imageUrls: {
                            default: './assets/p2.jpg'
                        }
                    }
                ]
            }
        },
        methods: {
            imagePath(photo) {
                return require(photo.imageUrls.default);
            }
        }
    }
</script>

Is there anybody who can help explain what is wrong in the second example? I wish to avoid putting require() calls into the data, as that data could come from a server, and it seems weird to me to put a require() call in the data. Thanks.

EDIT: Per Edgar's advice below, since my images are part of the server and not the app, I can just put them into a folder in the /public folder, and not deal with require() at all.

like image 539
Stephen Avatar asked Aug 29 '18 17:08

Stephen


3 Answers

Vue.js has a public folder. If you are using the Vue CLI, it should have created a public folder for you, you have to place any assets in this folder. Read more about it in the official Vue.js documentation.

Example folder structure:

/api
/public
/public/assets
/public/favicon.ico
/public/index.html
/src
index.js
app.json

etc...

In public you could put static assets such as images, fonts, favicon, robots.txt, sitemap.xml, etc.

Then to link to these static assets you'd use:

In your template HTML:

<img src="/assets/some-image.svg" alt="Example" />

Or in your component JS:

array: [
        {
          iconUrl: '/assets/some-image-1.svg',
          label: 'Some Label'
        }
      ]

Otherwise you'd have to use require since it is being pulled from the src folder, as someone else has already said. But there probably wouldn't be a real reason to have them in there, so using /public/ folder is recommended.

like image 103
Edgar Quintero Avatar answered Nov 04 '22 14:11

Edgar Quintero


You need the require because your resource is bundled on the client.

If you want you resource on the server, put it in the public folder instead.

Another issue we often see is when your component in the components folder. If so, try:

default: require('../assets/p1.jpg')
like image 4
Steven Spungin Avatar answered Nov 04 '22 14:11

Steven Spungin


I think this question is a common problem that you can search for. The solution is to put the resource file in the static directory. The files in the asset folder will be processed by webpack, so there is no problem in html module ,buy there is a problem in the code module.

like image 1
kaluogh Avatar answered Nov 04 '22 15:11

kaluogh