Understanding Vue CLI Configuration Files in Depth

When deploying a Vue application separately from the backend, the config/index.js file requires proper configuration. This file controls both development and production build behaviors.

Basic Configuration Structure

var path = require('path')

module.exports = {
  build: {
    index: path.resolve(__dirname, 'dist/index.html'),
    assetsRoot: path.resolve(__dirname, 'dist'),
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    productionSourceMap: true
  },
  dev: {
    port: 8080,
    proxyTable: {}
  }
}

Build Cofniguration Options

build.index

Must be an absolute path on the local filesystem.

The generated index.html file (with injected resource paths) will be placed here. If using this template within a backend framework, you can modify the path to point to the file generated by your backend. For example, in Rails it could be app/views/layouts/application.html.erb, or in Laravel it could be resources/views/index.blade.php.

build.assetsRoot

Must be an absolute path on the local filesystem.

This should point to the root directory containing all static assets of the application. The public/ folder corresponds to Rails/Laravel projects.

build.assetsSubDirectory

All webpack-processed resource files reside within this subdirectory under build.assetsRoot. It must not contain any other files that might exist in build.assetsRoot. For instance, if build.assetsRoot is /path/to/dist and build.assetsSubDirectory is static, all webpack assets compile to path/to/dist/static.

This directory gets cleared before each compilation, so it should only contain compiled assets. The static/ folder files are copied directly during the build process. If you change this rule, all absolute paths referencing files in static/ must be updated accordingly.

build.assetsPublicPath

This is the URL path when serving via HTTP server. In most cases, it should be the root directory (/). If your backend framework requires a specific static resource URL prefix, modify this parameter. Internally, webpack treats this as output.publicPath.

If the backend has requirements, you may need to add ./ or adjust based on specific directory structures, otherwise static resources won't be accessible.

build.productionSourceMap

Controls whether to generate source maps when building for production.

Development Configuration Options

dev.port

Specifies the port for the development server to listen on.

dev.proxyTable

Defines proxy rules for the development server.

Production Environment Configuration

var path = require('path')

module.exports = {
  build: {
    env: require('./prod.env'),
    index: path.resolve(__dirname, '../dist/index.html'),
    assetsRoot: path.resolve(__dirname, '../dist'),
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    productionSourceMap: true,
    productionGzip: false,
    productionGzipExtensions: ['js', 'css']
  },
  dev: {
    env: require('./dev.env'),
    port: 8080,
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    proxyTable: {},
    cssSourceMap: false
  }
}

Webpack Base Configuration

The build/webpack.base.conf.js file contains the core webpack setup:

var path = require('path')
var config = require('../config')
var utils = require('./utils')
var projectRoot = path.resolve(__dirname, '../')

var env = process.env.NODE_ENV
var cssSourceMapDev = (env === 'development' && config.dev.cssSourceMap)
var cssSourceMapProd = (env === 'production' && config.build.productionSourceMap)
var useCssSourceMap = cssSourceMapDev || cssSourceMapProd

module.exports = {
  entry: {
    app: './src/main.js'
  },
  output: {
    path: config.build.assetsRoot,
    publicPath: process.env.NODE_ENV === 'production' 
      ? config.build.assetsPublicPath 
      : config.dev.assetsPublicPath,
    filename: '[name].js'
  },
  resolve: {
    extensions: ['', '.js', '.vue', '.scss'],
    fallback: [path.join(__dirname, '../node_modules')],
    alias: {
      'vue$': 'vue/dist/vue',
      'src': path.resolve(__dirname, '../src'),
      'assets': path.resolve(__dirname, '../src/assets'),
      'components': path.resolve(__dirname, '../src/components'),
      'scss_vars': path.resolve(__dirname, '../src/styles/vars.scss')
    }
  },
  resolveLoader: {
    fallback: [path.join(__dirname, '../node_modules')]
  },
  module: {
    loaders: [
      {
        test: /\.vue$/,
        loader: 'vue'
      },
      {
        test: /\.js$/,
        loader: 'babel',
        include: projectRoot,
        exclude: /node_modules/
      },
      {
        test: /\.json$/,
        loader: 'json'
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: 'url',
        query: {
          limit: 10000,
          name: utils.assetsPath('img/[name].[hash:7].[ext]')
        }
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        loader: 'url',
        query: {
          limit: 10000,
          name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
        }
      }
    ]
  },
  vue: {
    loaders: utils.cssLoaders({ sourceMap: useCssSourceMap }),
    postcss: [
      require('autoprefixer')({
        browsers: ['last 2 versions']
      })
    ]
  }
}

