Vite: Webpack Killer or Something Else?
What is Vite?
Vite is a build tool and development server for modern JavaScript applications. It aims to provide a faster and more efficient development experience for developers by using the native ES modules feature in the browser.
Vite uses the native ES modules feature in the browser to handle the imports of your JavaScript files, which allows for faster development builds and hot module replacement. This means that you can see your changes in the browser instantly without having to wait for a full build process to finish. Vite also has a plugin system that allows you to add additional functionality, such as TypeScript support or JSX transpilation.
One of the key features of Vite is its ability to handle large JavaScript projects with ease. Unlike other build tools, Vite does not require a configuration file, which can save developers a lot of time and hassle. Instead, it uses conventions and sensible defaults to handle the build process, which allows developers to focus on writing code rather than configuring the build process.
Another important aspect of Vite is its ease of use. It is designed to be easy to set up and get started with, and it has a simple command-line interface that makes it easy to use for developers of all skill levels. Additionally, Vite has a built-in development server that automatically reloads the browser when you make changes to your code, which makes the development process even more efficient.
Vite also has excellent documentation, which makes it easy for developers to learn how to use it and troubleshoot any issues that may arise. The documentation is clear, concise, and easy to understand, and it includes a wide range of examples and tutorials to help developers get started quickly.
The problems
Before the availability of ES modules in browsers, developers had to rely on external tools to write modularized JavaScript code. This led to the development of “bundling” tools like webpack, Rollup and Parcel, which improved the frontend development experience.
However, as applications have become more complex and large, the amount of JavaScript code has also increased, leading to performance bottlenecks with these tools. Long wait times to spin up a development server and slow feedback loops can greatly impact developer productivity and satisfaction. Vite addresses these issues by utilizing the native support for ES modules in the browser and leveraging advancements in JavaScript tools written in languages that can be compiled to native code. This allows for faster development builds and hot module replacement, improving the overall development experience.
-> Slow Server Start
When cold-starting the dev server, a bundler-based build setup has to eagerly crawl and build your entire application before it can be served.
Vite improves the dev server start time by first dividing the modules in an application into two categories: dependencies and source code.
- Dependencies are mostly plain JavaScript that do not change often during development. Some large dependencies (e.g. component libraries with hundreds of modules) are also quite expensive to process. Dependencies may also be shipped in various module formats (e.g. ESM or CommonJS).
- Vite pre-bundles dependencies using esbuild. esbuild is written in Go and pre-bundles dependencies 10–100x faster than JavaScript-based bundlers.
- Source code often contains non-plain JavaScript that needs transforming (e.g. JSX, CSS or Vue/Svelte components), and will be edited very often. Also, not all source code needs to be loaded at the same time (e.g. with route-based code-splitting).
- Vite serves source code over native ESM. This is essentially letting the browser take over part of the job of a bundler: Vite only needs to transform and serve source code on demand, as the browser requests it. Code behind conditional dynamic imports is only processed if actually used on the current screen.
-> Slow Updates
When a file is edited in a bundler-based build setup, it is inefficient to rebuild the whole bundle for obvious reasons: the update speed will degrade linearly with the size of the app.
In some bundlers, the dev server runs the bundling in memory so that it only needs to invalidate part of its module graph when a file changes, but it still needs to re-construct the entire bundle and reload the web page. Reconstructing the bundle can be expensive, and reloading the page blows away the current state of the application. This is why some bundlers support Hot Module Replacement (HMR): allowing a module to “hot replace” itself without affecting the rest of the page. This greatly improves DX — however, in practice we’ve found that even HMR update speed deteriorates significantly as the size of the application grows.
In Vite, HMR is performed over native ESM. When a file is edited, Vite only needs to precisely invalidate the chain between the edited module and its closest HMR boundary (most of the time only the module itself), making HMR updates consistently fast regardless of the size of your application.
Vite also leverages HTTP headers to speed up full page reloads (again, let the browser do more work for us): source code module requests are made conditional via 304 Not Modified
, and dependency module requests are strongly cached via Cache-Control: max-age=31536000,immutable
so they don't hit the server again once cached.
Once you experience how fast Vite is, I highly doubt you’d be willing to put up with bundled development again.
Basic usage of Vite
Here is an example of how to use Vite to set up a simple JavaScript project:
- First, you will need to install Vite on your machine by running the following command:
# npm
npm create vite@latest
# yarn
yarn create vite
# pnpm
pnpm create vite
2. Initialize a new project by running:
# npm 6.x
npm create vite@latest my-vue-app --template vue
# npm 7+, extra double-dash is needed:
npm create vite@latest my-vue-app -- --template vue
# yarn
yarn create vite my-vue-app --template vue
# pnpm
pnpm create vite my-vue-app --template vue
3. Now you can start the development server by running the following command:
vite
4. This will create a new index.html
file in your project directory and open it in your default browser. The development server will also be running on http://localhost:3000
5. You can start writing your JavaScript code in the src
folder, and Vite will handle the imports and automatically reload the browser when you make changes to your code.
That’s it! You now have a working development environment set up with Vite. You can add more files to your project and use the modern JavaScript features without any configuration.
Note: Vite also has a lot of options and plugins you can use to customize your development environment and add more functionality, but this is the basic usage.
Configuration
Vite does not require a configuration file by default, instead it uses conventions and sensible defaults to handle the build process. However, you can create a vite.config.js
file in the root of your project to customize the behavior of Vite. Here is an example of a basic vite.config.js
file:
module.exports = {
// Enable the esbuild plugin, which will transpile modern JavaScript to compatible with older browsers
esbuild: {
minify: true,
target: 'es5'
},
// Enable the TypeScript plugin
plugins: [
require('vite-plugin-typescript')
]
}
This configuration file enables the esbuild plugin, which will minify and transpile modern JavaScript to ES5 so it is compatible with older browsers, and also enables the TypeScript plugin.
You can also add other options like the root directory of your project, proxy settings, alias, or define custom middleware.
module.exports = {
alias: {
'@': '/src',
},
plugins: [
'vite-plugin-typescript',
],
};
In this example, I’m using the alias
option to configure Vite to recognize the @
symbol as an alias for the src
folder. This allows you to use shorter imports, such as import { foo } from '@/bar'
instead of import { foo } from './src/bar'
.
Additionally, I’m using the plugins
option to configure Vite to use the vite-plugin-typescript
plugin, which allows Vite to transpile TypeScript code. To use it, you need to install it first by running npm install vite-plugin-typescript
.
There are other options you can use to configure Vite, such as root
, port
, assetsDir
, outDir
and more, you can check the official documentation for more details https://vitejs.com/docs/config.
It’s worth noting that even though you can use a config file, Vite is intended to be simple, flexible and fast for small-medium projects, it’s not suitable for large monolithic applications that require more complex build processes and configurations.
import { defineConfig, loadEnv } from 'vite';
import path from 'path';
import { createVuePlugin } from 'vite-plugin-vue2';
import envCompatible from 'vite-plugin-env-compatible';
import { injectHtml } from 'vite-plugin-html';
import { viteCommonjs } from '@originjs/vite-plugin-commonjs';
// https://vitejs.dev/config/
export default defineConfig(({ command, mode }) => {
const { OUTPUT_DIR, VITE_PORT } = loadEnv(mode, process.cwd(), '');
return {
resolve: {
alias: [
{
find: /^~/,
replacement: '',
},
{
find: '@',
replacement: path.resolve(__dirname, 'src'),
},
{
find: '@trendyol/sc-ui-kit',
replacement: path.resolve(__dirname, 'node_modules/@trendyol/sc-ui-kit/dist'),
},
],
extensions: [
'.mjs',
'.js',
'.ts',
'.jsx',
'.tsx',
'.json',
'.vue',
],
},
plugins: [
createVuePlugin({ jsx: true }),
viteCommonjs(),
envCompatible(),
injectHtml(),
],
css: {
devSourcemap: false,
preprocessorOptions: {
sass: {
prependData: '@import "@/styles";',
quietDeps: true,
},
scss: {
additionalData: '@import "@/styles";',
quietDeps: true,
},
},
},
test: {
globals: true,
},
server: {
strictPort: false,
port: VITE_PORT,
},
build: {
sourcemap: true,
outDir: OUTPUT_DIR,
},
};
});
An example Vite config from my project on Trendyol
Why we should use Vite?
Vite has several advantages:
- Fast development builds: Vite uses the native ES modules feature in the browser to handle imports, which allows for faster development builds and hot module replacement. This means that you can see your changes in the browser instantly without having to wait for a full build process to finish.
- No configuration required: Vite does not require a configuration file, which can save developers a lot of time and hassle. Instead, it uses conventions and sensible defaults to handle the build process, which allows developers to focus on writing code rather than configuring the build process.
- Easy to use: Vite is designed to be easy to set up and get started with, and it has a simple command-line interface that makes it easy to use for developers of all skill levels.
- Built-in development server: Vite has a built-in development server that automatically reloads the browser when you make changes to your code, which makes the development process even more efficient.
- Excellent documentation: Vite has excellent documentation, which makes it easy for developers to learn how to use it and troubleshoot any issues that may arise.
On the other hand, Vite also has some disadvantages:
- Limited browser support: Vite relies on the native ES modules feature in the browser, which is not fully supported by all browsers yet. This means that some users may not be able to use your application if they are using an older browser.
- Limited plugin ecosystem: Vite has a relatively limited plugin ecosystem compared to other build tools, which means that it may not have all the features or functionality that some developers need.
- Limited production build features: Vite is primarily focused on development builds and may not have as many features for production builds as other build tools.
- Not as widely adopted: Vite is a relatively new build tool and may not be as widely adopted by the community as other more established build tools, which can make finding help or resources more difficult.
- Not suitable for large monolithic applications: Vite is designed to be simple and fast, so it may not be the best option for large monolithic applications that require more complex build processes.
Comparison with others
Vite is a relatively new build tool and it is different from other more established build tools like webpack or Parcel in several ways:
- Vite uses the native ES modules feature in the browser to handle imports, while webpack and Parcel use a more traditional approach of bundling all the files together. This allows for faster development builds and hot module replacement with Vite.
- Vite does not require a configuration file, which makes it simpler to set up and use than webpack or Parcel.
- Vite has a relatively limited plugin ecosystem compared to webpack or Parcel.
- Vite is primarily focused on development builds and may not have as many features for production builds as webpack or Parcel.
- Vite is a relatively new build tool and may not be as widely adopted by the community as webpack or Parcel, which can make finding help or resources more difficult.
In summary, Vite is a great option for developers who are looking for a faster and more efficient way to build and develop JavaScript applications, especially for small-medium size projects. Webpack and Parcel are more widely adopted, have more advanced features and more plugins available. It’s best to evaluate the needs of your specific project and choose the tool that best fits your needs.
Migration from Webpack
Migrating from webpack to Vite can be a straightforward process, but there are a few things to keep in mind:
- Make sure your codebase is using the latest features of JavaScript, such as ES modules, as Vite relies on them to handle imports.
- You will need to remove any webpack-specific configuration files, such as webpack.config.js, and replace them with a vite.config.js file.
- You will need to update your package.json file to replace webpack commands with Vite commands.
- Review your project’s dependencies and remove any webpack loaders or plugins that are no longer needed.
- Test your application thoroughly after the migration to make sure everything is working as expected.
- In case of using plugins or loaders that are not supported by Vite, you will have to find alternatives or implement them manually.
It is also recommended to do the migration step by step, testing and fixing issues along the way, instead of doing everything at once. This will make the process less stressful and you will have more control over the outcome.
Also, you can look this plugin for migration: https://github.com/originjs/webpack-to-vite
Keep in mind that Vite is a simpler and faster build tool, it is designed to handle small-medium size projects, if your project is a large monolithic application, you may want to evaluate if Vite is the best option for you or if you need to stick with webpack or other more established build tools.
Conclusion
In conclusion, Vite is a modern build tool and development server that is designed to provide a faster and more efficient development experience for JavaScript developers.
It uses the native ES modules feature in the browser to handle imports, which allows for faster development builds and hot module replacement. Vite also has a plugin system, ease of use, and excellent documentation. It can handle small-medium size projects with ease and does not require a configuration file.
It can be a great option for developers who are looking for a faster and more efficient way to build and develop JavaScript applications, especially for small-medium size projects.
However, it may not be the best option for large monolithic applications that require more complex build processes or for projects that require a more robust plugin ecosystem.
Migrating from webpack to Vite can be a straightforward process but needs to be done with care and step by step. It’s best to evaluate the needs of your specific project and choose the tool that best fits your needs.