0

I have a vue application with single file components, and I'm using webpack. One of the components has an image that works fine locally when I run it with npm run serve, but when I build the application (using npm run build) and deploy it online, I just see the broken image icon.

The image is is referenced in this in the component:

<img id="sockPhoto" :src="require('../assets/a_sock.png').default" alt="a_sock">    

but if I inspect the same element in the deployed version, I see this:

<img data-v-f9e5c994="" id="sockPhoto" alt="a_sock">

which doesn't even have a src attribute.

This is the relevant part of my package.json:

{
  "name": "my-app ",
  "version": "0.2.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "test": "jest"
  },
  "dependencies": {
    "bootstrap": "^4.5.0",
    "bootstrap-vue": "^2.15.0",
    "core-js": "^3.6.5",
    "file-loader": "^6.0.0",
    "jquery": "^3.5.1",
    "jspdf": "^1.5.3",
    "popper.js": "^1.16.1",
    "portal-vue": "^2.1.7",
    "printd": "^1.4.2",
    "vue": "^2.6.10"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "^4.3.1",
    "@vue/cli-plugin-eslint": "^4.3.1",
    "@vue/cli-service": "^4.4.1",
    "@vue/test-utils": "^1.0.3",
    "babel-core": "^7.0.0-bridge.0",
    "babel-eslint": "^10.1.0",
    "babel-jest": "^26.0.1",
    "eslint": "^5.16.0",
    "eslint-plugin-vue": "^5.0.0",
    "jest": "^26.0.1",
    "vue-jest": "^3.0.5",
    "vue-template-compiler": "^2.6.11",
    "vue-test-utils": "^1.0.0-beta.11"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "eslint:recommended"
    ],
    "rules": {},
    "parserOptions": {
      "parser": "babel-eslint"
    }
  },
  "browserslist": [
    "> 1%",
    "last 2 versions"
  ],
  "jest": {
    "moduleFileExtensions": [
      "js",
      "json",
      "vue"
    ],
    "transform": {
      "^[^.]+.vue$": "vue-jest",
      "^.+\\.js$": "babel-jest"
    },
    "transformIgnorePatterns": [
      "/node_modules/"
    ],
    "moduleNameMapper": {
      "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
      "\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js"
    }
  }
}

Also, this was working before my latest deployment, which contained some modifications, but nothing I can think of that should mess this up.

I am relatively new to vue and webpack so all help is much appreciated.

EDIT: I have already tried the basic <img id="sockPhoto" src="./../assets/36_37.png" alt="a_sock">, but that didn't even work locally. This answer provided me with the method above, using require(...).default which was working fine until this last deployment.

Nanna
  • 515
  • 1
  • 9
  • 25
  • What happens if you move the `require` statement to either a computed property or as part of the component data? – Terry Jun 01 '20 at 20:55
  • Did u try to force refresh by ctr+f5? –  Jun 01 '20 at 20:58
  • @Terry I just tried that and it behaves the same, no src attribute in the img tag. – Nanna Jun 01 '20 at 21:07
  • @mabujaber Yes I have tried a hard refresh but the problem persists. – Nanna Jun 01 '20 at 21:08
  • If you're importing the PNG file as a module, you probably need to use `file-loader` to do that for you. Are you using Vue CLI? – Terry Jun 01 '20 at 21:13
  • @Terry yes I am using vue cli. I have "file-loader": "^6.0.0" installed but I searched for a config for it earlier and i found no references to file-loader anywhere else other than in package.json. Could there be something missing? And if there are other, more sensible methods to import a png than as a module I would love to hear about them. I just want the image to appear on my website, no preferences on how it makes it there. – Nanna Jun 01 '20 at 21:18
  • Where is the assets folder sitting in your project? Vue CLI has file-loader configured natively so you shouldn't need to tweak it. Might want to look into using the `@` alias so that you're using the correct path: https://cli.vuejs.org/guide/html-and-static-assets.html#static-assets-handling – Terry Jun 01 '20 at 21:24
  • It is under src, on the same level as components. Under components there is SockRecipe.vue where I am trying to import the image. Inside the same asset folder are some other images that I can import without problems as background images using e.g. `background: url('assets/sweater.png'); – Nanna Jun 01 '20 at 21:55
  • 1
    I'm not sure whether required to bind src!! you are using relative path directly without binding so, try to remove the binding and make it src="../assets/a_sock.png" or whatever the path is –  Jun 02 '20 at 08:27
  • 1
    Have you tried creating a new, completely fresh vue project and recreate the issue? If it works in a completely fresh environment, then something is just off in your current build. It should help to look at the issue in isolation. Other than that I know it isn't what you asked for but have you considered using a dedicated storage like S3 to host your images and directly link to that ressource instead of bundling it? – discolor Jun 02 '20 at 11:22
  • 1
    Thank you for this advice @Rie, in a fresh vue cli project this wasn't an issue, and I was able to backtrack and fix it. Now I no longer have to load the image as a module, but can include it like `sokkur` without problems. Unfortunately I'm not sure what caused this to break, because this is what I started out with, but happy that it works now. (Also interesting thought to use S3, will keep that in the back of my mind!) – Nanna Jun 05 '20 at 23:01

0 Answers0