Key aspects include:

  • Entry point: Configured via app: './src/main.js'
  • Output path: Uses config.build.assetsRoot for the webpack output directory
  • Public path: Dynamically selects between production and development settings
  • Aliases: Shorthand paths for common imports like src, assets, and components
  • Module loaders: Handles Vue files, JavaScript, JSON, images, and fonts

Production Webpack Configuration

The webpack.prod.conf.js file extends the base configuration for production builds:

var path = require('path')
var config = require('../config')
var utils = require('./utils')
var webpack = require('webpack')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var HtmlWebpackPlugin = require('html-webpack-plugin')

var env = config.build.env

var webpackConfig = merge(baseWebpackConfig, {
  module: {
    loaders: utils.styleLoaders({ sourceMap: config.build.productionSourceMap, extract: true })
  },
  devtool: config.build.productionSourceMap ? '#source-map' : false,
  output: {
    path: config.build.assetsRoot,
    filename: utils.assetsPath('js/[name].[chunkhash].js'),
    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
  },
  vue: {
    loaders: utils.cssLoaders({
      sourceMap: config.build.productionSourceMap,
      extract: true
    })
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env': env
    }),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      }
    }),
    new webpack.optimize.OccurenceOrderPlugin(),
    new ExtractTextPlugin(utils.assetsPath('css/[name].[contenthash].css')),
    new HtmlWebpackPlugin({
      filename: config.build.index,
      template: 'index.html',
      inject: true
    })
  ]
})

Notable plugins:

  • DefinePlugin: Injects environment variables
  • UglifyJsPlugin: Minifies and compresses code
  • ExtractTextPlugin: Extracts CSS into separate files
  • HtmlWebpackPlugin: Generates HTML with injected assets

Build Script

The build/build.js file handles the production build process:

require('./check-versions')()
require('shelljs/global')

env.NODE_ENV = 'production'

var path = require('path')
var config = require('../config')
var ora = require('ora')
var webpack = require('webpack')
var webpackConfig = require('./webpack.prod.conf')

console.log(
  '  Tip:\n' +
  '  Built files are meant to be served over an HTTP server.\n' +
  '  Opening index.html over file:// won\'t work.\n'
)

var spinner = ora('building for production...')
spinner.start()

var assetsPath = path.join(config.build.assetsRoot, config.build.assetsSubDirectory)
rm('-rf', assetsPath)
mkdir('-p', assetsPath)
cp('-R', 'static/*', assetsPath)

webpack(webpackConfig, function (err, stats) {
  spinner.stop()
  if (err) throw err
  process.stdout.write(stats.toString({
    colors: true,
    modules: false,
    children: false,
    chunks: false,
    chunkModules: false
  }) + '\n')
})

The build script performs the following steps:

  1. Validates Node and npm versions
  2. Sets production environment
  3. Cleans and recreates the output directory
  4. Copies static files
  5. Executes webpack compilation
  6. Displays build progress and results

NPM Scripts

The package.json defines the command-line interfaces:

"scripts": {
  "dev": "node build/dev-server.js",
  "build": "node build/build.js",
  "watch": "node build/build-watch.js"
}

Running npm run dev starts the development server, npm run build creates a production build, and npm run watch enables continuous compilation in production mode with the webpack watch option enabled.

Tags: vue Vue CLI webpack configuration Build

Posted on Sat, 09 May 2026 09:35:11 +0000 by nick1