Stove Games Games
Stove Games Games

Reputation: 115

Vue 3 Resolving Image Assets Build

So I'm trying to build and deploy a Vue 3 website using Heroku. When I test the website locally using npm run dev it works just fine. However, when building I get the following error

Error:

Could not resolve './assets/Design%20Pics/Drone/7_0030.png' from src/App.vue
error during build:
Error: Could not resolve './assets/Design%20Pics/Drone/7_0030.png' from src/App.vue
    at error (C:\Users\stove\Desktop\Aero Website\AeroWebsite\node_modules\rollup\dist\shared\rollup.js:198:30)
    at ModuleLoader.handleResolveId (C:\Users\stove\Desktop\Aero Website\AeroWebsite\node_modules\rollup\dist\shared\rollup.js:22508:24)
    at C:\Users\stove\Desktop\Aero Website\AeroWebsite\node_modules\rollup\dist\shared\rollup.js:22471:26

code:

Note: it's a fragment of the overall code, this is where the "issue" is. Also, I'm using Bulma to style

<section class="section">

<!-- to center columns, the parent has to be the image which is impossible -->
    <div class="card">

      <div class="card-image">
        <figure class="image is-2by1 level">
          <img src="./assets/Design Pics/Drone/7_0030.png" alt="Drone Image" width="1280" height="720">

          <div id="title-overlay-pad" class="is-overlay level-right">
            <div id="title-overlay-background" class="has-text-centered">
              <p id="title-home-page">delivAERO</p>
              <p id="tagline-home-page">Revolutionizing the World's Delivery Infrastructure</p>
            </div>
          </div>
        </figure>
      </div>

    </div>


  </section>

Heiarchy:

enter image description here


UPDATE: ANOTHER SOLUTION

After getting a lot of help from Daniel, using the import method mentioned in their answer I was still getting errors. I assume this is more about the way the project is setup, but I found another solution. The way, this post mentions is, it should be imported is as

import img from '@/assets/path/to/img.png'

Note: I have all my images in the assets folder on the src directory

However, this may give the following error:

error TS1232: An import declaration can only be used at the top level of a namespace or module.

From this post, the reason for this error is because imports should be declared first before any Javascript code.

In other words, it should look like:

<script setup lang="ts">
  //any other imports here, before javascript code
  import img from '@/assets/path/to/img.png'; // ASSETS
  
  // Javascript code here
</script>

I'll still be accepting Daniel's answer as I believe that should be the solution for most.

Upvotes: 2

Views: 7475

Answers (1)

Daniel
Daniel

Reputation: 35684

Update

both require and import should work with default setup (used latest ATTOW vue-cli 5.0.6 and vue 3.2.13)

I've setup a new project with vue-cli and updated the helloWorld component with:

<template>
  <div class="hello">
    <img src="/images/logo.png">
    <img :src="img"/>
    <img :src="require('../assets/logo.png')">
  </div>
</template>

<script setup>
import img from "../assets/logo.png"
</script>

All three versions work for me. If you are still having issues, I'd recommend the 1st option <img src="/images/logo.png">. The only thing you need to do is to move the image (logo.png) into the public folder (public/images/logo.png)

I've also noticed that with the default settings, the images that are "imported" or "required" get injected into the js as base64, which I'm not a fan of, so unless the configuration is updated to handle those, I'd recommend the first option.

AS an aside, I would also recommend removing spaces from the resource and directory names. You have a space in Design Pics, which servers should all handle properly, but it's not guaranteed .


When you use the image like this in the template, it is handled as a string

<img :src="./assets/Design Pics/Drone/7_0030.png" alt="Drone Image" width="1280" height="720">

In order for Vue to bundle the asset it needs to know about it.

you can do this reference in-template

You can import it and then pass the reference the image as the variable in the template

<template>
  <div>
    <img :src="myImg" alt="Drone Image" width="1280" height="720">
  </div>
</template>

<script setup>
import myImg from './assets/Design Pics/Drone/7_0030.png'; // import asset

</script>

or use require in the template:

<template>
  <div>
    <img :src="require(./assets/Design Pics/Drone/7_0030.png)" alt="Drone Image" width="1280" height="720">
  </div>
</template>

Upvotes: 2

Related Questions