Vue Cli 3: defined output paths

Tobias Schäfer picture Tobias Schäfer · Jul 17, 2018 · Viewed 14.2k times · Source

I need to configure the output paths of the final build as described below:

My Vue project is default from structure but the output paths are outside this structure:

Output HTML file is: ../main/resources/

Output of all asset files: ../main/assets/[js/css/img]

And in the index.html file the path where to find the assets has to be "js/name.js" and similar.

My current vue.config.js does not provides this:

module.exports = {
    chainWebpack: config => {
        config.module
            .rule('vue')
            .use('vue-loader')
            .tap(options => {
                return options;
            });
    },
    css: {
        sourceMap: true
    },


    baseUrl: '/',
    outputDir: '../main/resources/',
    assetsDir: '../main/assets/',
    runtimeCompiler: undefined,
    productionSourceMap: undefined,
    parallel: undefined,
    configureWebpack: {
        module: {
            rules: [
                {
                    test: /\.(png|jpg|gif)$/,
                    use: [
                        {
                            loader: 'file-loader',
                            options: {
                                outputPath: '../main/assets/img',
                                name: '../main/assets/img/[name].[ext]'
                            }
                        }
                    ]
                }
            ]
        }
    }
}

Can someone help to configure this file? Thank you!
With kind regards
tschaefermedia

Sorry, I was busy with other projects. Now back to VueJS.
UPDATE:
I tried what was indicated in the GIT posts. My vue.config.js files looks now like this:

const path = require('path');
module.exports = {
    css: {
        sourceMap: true
    },

    devServer: {
        proxy: {
            '/api': {
                target: 'http://localhost:8080',
                'changeOrigin': true,
                'secure': false
            }
        }
    },
    baseUrl: '',
    outputDir: '../main/resources/',
    assetsDir: '../main/assets/',
    chainWebpack: config => {
        config.module
            .rule('vue')
            .use('vue-loader')
            .tap(options => {
                return options
            })
        config.module
            .rule('images')
            .test(/\.(png|jpe?g|gif|ico)(\?.*)?$/)
            .use('url-loader')
            .loader('url-loader')
            .options({
                name: path.join('../main/assets/', 'img/[name].[ext]')
            })
    }
}

Everything works now, as I want it to, but the images are not copied to the correct folder.
In ".../assets/" I have the css and js folder but no img folder. In ".../ressources" next to my index.html file I have this folder.

Answer

Richard Matsen picture Richard Matsen · Sep 4, 2018

After testing the problem on my build, I think you need two changes:

vue.config.js

module.exports = {
  ...
  outputDir: '../main/resources/',
  assetsDir: '../assets/',
  ...
}

and forget about the webpack plugin!

Ref config:assetsDir

assetsDir

Type: string

Default: ''

A directory (relative to outputDir) to nest generated static assets (js, css, img, fonts) under.

so assets will end up in ../main/resources/../assets/ which equates to ../main/assets/.


Image location in project

The optimum location IMO (from testing) is to use <project folder>/static which is the old CLI2 folder for static resources. In fact, any folder outside of src will do. This makes then handled as-is rather than 'webpacked'.

See Handling Static Assets

"Real" Static Assets ... In comparison, files in static/ are not processed by Webpack at all: they are directly copied to their final destination as-is, with the same filename.

Note quite true, they do get a versioning hash (see below).

This gives the following build folder structure:

../main
  assets/
    css/
    fonts/
    images/
    js/
  resources/
    index.html
    

With CLI 3 the /static folder was changed to /public/static, but if you put your images there, an extra copy is made under ../main/resources/static.

If you prefer this location (to stay standard) you could remove that copy with a postbuild script in package.json, for example using npm run under Windows,

package.json

{
  ...
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "postbuild": "rd /s /q \"../main/resources/static/images\"",
    "lint": "vue-cli-service lint",
    "test:unit": "vue-cli-service test:unit"
  },
  "dependencies": {

Image references

In the source, I found that relative image references work fine.

For example,

import myPic from '../public/static/images/myPic.png'

gets changed to

../assets/img/myPic.ec4d96e7.png

in the built app.js.

Note the hash added for versioning.


Serving the build

I note that the folder structure you use cannot be served with a simple http-server, as index.html is in main/resources and this server cannot fetch from main/assets.

I presume your deploy mechanism takes care of that?