Skip to main content

Vue.js CLI

Introduction

The Vue Command Line Interface (CLI) is an essential tool in the Vue.js ecosystem that helps developers quickly scaffold, develop, and manage Vue.js projects. Instead of manually configuring your project setup, webpack, babel, and other dependencies, Vue CLI provides an interactive interface that handles all the complex configurations for you.

In this guide, you'll learn how to install Vue CLI, create new projects, understand the project structure, use plugins, and leverage the built-in development tools to streamline your Vue.js development workflow.

What is Vue CLI?

Vue CLI is a full system for rapid Vue.js development that provides:

  1. Interactive project scaffolding
  2. A runtime dependency (@vue/cli-service) that handles webpack configuration
  3. A collection of official plugins that integrate best practices
  4. A graphical user interface to manage your projects

By using Vue CLI, you can focus on writing your application instead of spending time configuring tools.

Installing Vue CLI

Before starting, ensure you have Node.js (version 10.x or above) installed on your machine.

To install Vue CLI globally, run the following command in your terminal:

bash
npm install -g @vue/cli

To verify that the installation was successful, run:

bash
vue --version

This should display the installed Vue CLI version, something like @vue/cli 5.0.8.

Creating a New Vue Project

With Vue CLI installed, you can create a new project using the vue create command:

bash
vue create my-vue-app

This will launch an interactive interface where you can select a preset configuration for your project:

  1. Default preset - Includes Babel and ESLint with basic configuration
  2. Manually select features - Allows you to customize your project setup

For beginners, the default preset is a great starting point. However, let's explore the manual selection to understand what options are available.

If you choose "Manually select features", you'll be prompted to select features like:

  • Babel
  • TypeScript
  • Progressive Web App (PWA) Support
  • Router
  • Vuex
  • CSS Pre-processors
  • Linter / Formatter
  • Unit Testing
  • E2E Testing

Here's an example of what selecting features might look like:

? Check the features needed for your project:
◉ Babel
◯ TypeScript
◯ Progressive Web App (PWA) Support
◉ Router
◉ Vuex
◉ CSS Pre-processors
◉ Linter / Formatter
◯ Unit Testing
◯ E2E Testing

After selecting features, additional configuration questions will appear based on your choices.

Understanding the Project Structure

After creating a project, let's explore the structure Vue CLI generates:

my-vue-app/
├── node_modules/ # Project dependencies
├── public/ # Static assets that won't be processed by webpack
│ ├── favicon.ico # Site favicon
│ └── index.html # HTML template
├── src/ # Main source code directory
│ ├── assets/ # Assets that will be processed by webpack
│ ├── components/ # Vue components
│ ├── views/ # Vue components that represent pages (if Router is selected)
│ ├── App.vue # Root Vue component
│ ├── main.js # Application entry point
│ ├── router.js # Vue Router configuration (if selected)
│ └── store.js # Vuex store (if selected)
├── .gitignore # Git ignore configuration
├── babel.config.js # Babel configuration
├── package.json # NPM package configuration
├── README.md # Project documentation
└── vue.config.js # Vue CLI configuration (optional)

Key Files Explained

  1. public/index.html: This is the template HTML file that your Vue app will be injected into.
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<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 <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
  1. src/main.js: This is the entry point of your Vue application:
javascript
import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')
  1. src/App.vue: This is the root component of your Vue application:
html
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
name: 'App',
components: {
HelloWorld
}
}
</script>

<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>

Running Your Vue Project

Vue CLI provides a development server that includes hot-reload, which updates your application in the browser without refreshing when you make changes to your code.

To start the development server, navigate to your project folder and run:

bash
npm run serve

This command will compile your Vue application and start a development server, typically available at http://localhost:8080/.

You'll see output similar to:

 DONE  Compiled successfully in 3245ms

App running at:
- Local: http://localhost:8080/
- Network: http://192.168.1.5:8080/

Note that the development build is not optimized.
To create a production build, run npm run build.

Building for Production

When your application is ready for deployment, you'll want to create a production build:

bash
npm run build

This command creates a dist folder with optimized, minified files ready for deployment to a web server.

The output will look something like:

File                                      Size             Gzipped
dist/js/chunk-vendors.7f8cd738.js 97.69 KiB 34.79 KiB
dist/js/app.c6f83e33.js 4.35 KiB 1.65 KiB
dist/css/app.fb0c6e1c.css 0.33 KiB 0.23 KiB

Vue CLI Plugins

One of Vue CLI's most powerful features is its plugin system. Plugins allow you to add new functionality to your project without configuring everything manually.

Adding Plugins to an Existing Project

You can add plugins to an existing Vue CLI project using the vue add command:

bash
vue add vuetify

This would install the Vuetify UI framework and configure your project to use it.

Some popular official plugins include:

  • @vue/cli-plugin-babel - Babel transpilation
  • @vue/cli-plugin-router - Vue Router
  • @vue/cli-plugin-vuex - Vuex state management
  • @vue/cli-plugin-eslint - ESLint code linting
  • @vue/cli-plugin-unit-jest - Jest unit testing

Example: Adding Vue Router to a Project

Let's add Vue Router to an existing project:

bash
vue add router

This will:

  1. Install the Vue Router package
  2. Add router configuration files
  3. Create sample route components
  4. Modify App.vue to use the router

After running this command, your src folder will have a new router/index.js file:

javascript
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'

const routes = [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'about',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
}
]

const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})

export default router

And your main.js will be updated to use the router:

javascript
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

createApp(App).use(router).mount('#app')

Vue CLI Graphical User Interface

