Using webpack Encore hashed images and aliases within Vue.js

43 views Asked by At

I am working on an existing project which uses Webpack encore to create images in the build folder with hashed filenames. I am having trouble accessing these images within .vue files

The site is Symfony, and uses majority twig templates, however a number of pages have vue files embedded within them.

I have found this existing question but none of the answers are resolving the issue- I'll detail what I've tried below:

I know the images are present and accessible in the build folder, as if I hardcode a full, relative filepath in the vue component, the images are shown. <img src="../../../../img/notification.svg" :alt="alt">

The outputted src contains the hashed filename, eg src="/build/images/notification.f000953c.svg"

However the image is 404 when I try to pass the filename as a prop, for example if I do <img :src="`../../../../img/${iconName}`">

It is the same whether I create the src as a computed property, or even if I pass the entire relative filepath as the prop. This appears to happen any time the image src is in any way dynamic, even if I hardcode the relative path but using :src instead of src

The outputted src is ../../../../img/notification.svg - the hashed part is missing

It appears that whatever Encore does to replace the filenames in image tags, it does so only in non-dynamic src tags and not :src tags.

A suggestion I found was to create aliases in the webpack.config.js file - relevant sections are

const Encore = require('@symfony/webpack-encore');
const path = require('path');

Encore
    .setOutputPath('web/build/')
    .setPublicPath('/build')
    .copyFiles({
        from: './assets/img',
        to: 'img/[path][name].[hash:8].[ext]',
    })
    .addAliases({
        '@images': path.resolve(__dirname, 'img'),
        'images': path.resolve(__dirname, 'img'),
    })

However, I don't seem to be able to use these aliases within the vue files - if I include an @ symbol within either the template or a computed prop, the component does not render, with an error about the 'decorators' syntax not being suppported (Chrome)

iconPath() {
        return `${@images/this.iconName}`
      },

If I add the @images as a string, eg return `@images/${this.iconName}` , then this is simply outputted verbatim in the html and I get src="@images/notification.svg" - which has neither the correct path, nor the hashed filename.

This doesn't seem like an especially weird use case, so I'm sure there must be a step I'm missing somewhere to get this working. However after many wasted hours I'm losing hope of discovering it on my own!

Essentially there are three things I'm trying to achieve here:

  • Pass the icon name / filename to a component as a prop
  • Dynamically get the filepath without having to use a lengthy relative path for every icon
  • Access the hashed name of the image file, when passing in the un-hashed name.

Many thanks for anyone who can help out here and save my sanity!

0

There are 0 answers