Transcription
If you are starting to master front-end development, you have surely heard phrases like: set up a bundler, build a build, turn on the dev server, and other mysterious incantations. The word "bundler" scares many. It seems like something complex and incomprehensible. And when you start googling, you stumble upon dozens of articles about Webpack, Gulp, Parcel, and other tools. But the truth is that in 2025, there is one tool that covers 99% of tasks, and that is Vite. In this video, I will tell you what Vite is, how it works, why you need it, and why you shouldn't bother yourself with other bundlers. Just take Vite and you will be happy. If you want more content from me, check out my Telegram channel. There I regularly share unique cases from my development experience and sometimes write about soft skills, teamwork, and professional growth. The QR code is on the screen, the link is in the description below the video. If you want to develop as a front-end developer, join us. Now, let's get down to business. A bundler is a program that helps you run a project locally, automatically rebuild code upon changes, combine dozens of files into a few convenient ones for production, connect dependencies and modules with simple import syntax, and finally, use modern language features and transform them into a more primitive syntax so that older browsers can understand it. In short, modern front-end practically doesn't work without a bundler. And although previously you had to configure Webpack or Gulp manually, now Vite provides a ready-made solution without pain and suffering. Vite is a modern tool for developing front-end applications. It was developed by the author of Vue.js, but it works perfectly with React and other frameworks as well. Vite does two important things. First, a dev server with so-called hot module replacement. You run the project, and all changes are immediately displayed in the browser instantly. And a production build. Vite uses Rollup for production, which means the final code will be lightweight and optimized. Under the hood, ES Build is used for development, one of the fastest transpilers on the market. It is written in Go, which makes Vite literally lightning fast. Why is Vite the best choice in 2025? Here is a list of reasons why I consider Vite an ideal choice for beginners and not only. Fast start. Project creation takes less than a minute. Minimal configuration. TypeScript, React, Vue, Svelte, and others work out of the box. Hot module replacement, almost instant browser updates upon code changes. Plugins. A large number of plugins, including compatibility with the Rollup ecosystem. Support and popularity. Vite is actively developed, and it has a huge community. And most importantly, Vite allows you to avoid spending weeks on configuration and start writing code immediately, focusing on the product. Let's move on to practice. Let's figure out how to start using Vite. First, you will need Node.js and a package manager like npm installed on your computer. I already have a video on the channel about these tools, the link will appear in the corner and will be in the description below this video. So, as a test project, I created a new folder on my computer, named it vite, and opened it in WebStorm. On the main page of the official Vite.dev website, you can click the "Get Started" button, and instructions will open. To create a new project with Vite, you are prompted to enter the following command in the terminal. We copy it to the clipboard and paste it into the WebStorm terminal. Press Enter. We confirm our intentions with Y. Next, there will be a few questions in the console. First, the project name. You can enter anything, but since we are already in the project folder named vite-app, we can enter a dot symbol, and this will mean that Vite will be initialized directly in the root of our current folder vite-app without any unnecessary subdirectories. Press Enter. Next, a question about our directory not being empty. What should be done before continuing? Cancel the operation, clean up all current files and continue, or ignore files and continue. I choose "ignore" because the .git folder doesn't bother us here. And finally. We need to choose a framework. Vanilla, Vue, React, and so on. Vanilla is pure JavaScript. I choose it. Ah, yes, and we also need to choose a TypeScript or JavaScript variation. Again, I choose JavaScript. After this, the initial structure of the Vite project bundler will appear in our vite-app folder. Before installing the necessary dependencies, I suggest going to the package.json file. And here, in "devDependencies," for the Vite library, the dependency Vite is specified with version 6.3.5. with this prefix. But since you will be watching this video later, you might have a different number here. I suggest you do the following. Regardless of the version specified here, keep the value 6.3.5 and remove the prefix. This is necessary to avoid asynchronous behavior of your project bundler with what I will show in this video next. Now we need to install the dependencies. To do this, we enter the command npm i in the terminal. After a short wait, the dependencies are installed, and we are ready to launch the dev server. If we look at package.json again, in the "scripts" field, there will be three commands: dev, build, and preview. We only need the dev command for now. We enter the command npm run dev in the terminal. And immediately we see information. Vite has been launched locally at the following address in X seconds. Click on it, and the dev server page will open in the browser. And now any changes in our code will automatically appear in the browser without the need for manual reloading. Let's go back to the IDE and analyze what is inside the project folder. The package.json, package-lock.json files, and the node_modules folder are what any project created through the npm package manager has. I talked about all of this in the video about npm, which I already mentioned. The .gitignore file also appeared here automatically. I also had a video about Git and the purpose of the .gitignore file in particular. The link will appear in the corner and will be in the description. Now, about the files directly related to the project bundler. It's worth noting right away that which files are generated depends on the settings we chose after entering the npm create command. Recall that we don't have a framework, so we chose vanilla, and as a template, we selected JavaScript, not TypeScript. With these initial conditions, Vite creates a minimal but quite understandable structure. index.html is the entry point with the source markup, which we can edit manually. If anything, Vite has already connected the necessary JavaScript file for us. It's best to leave it like that. The SRC folder. Almost all of our development will be in this directory. In the SRC folder, the most important file is main.js, the entry point for our JavaScript code. There is already some JavaScript code here, a few imports, and then through innerHTML, this markup is rendered into a DOM element with the ID "app." Besides the main.js file, there are a few other files in the SRC folder that were imported and used in the main.js file. In counter.js, we have some function here. JavaScript SVG is a file with an icon that is imported in this tricky way, specifying the name. And then this JavaScript logo entity is used as the value of the src attribute for the HTML img tag. And pay attention to style.css as well. Styles in the project are not connected directly in the markup via a link tag, but are imported into JS files, in our case, into the entry point main.js. I will talk more about how to work with icons and styles in Vite a little later. For now, let's move on. In addition to the SRC folder with the project's source code, there is also a public folder. This folder is used for so-called static files that should not be processed by the project bundler during the build, but should be included in the final bundle as is, i.e., without changes such as file size compression, conversion to another format, and the like. We can safely access files in the public folder in our code using absolute paths. And the last thing from the project structure that is important to discuss is vite.config.js. A project using the Vite project bundler can have a configuration file, vite.config.js. Currently, we don't have such a file because when initializing the project, we chose the vanilla option and the JavaScript variant. Vite will work perfectly without this file, using its default settings. But in any case, I recommend creating this file; it can be very useful. So, in the project root, we manually create the file vite.config.js. Let's go back to the Vite documentation and open the config reference page from the left menu. Here we can find an example of a basic configuration. We can take this one with importing the defineConfig function and exporting the result of calling this function. An object with Vite configuration is passed as an argument to the defineConfig function. The properties in this object that we can specify will override specific default Vite settings. That is, with the current situation with an empty object, we have literally done nothing. Vite will work as before, using its basic settings. Most beginners don't need the vite.config.js file at all; everything is already configured. But if you want, you can connect additional plugins here, change the port for the dev server. My favorite thing is that you can configure aliases here. More on that later. You can also configure the project's root folder here or change the public folder for static files to something else. And in general, you can do a lot, a lot here. For now, let's not add anything here. We will return to this file later. Let's discuss in more detail how styles are handled in Vite. In Vite, you don't connect CSS via a link tag in HTML. Instead, you import styles directly into JS files. Why is that? It's actually just convenient. You decide which styles belong to which component, and everything is connected automatically. Vite will figure it out. For the sake of experiment, let's delete all files from the SRC folder except main.js. If anything, the build is still running in dev mode, and don't pay attention to errors in the terminal if they appear, yes, like these. Now let's go into the main.js file and delete all its contents. Well, just completely. Now, let's create a styles.css file in the SRC folder. Let's write something like this, i.e., paint the page background in some shade. Now let's go back to the main.js file and add an import of our new styles file at the beginning. Like this. And now, if we look in the browser, we will see how the background of the empty page has become blue. This style. If you prefer to work with styles using a preprocessor, for example, Sass, then using it with Vite is very simple. First, install the package. I stop the running dev mode command with Ctrl+C and enter the command npm install -D, i.e., install the Sass library as a dev dependency. And that's it. We can already use scss or sass files, just like CSS. No additional settings in vite.config.js are required. Let's just change the extension of this file to styles.scss. After renaming the file, my IDE WebStorm immediately picked up these changes. And in the main.js file, at the end of the import line, the extension automatically changed to scss. Let's use some feature of the style preprocessor in the styles.scss file. For example, let's declare a variable $color-pink in Sass variable format and use this variable in the background-color property. Now let's launch the dev server again with the command npm run dev. Let's switch to the browser and look. The page background has changed to a new color. This means our Sass style preprocessor connected to the project is working great. In addition to style preprocessors, we can use the CSS Modules mechanism. If you already know this approach, you can skip to the next timestamp. For others, a brief explanation. Vite supports CSS Modules out of the box. This means you can write styles that will only apply to a specific component. To understand what CSS Modules are and how they can be useful, we will need some primitive UI component. Since we don't have a markup templating engine yet, let's create it using regular JavaScript. In the SRC folder, let's add a new folder Components. Inside it, a folder Button, capitalized. In this folder, let's create an index.js file for greater convenience of further imports. And in the newly created index.js file, let's write export default () => { return `...`; };. Now let's go back to the main.js file. Immediately after importing the general styles, let's import the Button entity, capitalized, from the following path. In fact, Button here is a function that returns the markup of a button, a string with the markup of a button. In index.html, in the markup, we have a div with the id "app" by default. Let's find this element in the script using document.querySelector and render the following markup through innerHTML. Let it be a section. And inside, through string interpolation, i.e., through expressions with a dollar sign, let's insert three such buttons. Let's look in the browser. And visually, and according to the Elements tab in DevTools, we see a section element with three buttons inside within the element with the ID "app." Now let's deal with CSS Modules. Let's go back to the Button folder. Let's create a file here, Button.module.scss.scss. You can use any extension: scss, sass, css. Any will work. But the main rule for CSS Modules: at the end of the file name, before the extension, there must be the word "module" without an "s" at the end. Not "modules," but "module." This is important. In this module file, let's write two selectors. The first class is "root" for the component's root wrapper. Here we will specify a blue color. The second selector is the class "label." Here we will specify color: white. Class names in the module styles file can be anything, but usually, they are one or two words in camelCase notation. Let's go to the index.js file in the Button folder. At the beginning of the file, let's import the styles entity from the following path. That is, we are referencing the adjacent file with module styles. The name of the imported entity can be anything. ButtonStyles, just the letter S, or anything else. I'm used to writing "styles." This name is quite concise. Next, in the markup, for the button element, let's add a class attribute, and in the value, within double quotes, let's use string interpolation syntax. Let's write a dollar sign and curly braces. Inside these braces, we can use any JS expressions. Remember, here we are accessing the styles entity and, attention, through a dot, like in objects, we are accessing the root property. Get the gist. The styles entity is an object with properties. Each property is a CSS class from the styles file. Let's open it side by side to make it clearer. That is, in the styles object, we have fields "root" and "label." We have already used the CSS class "root" on the component's root element. And by analogy, we can use the "label" class. Let's wrap this click in a span. And let's assign the class "styles.label" to this span. Okay, let's check in the browser. We already see that the buttons have changed color according to the styles described in the Button.module.css file. And if we look through DevTools at the classes of these button elements, we will see these "crocodiles." Why is this so, and why is it needed at all? By using CSS Modules, we can use the same CSS classes in module style files for different components. Thus, CSS Modules allow for maximum isolation of components from each other, so that in the source code, the same words can be used for CSS classes. That is, literally, we can create another component, for example, an input. And in its input.module.css file, we can use the same classes as for the button component, i.e., "root" and "label." As a result, there will be no conflicts in the browser. All class names are made unique for each component using prefixes and suffixes like these. Well, in this case, only suffixes. The next feature of the Vite project bundler that will save your nerves is aliases. As your project grows, writing paths like ./components/button and similar in imports becomes very painful. To demonstrate the problem, let's create a mixins.scss file in the SRC folder. In it, let's write some Sass mixin. Let it be FlexCenter. And here are the properties: display: flex, justify-content: center, align-items: center. Let's move on. In our project, in the SRC folder, there is a Components folder. Inside it, a Button folder with the following files: button.module.css and index.js. We created all of this as part of the CSS Modules explanation. If you skipped this topic and jumped directly to the current timestamp, just create any scss file in the Button folder. So, we want, for example, in button.module.scss, to use the mixin from the Mixins file. To do this, we need to use the Sass directive @use. It, in essence, replaces the outdated @import. Then we need to specify the path to the file with mixins. This is where the mess begins. In the path, we need to go up the folder hierarchy two levels and only then refer to the mixins.scss.scss file. After the path, we specify @use "..." as *; to make all entities from the mixins file appear, let's say, in the global scope. And now, anywhere, for example, in the selector by the class "root," let's use our mixin, i.e., @include flex-center. Like this. Let's jump to the browser, select the button element, and see that the properties have been applied. This means the mixin is working. Now let's return to this mess. Writing such constructions like "./" is a sin. Pity yourself and other project developers and configure aliases. Let's go to vite.config.js. At the beginning of the file, after the first line with import, let's add the import of the path entity from the same path. import path from 'path'; This is a special object from the JavaScript world with helper functions for working with paths. Don't delve too deeply into this for now, just follow me. Now, in the empty defineConfig object, let's add the resolve property. The value is also an object. In this object, we need to specify the alias property and in the value, another object. And here, as the property name, we specify a string that will be our alias. I usually use exactly one character, i.e., the "@" symbol. And as the value of this property, let's write the following. We access the path entity object and call the resolve method through a dot. We pass the __dirname entity as the first argument. This entity is in the global scope when working with the Node.js environment, where Vite is launched. As the second argument to the resolve method, we pass a string with the path that will be automatically substituted where the "@" alias is used. We need to specify the relative path to "./src". And if you are using the latest versions of WebStorm, you don't need to configure anything else. Otherwise, one more small adjustment is required. I will do it with you so that you don't get confused. In the root folder of the project, let's create a jsconfig.json file. In this file, let's write the following. Just follow me. An object that has a compilerOptions property with another object as its value. And here there are two properties: baseUrl with a value of "." and a property named paths with another object as its value. And here we will have the following: "@/*" and in the value, attention, an array with the string "src/*". Like this. This jsconfig.json file is solely for alias compatibility with your IDE. Without it, everything should also work, but you might get obscure warnings or even errors during imports. Okay, let's check. In the button.module.scss file. All this mess with "./" in the path can be replaced with the concise syntax "@ /mixins.scss". That is, as if we are referencing relative to the src root folder. Aliases allow, regardless of the depth of the folder hierarchy, to use the same, identical, and obvious paths to any project files, wherever they are located. If we go to the browser, we will see that everything still works perfectly. Next, let's briefly discuss how to work with icons, images, and other similar media content in Vite. Regardless of which framework you are using, React, Vue, or if you are writing in vanilla JS, there are at least two universal ways. Method one: place images and SVG files in the public folder. When initializing Vite, this test icon was already provided here. Let's use it. We want to display this icon through an img element. Let's go to the main.js file. Here, inside the element with the ID "app," we display the following markup: a section and three buttons inside. Let's add an img tag anywhere in the markup of this section, let's add it at the end. In the value of its src attribute, we can specify "vite.svg," and everything will already work. That is, we reference files located in the public folder using absolute paths with a slash at the beginning. And in the browser, we will see the successful result of displaying the img, which refers to the vite.svg file. The next method is needed if we are referencing a file that is located inside the SRC folder. Let's copy and paste this file. And place its copy in the SRC folder, in the Icons subdirectory. Let's name the copy icon-vite.svg for clarity. And in the main.js file, at the beginning, after the current group of imports, let's add the following: import iconViteSrc from '@/icons/icon-vite.svg'; Later I will explain why. And using the alias, we refer to the corresponding file. Here we assign any name to the imported entity, but for clarity, I call it iconViteSrc. In the path, we can again use the alias, since we have configured it. Here we have referenced a specific file within the SRC folder. The iconViteSrc entity contains nothing more than a string with the path to this file, but not a regular string, a smarter one. Now, for this img in the markup, in the src attribute, we can replace this value through string interpolation and use the iconViteSrc entity. Let's go to the browser. We see that everything is still displayed wonderfully, and in the SRC attribute, there will be this "crocodile." This is how it should be. If you ask why this import is needed and why you can't just specify a string with the path to this file in SRC? Well, let's comment this out and write it like this here. This way, we will get an error in the browser. Such a file will not be found. And even if we remove it and try to reference it directly, i.e., to ./icons/icon-vite.svg, we will still get an error. Well, or rather, the file will not be found. That is, for correct processing of paths to media resources, such as images, SVG icons, video files, and the like, you need to use one of the two methods I showed. And a couple of words about the mechanism of combining all SVG icons in the project into a single sprite. Vite does not have this capability out of the box, but there are many plugins that simplify working with sprites. One of them is the vite-plugin-svg-sprite. I won't show how to work with it in detail. On the documentation page, even on the npm page, everything is described in detail on how to connect and use it. A couple more words about how to automate development using a project bundler. As you know, the component approach in front-end development is literally the foundation of high-quality interfaces. Even without any project bundlers, at the markup level, we isolate individual blocks as independent, reusable components. However, having such a powerful tool as Vite, when creating another button on the page, it's a sin to engage in copy-pasting markup. Within this video tutorial, to demonstrate the operation of CSS Modules, we created a JS file with the markup for the button component. In essence, we implemented the mechanism of a primitive markup templating engine. That is, we can even pass some arguments to this function. an additional CSS class, a different value for the type attribute, specific text content, individual for each of the buttons that are displayed here through such a call. And all of this will also work. But still, we reinvented the wheel. If you want more features, you need a markup templating engine. Over the entire history of front-end development, dozens and perhaps even hundreds of them have been created. The most prominent among them are EJS, Pug, Handlebars. All of them have their specific syntax and different capabilities. For Vite, you can find a plugin to work with any of the above markup templating engines, and not only. However, I strongly do not recommend getting bogged down in configuring these things. Most markup templating engines are morally outdated with the advent of frameworks like Vue, Angular, and the React library. Each of these modern tools has its own implementation of the markup templating mechanism. For example, React has the excellent and convenient JSX syntax. And this very JSX, it seems, we can use without a strict binding to React, i.e., for creating a regular vanilla JavaScript application. If you search on Google for "Vite JSX markup generation" or talk about this topic with ChatGPT, you will be told that it is supposedly easy to do without any special settings. In reality, there is a huge nuance. The task of a markup templating engine for a vanilla JavaScript application is to conveniently generate HTML pages at the development stage, but without complex settings in Vite. JSX in the final application will only work at runtime, i.e., literally through JavaScript to draw markup in the user's browser. We need a so-called SSG (Static Site Generator). Configuring it yourself is a real pain, believe me, I've tried. But you can use tools like Astro, RSPress, or Minista. The very one that I used in my powerful paid masterclass on Stepik. I will make a separate video for YouTube about one of these tools. But for now, let's move on to Vite. When you finish development with Vite and want to build the project for production, use the npm build command. This command will build an optimized project into the dist folder. Everything here will be compressed, minified, and ready to be uploaded to hosting. But you won't be able to simply open the HTML file from this folder in the browser. Well, formally you can, but scripts, styles, and other resources will break due to CORS errors. To properly see how your project looks after the build, i.e., in production format, after the build, run the command npm run preview. Vite will launch a local server at the following address, where you can see how your site looks in real production. This is especially useful to ensure that everything works not only in development mode but also after the build. If you are a beginner, just take Vite. Don't waste time learning dozens of outdated tools if you can immediately start writing code using a powerful project bundler. The link to the Vite documentation is in the description below this video. Everything there is concise, clear, and with examples. If you have any questions, write them in the comments below the video or in the Telegram chat. And the next video will be about a very cool markup templating engine with JSX syntax. Don't miss it. Thanks for watching. Subscribe and see you in the next videos. M.