Caleb Jay
Caleb Jay

Reputation: 2199

Vue-cli production build not displaying static images

I'm trying to get our logo to show up in a vue-cli production build.

If I do vue-cli-service serve (run webpack dev server), the images resolve (I can see them in the web browser). However, if I serve the bundled files (using node or whatever), the images don't resolve, despite the fact that they're in the proper folder. I can see in my network tab a 200 OK request for http://localhost:8888/img/logo.fdcc9ca9.png, which means the proper file-named object is being seen in the correct location. I can also see it there in the proper in my sources tab.

Also, if I inspect the element, it looks like this, which also looks correct:

<img data-v-0242e324="" src="/img/logo.fdcc9ca9.png" alt="logo">

Despite all this, on production build, the image shows the class HTML "broken image" thumbnail.

What's going wrong? How can I not show the "broken image" thumbnail on production build? Why is it working on webpack-dev-server but not production?

Logo.vue

<template>
  <img src="../img/logo.png" alt="logo">
</template>
<script>
  ...
</script>

vue.config.js

const path = require('path');
const webpack = require('webpack');
module.exports = {
    chainWebpack: config => {
        config.resolve.alias
            .set('@', path.resolve(__dirname, 'client/src'));
        config
            .plugin('provide')
            .use(webpack.ProvidePlugin, [{
                $: 'jquery',
                jquery: 'jquery',
                jQuery: 'jquery',
                'window.jQuery': 'jquery'
            }]);
        config.plugin("html")
            .tap(args => {
                args[0].template = "./client/index.html"
                return args
            })
    },
    runtimeCompiler: true,
    devServer: {
        proxy: 'http://localhost:8888'
    }
}

package.json

...
    "serve:ui": "vue-cli-service serve client/src/main.js",
    "build:ui": "vue-cli-service build --dest build/public/ client/src/main.js",
...

folder structure, developing

client/
  src/
    img/
      logo.png
    components/
      Logo.vue

folder structure, output build

build/
  public/
    css/
    fonts/
    img/
      logo.fcdd9ca9.png
    js/
    index.html

Upvotes: 3

Views: 2334

Answers (1)

Caleb Jay
Caleb Jay

Reputation: 2199

The answer is our API was misconfigured.

In short, there was no handler for images (or fonts). As @aBiscuit pointed out, trying the request directly in my browser for whatever my image URLs were returned the index.html, which is our API's fallback for stack file requests it doesn't understand.

Without our code, this isn't helpful, but adding the following to our route handling solved the issue:

routes.ts

router.get('/img/:file', async (ctx, next) => {
    await next();
    await send(ctx, `build/public/img/${ctx.params.file}`);
});

Upvotes: 1

Related Questions