Vue3 how to use remote images

Viewed 60

I am porting a lot of php projects to vue3 at the moment. But I have difficulties with images I dont have locally and webpack refuses to work. I do not want to download 1000+ images and put them in my assets/images folder. They are available remote.

error:

This dependency was not found:

* @/img/backgrounds/background.png in ./node_modules/css-loader/...

Simple example:

<template>
  // awesome vue template
</template>

<script lang="ts">
  // awesome vue code
</script>

<style scoped lang="scss">
  #awesome-container {
    /* webpack says no */
    background-image: url('~@/img/background.png');
  }
</style>

folder structure remote:

/api/ <--- php stuff
/img/ <--- merged with the img from vue, but has a lot more folders and images
/css/ <--- from vue
/fonts/ <--- from vue
/... more vue folders .../
/index.html

Currently I help myself with using url('https://<ip-address-x>/img/background.png'). The vue3 will be deployed to https://<ip-address-x>/.

Is it possible to have an alias (like the paths in tsconfig) to tell webpack he has to use PATH_A in dev and PATH_B in prod?

It is highly possible we will use a cdn in a few month and it would be cool to just change one variable then instead of going trough 100+ files. The best thing would be, if I can keep the url('~@/img/background.png'); (or any other alias) and webpack/vue know where the files are.

1 Answers

Thanks to jeremy castelli who pointed me in that direction, I was able to create a solution which satisfies us for now (even if it is a bit of a hassle). Steps:

  1. created two files: .env.development and .env.production in the root (where vue.config.js is)
  2. content of .env.development:
VUE_APP_IMAGE_PATH=http://whatever/
  1. content of .env.production:
VUE_APP_IMAGE_PATH=/
  1. in vue.config.js (can be omitted, see info after steps!!!)
let sav = '';
for (const variable in process.env) {
  // Look for edit at the bottom for some improvements here
  if (variable.startsWith('VUE_APP')) sav += `$${variable}: '${process.env[variable]}';`;
}

// eslint-disable-next-line @typescript-eslint/no-var-requires
const fs = require('fs');
fs.writeFileSync('src/assets/scss/settings/_env.scss', sav);

module.exports = {
...
};
  1. in scripts it can be used with process.env.VUE_APP_IMAGE_PATH
export default class MainMenu extends Vue {
  
  mounted():void {
    console.log(process.env.VUE_APP_IMAGE_PATH);
  }
}
  1. in scss it can be used with $VUE_APP_IMAGE_PATH (only with step 4)
#gui-mainmenu {
    background-image : url($VUE_APP_IMAGE_PATH + 'assets/images/backgrounds/mainmenu_background.png');
}

Info to step 4:

You don't have to write the env vars into a scss file. I did that because I hate warnings. And PHPStorm gives it to me for every env var I use because it can't find it somewhere.

I use a sass loader and put my mixins, vars, functions... into a src/assets/scss/settings.scss. In there I load every scss file I want to prepend in components. But take care you don't have styles in there, which outputs to something. It bloats your dom. So for example:

@import 'settings/env'; // <--- file for env vars created by step 4
@import 'settings/fontSettings';
@import 'settings/fonts';
@import 'settings/config';
@import 'helper/functions';
@import 'helper/mixins';

In the vue.config.js I then have this:

let sav = '';
for (const variable in process.env) {
  if (variable.startsWith('VUE_APP')) sav += `$${variable}: '${process.env[variable]}';`;
}

// eslint-disable-next-line @typescript-eslint/no-var-requires
const fs = require('fs');
fs.writeFileSync('src/assets/scss/settings/_env.scss', sav);

module.exports = {
  ...

  css:        {
    loaderOptions: {
      scss: {
        prependData: `
        @import "~@/assets/scss/settings.scss";
        `,
      },
    },
  },
};

Edit:

Instead of including all env vars in scss, we can change the vars we need in scss to VUE_APP_SCSS_xxx and do this instead in step 4:

for (const variable in process.env) {
  if (variable.startsWith('VUE_APP_SCSS')) sav += `$${variable}: '${process.env[variable]}';`;
}
Related