Project Structure

vue.js logo

Default files & folders

When you open the project in your code editor, you'll see a structure that's quite different from our CDN-based projects:

vue-countdown/
├── node_modules/      # Dependencies installed by npm
├── public/            # Static assets that are not processed by Vite (CSS, images etc)
├── src/               # Project source code
│   ├── assets/        # Assets to be processed by Vite
│   ├── components/    # Vue component files
│   ├── App.vue        # Main/root component of the project
│   └── main.js        # App entry point
├── index.html         # HTML entry point
├── package.json       # Project info, dependencies, and scripts
├── vite.config.js     # Vite configuration file
└── README.md          # Project info/docs

The Vite setup allows you to:

  • Auto update the browser with code changes instantly.
  • Organize your project code into smaller components.
  • Use single-file components (.vue files) for organization.
  • Use modern JavaScript features with automatic browser compatibility.
  • Import CSS, images, and other assets directly.
  • Create optimized bundles for production.

Node modules

Node.js logo

This folder is where all of the npm modules are installed. If you have used Node before you will be familiar with this kind of setup. Typically projects using Node are split up into packages, each one adding some functionality. We may have a package for formatting dates, form validation, and we can also add our own packages here too, using NPM which we just installed.

This is where packages such as the Vue core library is located, rather than linking to the CDN script like in the first project.

Public

The public folder contains static files (assets which does not change dynamically based on user etc) such as images, fonts, favicons etc. It can also contain scripts, CSS, and other files. These files are not processed by Vite and can be accessed directly with a root path (e.g. /image_name).

The default project contains a favicon.ico file which contains the default favicon icon which appears in the browser tab.

index.html

This file is the HTML entry point and contains a minimum HTML structure, and then the rest of our code will be bundled and injected in:

<div id="app"></div>
<script type="module" src="/src/main.js"></script>

Just like earlier with the first project, we still need a place in the HTML to mount our app to, this is the div id=”app”.

src

The src folder will be where we do most of our work, this is where we will be adding most of our code for the project.

Assets folder

In here we have the assets folder, this is where we store our assets for the project such as CSS files, icons, fonts and images. These will all be processed by Vite and served/bundled as part of our project.

Components folder

The components folder is something we will look at in more detail soon. Rather than creating components as we looked at in the last project, we can organise them into separate files (.vue file extension).

The app.vue file

Next we see the App.vue file, this is a special Vue file which you can think of as the main file or component. We could write our full project inside of this single file, but it will get very big and difficult to maintain. To help organize our code we instead break down the code into smaller .vue files as components. Since these components are in their own separate file, we need to import them, just like we see here:

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

Then the code from the hello world file is placed inside the template:

<div class="wrapper">
  <HelloWorld msg="You did it!" />
</div>

The main.js file

With this Vue code in place, we just need to mount it all to the <div> we looked at above in the index.html file. This is done in the main.js file:

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

This is the main JavaScript file for the project and the place where we can also add plugins such as a router.We create the Vue app (createApp method), and then mount it to the <div> with the ID of app from our index page.

In the earlier project, we added an object to createApp directly like this:

createApp({
    data() {
        return {

        }
    }
}).mount('#app')

Using this new setup, we import the root component which is the App.vue file:

import App from './App.vue'

And pass it to create app instead:

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

This may seem complex to begin, but all we are doing is creating a HTML file to run in the browser and mounting this App to it. The difference now is the App file can also contain components but ultimately, they are all nested under this one App.vue file.