1

I'm trying to bind background images dynamically but there seems to be trouble compiling the assets. What's weird is that it works but no at the same time. vue_dynamic_image_err_compile

I've tried various solutions from SO and nothing get rids of the compilation error (which still compile based on the image above):

How The Project is Set Up

Laravel Sanctum as the backend, Vue SPA for the frontend and utilising Axios for communications.

Topic.vue Component

<div
    v-for="topic in topics"
    :key="topic.id"
    class="col-12 col-sm-6 col-lg-3 mb-4 d-flex justify-content-center"
>
    <div
        class="card-topic d-flex align-items-end"
        :style="inlineBgImage(topic.src)"
    >
        <div class="card-topic__button py-3 text-center w-100">
            <a href class="card-topic__link">{{ topic.title }}</a>
        </div>
    </div>
</div>

Script in Topic.vue

<script>
import { mapState } from 'vuex'

export default {
    computed: {
        ...mapState('topic', ['topics']),
    },
    created() {
        this.$store.dispatch('topic/fetchTopics')
    },
    methods: {
        inlineBgImage(src) {
            let bgImage = require('@/assets' + src)

            return {
                backgroundImage: `url("${bgImage}")`,
            }
        },
    },
}
</script>

In the inlineBgImage(src) methods, the background-image is successfully applied if the require is hardcoded i.e. let bgImage = require('@/assets/img/topic/myself.jpg'). Once I used the src value, it broked but still works(Failed to compile. page appear)

Assets

Below is the asset folder structure

enter image description here

All SCSS files are imported to app.scss which are then imported to main.js

_variables.scss

enter image description here

The "undefined variable" does exist

app.scss

This is how I import the _variable.scss file in app.scss; @import 'variables.scss';. The import comes first before other files. enter image description here

I've also tried:

  • @import 'variables';
  • @import '_variables';
  • @import '_variables.scss';

It still gives out errors.

Error Details in Terminal

I want to reiterate that these errors does not appear if I hardcode the bgImage e.g. require('@/assets/img/topic/myself.jpg'). I don't understand how these changes affect the compiler.

ERROR  Failed to compile with 6 errors                                                                                                  12:37:58 PM
 error  in ./src/assets/scss/card.scss

Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: Undefined variable.
   ╷
16 │     background-color: $dark-blue;
   │                       ^^^^^^^^^^
   ╵
  src\assets\scss\card.scss 16:23  root stylesheet

 @ ./src/assets/scss/card.scss 4:14-233 14:3-18:5 15:22-241
 @ ./src sync ^\.\/assets.*$
 @ ./node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/babel-loader/lib!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/views/Topic.vue?vue&type=script&lang=js&
 @ ./src/views/Topic.vue?vue&type=script&lang=js&
 @ ./src/views/Topic.vue
 @ ./src/router/index.js
 @ ./src/main.js
 @ multi (webpack)-dev-server/client?http://192.168.100.14:8080&sockPath=/sockjs-node (webpack)/hot/dev-server.js ./src/main.js

 error  in ./src/assets/scss/search.scss

Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: Undefined variable.
   ╷
27 │     color: $blue;
   │            ^^^^^
   ╵
  src\assets\scss\search.scss 27:12  root stylesheet

 @ ./src/assets/scss/search.scss 4:14-235 14:3-18:5 15:22-243
 @ ./src sync ^\.\/assets.*$
 @ ./node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/babel-loader/lib!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/views/Topic.vue?vue&type=script&lang=js&
 @ ./src/views/Topic.vue?vue&type=script&lang=js&
 @ ./src/views/Topic.vue
 @ ./src/router/index.js
 @ ./src/main.js
 @ multi (webpack)-dev-server/client?http://192.168.100.14:8080&sockPath=/sockjs-node (webpack)/hot/dev-server.js ./src/main.js

 error  in ./src/assets/scss/image.scss

Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: Undefined variable.
   ╷
33 │     color: $white;
   │            ^^^^^^
   ╵
  src\assets\scss\image.scss 33:12  root stylesheet

 @ ./src/assets/scss/image.scss 4:14-234 14:3-18:5 15:22-242
 @ ./src sync ^\.\/assets.*$
 @ ./node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/babel-loader/lib!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/views/Topic.vue?vue&type=script&lang=js&
 @ ./src/views/Topic.vue?vue&type=script&lang=js&
 @ ./src/views/Topic.vue
 @ ./src/router/index.js
 @ ./src/main.js
 @ multi (webpack)-dev-server/client?http://192.168.100.14:8080&sockPath=/sockjs-node (webpack)/hot/dev-server.js ./src/main.js

 error  in ./src/assets/scss/button.scss

Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: Undefined variable.
  ╷
