3
votes

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
1
Can you access the image via direct url on production? your-domain.com/img/logo.fdcc9ca9.png? Does it load image correctly or is there any other response?aBiscuit
Aha, very good point, it resolves to our index.html, this is probably a misconfiguration on our API. Will look into this.Caleb Jay
Make sure that web server is configured to redirect only 404 requests to index.html, but not ALL requests. This will ensure that all static assets are accessible, except for those that could not be located by web server.aBiscuit

1 Answers

1
votes

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}`);
});