DEV Community

Cover image for Vite for the Beginner: A Guide to the Headaches (and How to Fix Them)
Xion Apex Academy
Xion Apex Academy

Posted on

Vite for the Beginner: A Guide to the Headaches (and How to Fix Them)

Hi Everyone, Creator X here!

Hope you're doing well. What kind of projects are you working on and keeping up the good fight?

Recently, I started playing around with Vite, mainly because I wanted to try something new. As a beginner, I hope this helps you and reduces some of the pain and frustration I experienced.

πŸ”§ Getting Started

First off, the setup is quick and straightforward. You can use:

npm create vite@latest
Enter fullscreen mode Exit fullscreen mode

I used the JavaScript template, but you can choose between different frameworks. Follow the setup instructions, and you're good to go. The template was great because everything was already set up, and I just needed to make a few changes.

First things first β€” I'm no pro or master, just a novice. So this might or might not work for you, but I hope it helps someone out there.

Coming from a background of pure HTML, CSS, and JS, using Vite was a strange experience. There were a few things I didn't fully catch on to until later.

πŸ“¦ ES Modules (ESM) Are the Default

Vite uses ES Modules (ESM) by default, which is a modern way of handling JavaScript modules. This is a crucial difference from the older CommonJS style.

The Difference:

  • ESM: Uses import and export statements.
  • CommonJS: Uses require() and module.exports.

βœ… Example:

// math.js
export function add(a, b) {
  return a + b;
}

// main.js
import { add } from './math.js';
console.log(add(2, 3));
Enter fullscreen mode Exit fullscreen mode

❗ If you see an error like require is not defined, you're likely using CommonJS-style code β€” which Vite doesn't support natively.

🧠 Handling JavaScript in HTML with Vite

Another thing I learned was the importance of making my HTML compatible with Vite, especially when handling JavaScript.

❌ The Old Way (Plain HTML/JS):

<button onclick="handleClick()">Click me</button>
Enter fullscreen mode Exit fullscreen mode
// script.js
function handleClick() {
  alert("Clicked!");
}
Enter fullscreen mode Exit fullscreen mode

βœ… The Vite Way:

To ensure your functions are accessible globally, you need to expose them on the window object.

// main.js
window.handleClick = function () {
  alert("Clicked!");
};
Enter fullscreen mode Exit fullscreen mode

This ensures that the onclick attribute can find the handleClick function in the browser environment.

🎨 Tailwind CSS Configuration

This issue happened very recently and was a result of reorganizing my project. It highlights the importance of keeping your configuration files up to date.

❌ The Problem:

I had created a new folder called pages for all my HTML files. When I ran the build command, the CSS for those pages wasn't working.

Why? Because my tailwind.config.js file wasn't scanning the new pages directory.

βœ… The Solution:

Update the content property in tailwind.config.js:

// tailwind.config.js
module.exports = {
  content: [
    "./index.html",
    "./pages/**/*.{html,js}", // βœ… This path was missing!
    "./src/**/*.{js,ts,jsx,tsx}"
  ],
  // ... other configuration
};
Enter fullscreen mode Exit fullscreen mode

πŸ’‘ Same goes for adding new CSS or JS folders β€” make sure Tailwind knows where to look.
Most importantly, I know we tend to be focused on getting our code running, so just be mindful of where you are placing your files and your folder structure.
for example

|_ public (to here, make sure you include it)
|_src
|_pages (and you move the files from here)


βš™οΈ The vite.config.js File

Initially, I wasn't sure about the purpose of vite.config.js, as some templates had it and some didn't. Turns out, it's the core configuration file for Vite itself.

What it does:

  • Controls which plugins to use (React, Vue, etc.)
  • Handles build behavior
  • Sets server options

πŸ—‚οΈ Multi-Page Application (MPA) Setup

If you're building an MPA, you must tell Vite about all your HTML pages:

// vite.config.js
import { resolve } from 'path';
import { defineConfig } from 'vite';

export default defineConfig({
  build: {
    rollupOptions: {
      input: {
        main: resolve(__dirname, 'index.html'),
        'quest-tracker': resolve(__dirname, 'public/quest-tracker.html'),
        // ... add more pages here
      },
    },
  },
});
Enter fullscreen mode Exit fullscreen mode

πŸ› Fixing the "Cannot set properties of null" Error

This was a major pain. The error appeared on one page, even though the component was for a completely different one.

❌ The Problem:

Your main.js file acts like a single controller running on every page. If a component tries to initialize on a page that doesn't have its expected HTML element, it fails with a TypeError.

βœ… The Solution:

Make your code more resilient:

// main.js
document.addEventListener('DOMContentLoaded', () => {
  const projectsContainer = document.getElementById('project-listing');
  if (projectsContainer) {
    const projectManager = new ProjectManager();
    projectManager.init();
  }
});
Enter fullscreen mode Exit fullscreen mode

This ensures the component code only runs where it's supposed to.


🏁 Conclusion & Community

That's most of the trouble I ran into while learning and experimenting with Vite.

I recently built two sites using it and will be posting them once they're fully complete and they finally being deployed. As I mentioned earlier, I hope this helps other beginners avoid getting burnt like I did!

To everyone out there β€” happy coding πŸ’». Feel free to drop in and say hello. If you have tips or problems you faced using Vite, share them in the comments!

Top comments (0)