Customizing Vue CLI 3 Projects: Essential Build and Development Configurations

The ESLint setup for Vue CLI 3 projects can be configured within the eslintConfig field of package.json. This section allows for fine-grained control over linting rules. For instance, to permit the use of console statements in your codebase, you can define a rule to disable the no-console check.

{
  "name": "my-vue-project",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "vue": "^2.6.11"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~4.5.0",
    "@vue/cli-plugin-eslint": "~4.5.0",
    "@vue/cli-service": "~4.5.0",
    "babel-eslint": "^10.1.0",
    "eslint": "^6.7.2",
    "eslint-plugin-vue": "^6.2.2",
    "vue-template-compiler": "^2.6.11"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "eslint:recommended"
    ],
    "parserOptions": {
      "parser": "babel-eslint"
    },
    "rules": {
      "no-console": "off",
      "no-debugger": "warn"
    }
  }
}

In this example, "no-console": "off" (or 0) completely disables the warning/error for console statements, while "no-debugger": "warn" allows its use but flags it during linting.

Environment Variable Management

Vue CLI 3 leverages environment variables to manage different configurations across various deployment stages (e.g., development, staging, production). These variables enable conditional logic within your application and during the build process.

To introduce a new environment, such as a staging build, define a custom command in package.json:

{
  "name": "my-vue-project",
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "build:staging": "vue-cli-service build --mode staging",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "vue": "^2.6.11"
  }
}

Executing npm run build:staging will now trigger a build using the staging mode. To define variables for this mode, create a .env.staging file in the project's root directory (sibling to src/).

For example, .env.staging:

NODE_ENV=production
VUE_APP_API_BASE_URL=https://api.staging.example.com

Important Considerations for Environment Variables:

  • NODE_ENV: This special variable dictates Webpack's build behavior. If your custom mode (e.g., staging) should produce an optimized, minified build similar to a standard production build, NODE_ENV must be set to production. Setting it to development or the custom mode name (staging) might result in an unoptimized output, even when running vue-cli-service build.
  • Client-Side Access (VUE_APP_ prefix): For any custom environment variable to be accessible within your client-side JavaScript code (e.g., process.env.VUE_APP_API_BASE_URL), it must be prefixed with VUE_APP_. Variables without this prefix are typically only available during the build process (e.g., for Webpack configurations).

Customizing public/index.html

The primary index.html file in Vue CLI 3 projects resides in the public/ directory. This file serves as a template and supports EJS (Embedded JavaScript) syntax, allowing for dynamic content injection based on environment variables during the build.

A common use case is conditionally including third-party scripts, like analytics tracking, only for production builds.

public/index.html example:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
    <% if (process.env.NODE_ENV === 'production') { %>
    <script>
      // Third-party analytics script (e.g., Google Analytics)
      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
      (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
      m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
      })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

      ga('create', 'UA-XXXXX-Y', 'auto');
      ga('send', 'pageview');
    </script>
    <% } %>
  </body>
</html>

Here, the Google Analytics script is only embedded when NODE_ENV is set to production.

Customizing Build Output Paths via vue.config.js

For advanced build configurations, the vue.config.js file (located in the project root) is the primary entry point.

Output HTML File Path (indexPath)

By default, the built index.html (or other HTML templates) is placed inside the outputDir. However, if your Vue application is integrated into a larger backend system, you might need to output the HTML template to a specific backend view directory. The indexPath option allows you to define this relative path:

vue.config.js:

module.exports = {
  indexPath: '../../backend/templates/dashboard.html'
};

This configurasion outputs the main HTML file two directories up, then into backend/templates/dashboard.html, decoupling it from the typical static asset folder.

Static Assets Output Directory (outputDir)

The outputDir option specifies the directory where all generated static assets (JavaScript, CSS, images, etc.) are placed after a build. By default, this is dist.

vue.config.js:

module.exports = {
  outputDir: 'build/frontend-assets'
};

This places all compiled assets into build/frontend-assets/.

Public Path for Assets (publicPath)

The publicPath option determines the base URL for all assets referenced in the generated HTML and CSS. This is crucial for correctly serving your application in production, especially when deployed to a subdirectory or a CDN.

vue.config.js:

module.exports = {
  publicPath: process.env.NODE_ENV === 'production'
    ? '/static/my-app/'
    : '/'
};
  • outputDir controls where the files are physically saved on the disk.
  • publicPath controls the URL path browsers use to request those files after deployment. A mismatch can lead to assets failing to load (404 errors).

Multi-Page Application (MPA) Configuration

Vue CLI 3 supports building multi-page applications using the pages option in vue.config.js. This allows you to define multiple entry points, each generating its own HTML file.

The pages option accepts an object where each key represents a page name. The value for each page can be either a string or an object.

String Format (Simple Page)

For a basic page, you can specify just the entry JavaScript file.

vue.config.js:

module.exports = {
  pages: {
    admin: 'src/admin/main.js'
  }
};

With this, Webpack will look for public/admin.html as the template. If not found, it falls back to public/index.html. The output HTML file will be admin.html within the outputDir.

Object Format (Detailed Page)

The object format provides more granular control over each page's configuration.

vue.config.js:

module.exports = {
  pages: {
    mainApp: {
      entry: 'src/main.js',
      template: 'public/index.html',
      filename: 'main-app.html',
      title: 'Main Application',
      chunks: ['chunk-vendors', 'chunk-common', 'mainApp']
    },
    loginPortal: {
      entry: 'src/login/main.js',
      template: 'public/login.html', // Specific template for login
      filename: 'auth/login.html',    // Output to a subdirectory
      title: 'Login',
      chunks: ['chunk-vendors', 'loginPortal'] // No 'chunk-common' for a simpler page
    }
  }
};
  • entry: Path to the page's JavaScript entry file.
  • template: Path to the HTML template file for this page.
  • filename: The name (and relative path within outputDir) of the generated HTML file.
  • title: The <title> tag content for the page. Requires <title><%= htmlWebpackPlugin.options.title %></title> in your HTML template.
  • chunks: An array specifying which Webpack chunks should be injected into this page's HTML file.
    • chunk-vendors: Contains third-party dependencies.
    • chunk-common: Contains modules shared across multiple async chunks.
    • mainApp (or loginPortal): The chunk specific to this page's entry point. Omitting a chunk from this array means its corresponding JavaScript or CSS will not be automatically included in the <script> or <link> tags of the generated HTML for that specific page. This can be used to optimize page load by including only necessary assets.

The mainApp page will include vendor, common, and mainApp specific code, while loginPortal will only include vendor and its specific code, potentially leading to a smaller initial load for the login page if chunk-common is not required.

Tags: Vue CLI webpack configuration ESLint Environment Variables

Posted on Thu, 01 Oct 2026 16:23:44 +0000 by fireMind