2 │     color: $light-blue;
  │            ^^^^^^^^^^^
  ╵
  src\assets\scss\button.scss 2:12  root stylesheet

 @ ./src/assets/scss/button.scss 4:14-235 14:3-18:5 15:22-243
 @ ./src sync ^\.\/assets.*$
 @ ./node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/babel-loader/lib!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/views/Topic.vue?vue&type=script&lang=js&
 @ ./src/views/Topic.vue?vue&type=script&lang=js&
 @ ./src/views/Topic.vue
 @ ./src/router/index.js
 @ ./src/main.js
 @ multi (webpack)-dev-server/client?http://192.168.100.14:8080&sockPath=/sockjs-node (webpack)/hot/dev-server.js ./src/main.js

 error  in ./src/assets/scss/header.scss

Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: Undefined variable.
  ╷
4 │     background-color: $dark-blue;
  │                       ^^^^^^^^^^
  ╵
  src\assets\scss\header.scss 4:23  root stylesheet

 @ ./src/assets/scss/header.scss 4:14-235 14:3-18:5 15:22-243
 @ ./src sync ^\.\/assets.*$
 @ ./node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/babel-loader/lib!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/views/Topic.vue?vue&type=script&lang=js&
 @ ./src/views/Topic.vue?vue&type=script&lang=js&
 @ ./src/views/Topic.vue
 @ ./src/router/index.js
 @ ./src/main.js
 @ multi (webpack)-dev-server/client?http://192.168.100.14:8080&sockPath=/sockjs-node (webpack)/hot/dev-server.js ./src/main.js

 error  in ./src/assets/scss/nav.scss

Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: Undefined variable.
  ╷
6 │     color: $light-blue;
  │            ^^^^^^^^^^^
  ╵
  src\assets\scss\nav.scss 6:12  root stylesheet

 @ ./src/assets/scss/nav.scss 4:14-232 14:3-18:5 15:22-240
 @ ./src sync ^\.\/assets.*$
 @ ./node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/babel-loader/lib!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/views/Topic.vue?vue&type=script&lang=js&
 @ ./src/views/Topic.vue?vue&type=script&lang=js&
 @ ./src/views/Topic.vue
 @ ./src/router/index.js
 @ ./src/main.js
 @ multi (webpack)-dev-server/client?http://192.168.100.14:8080&sockPath=/sockjs-node (webpack)/hot/dev-server.js ./src/main.js

Other Details

The topic.src from v-for="topic in topics" will yield a String, for e.g. /img/topic/myself.jpg.

Afiq Rosli
  • 357
  • 1
  • 7
  • 22
  • Yes, it does and as I've mentioned, hardcoding it works but not dynamically. @tony19 I've edited the post showing that it is defined – Afiq Rosli Aug 27 '20 at 04:18
  • Wouldn't `let bgImage = require('@/assets/img/topic/myself.jpg')` be equivalent to `let bgImage = require('@/assets' + src)` given that `src` equals to `/img/topic/myself.jpg`? – Afiq Rosli Aug 27 '20 at 04:24
  • I don't even know how it breaks the styling. That's why I'm asking for help. I would appreciate it if you could guide me on this issue. – Afiq Rosli Aug 27 '20 at 04:30
  • It seems like you didn't `@import` the `_variables.scss` right before using them. – Yom T. Aug 27 '20 at 04:50
  • Hey, I've tried various statement after you mentioned that. You can see from the edit I've made. How should I import it @YomS.? – Afiq Rosli Aug 27 '20 at 05:04
  • That being imported foremost should normally work, what's the error pertaining to that specifically? – Yom T. Aug 27 '20 at 05:09
  • All I know is that the error is caused by dynamically requiring assets; `require('@/assets' + src)`. I don't know any more from that. – Afiq Rosli Aug 27 '20 at 05:12

1 Answers1

0
inlineBgImage(src) {
    let fileExt = src.substring(src.lastIndexOf('.'))

    src = src.replace('/img/', '')
    src = src.replace(fileExt, '')

    let bgImage = require('@/assets/img/' + src + fileExt)

    return {
        backgroundImage: `url("${bgImage}")`,
    }
}

Kudos to skirtle for giving a solution at forum.vuejs.org. As skirtle mentioned, Webpack handles expression and fixed string parameter differently. I did change the solution a bit in case future files have different file extension. You see skirtle original answer and explanation there.

Afiq Rosli
  • 357
  • 1
  • 7
  • 22