Vue CLI provides a graphical user interface that makes project management even easier. To start it, run:

bash
vue ui

This will open a browser window with the Vue CLI UI, where you can:

  1. Create new projects
  2. Import existing projects
  3. Manage plugins
  4. Configure project settings
  5. Run tasks (serve, build, lint, etc.)
  6. Analyze build sizes and dependencies

The UI is particularly helpful for beginners as it provides a visual way to manage your project without remembering CLI commands.

Vue CLI Configuration

Vue CLI projects can be configured via a vue.config.js file in the root directory of your project.

Here's a basic example:

javascript
module.exports = {
// Public path for deployment (default: '/')
publicPath: process.env.NODE_ENV === 'production' ? '/my-app/' : '/',

// Output directory (default: 'dist')
outputDir: 'dist',

// Configure webpack
configureWebpack: {
// Simple configuration
plugins: []
},

// Advanced webpack config
chainWebpack: config => {
// Example: Adding a loader
config.module
.rule('svg')
.use('vue-svg-loader')
.loader('vue-svg-loader')
},

// Development server configuration
devServer: {
proxy: 'http://localhost:4000'
}
}

This configuration system is extremely powerful, allowing you to customize almost any aspect of your build process.

Real-world Example: Creating a Todo App

Let's build a simple Todo application using Vue CLI to demonstrate how to work with it in practice:

  1. First, create a new Vue CLI project:
bash
vue create vue-todo-app

Choose the default preset for simplicity.

  1. Navigate to the project folder:
bash
cd vue-todo-app
  1. Create a new TodoList.vue component in the src/components folder:
html
<template>
<div class="todo-list">
<h2>{{ title }}</h2>

<div class="add-todo">
<input
type="text"
v-model="newTodo"
placeholder="Add new todo"
@keyup.enter="addTodo"
>
<button @click="addTodo">Add</button>
</div>

<ul class="todos">
<li v-for="(todo, index) in todos" :key="index" :class="{ done: todo.completed }">
<input
type="checkbox"
v-model="todo.completed"
>
<span>{{ todo.text }}</span>
<button @click="removeTodo(index)">Delete</button>
</li>
</ul>

<div class="todo-status">
<p>{{ remainingTodos }} items left</p>
<button @click="clearCompleted">Clear completed</button>
</div>
</div>
</template>

<script>
export default {
name: 'TodoList',
props: {
title: {
type: String,
default: 'Todo List'
}
},
data() {
return {
newTodo: '',
todos: [
{ text: 'Learn Vue.js', completed: false },
{ text: 'Build a Todo app', completed: false },
{ text: 'Master Vue CLI', completed: false }
]
}
},
computed: {
remainingTodos() {
return this.todos.filter(todo => !todo.completed).length
}
},
methods: {
addTodo() {
if (this.newTodo.trim()) {
this.todos.push({
text: this.newTodo.trim(),
completed: false
})
this.newTodo = ''
}
},
removeTodo(index) {
this.todos.splice(index, 1)
},
clearCompleted() {
this.todos = this.todos.filter(todo => !todo.completed)
}
}
}
</script>

<style scoped>
.todo-list {
max-width: 500px;
margin: 0 auto;
padding: 20px;
border: 1px solid #e0e0e0;
border-radius: 5px;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}

.add-todo {
display: flex;
margin-bottom: 20px;
}

.add-todo input {
flex: 1;
padding: 8px 10px;
border: 1px solid #ddd;
border-radius: 4px 0 0 4px;
}

.add-todo button {
padding: 8px 15px;
background: #4caf50;
color: white;
border: none;
border-radius: 0 4px 4px 0;
cursor: pointer;
}

.todos {
list-style-type: none;
padding: 0;
}

.todos li {
padding: 10px;
border-bottom: 1px solid #eee;
display: flex;
align-items: center;
}

.todos li.done span {
text-decoration: line-through;
color: #888;
}

.todos li span {
flex: 1;
margin: 0 10px;
}

.todos li button {
padding: 5px 10px;
background: #f44336;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}

.todo-status {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 20px;
}

.todo-status button {
padding: 5px 10px;
background: #2196f3;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
</style>
  1. Now, update src/App.vue to use our TodoList component:
html
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<TodoList title="Vue CLI Todo App"/>
</div>
</template>

<script>
import TodoList from './components/TodoList.vue'

export default {
name: 'App',
components: {
TodoList
}
}
</script>

<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
  1. Start the development server:
bash
npm run serve
  1. Navigate to http://localhost:8080/ to see your Todo app in action!

This simple example demonstrates how to create components, manage state, use props, and handle events in a Vue CLI project.

Summary

The Vue CLI is an essential tool for modern Vue.js development that simplifies project setup and management. In this guide, we've covered:

  • Installing the Vue CLI
  • Creating new projects with customizable presets
  • Understanding the project structure
  • Running development servers and building for production
  • Working with Vue CLI plugins
  • Using the Vue CLI GUI
  • Configuring your Vue project
  • Building a real-world Todo application

By leveraging Vue CLI, you can focus more on building your application and less on configuring the development environment, making Vue.js development more efficient and enjoyable.

Additional Resources

Exercises

  1. Create a new Vue CLI project with Vue Router and Vuex enabled.
  2. Add the Vuetify plugin to an existing Vue CLI project.
  3. Create a custom configuration in vue.config.js to proxy API requests to a backend server.
  4. Extend the Todo app by adding the ability to edit existing todos.
  5. Use Vue CLI to build a production version of your Todo app and deploy it to a static hosting service like Netlify or GitHub Pages.


If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)