

Migrating your React app from Webpack to Vite
source link: https://dev.to/wojtekmaj/migrating-your-react-app-from-webpack-to-vite-inp
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

What is Vite?
Vite is a "next generation front-end tooling", as its maintainers claim. Instant dev server, fast Hot Module Reload, easy configuration, optimized production builds - it's all there.
But… Vite's documentation doesn't say how to migrate your existing Webpack app 🤷 Worry not! In this guide, we'll get through this together!
Change your repo to ES modules
In your package.json
, add the following entry:
"type": "module",
Enter fullscreen mode
Exit fullscreen mode
Embrace modernity! Reject tradition! That's why we're switching to Vite anyway!
Install Vite and its plugins
npm i --save-dev vite @vitejs/plugin-react vite-plugin-html
Enter fullscreen mode
Exit fullscreen mode
yarn add vite @vitejs/plugin-react vite-plugin-html --dev
Enter fullscreen mode
Exit fullscreen mode
Replace scripts
In your package.json
, you'll probably have scripts similar to these:
"build": "NODE_ENV=production webpack",
"dev": "NODE_ENV=development webpack serve",
Enter fullscreen mode
Exit fullscreen mode
build
command, invoked by npm run build
or yarn build
, builds your app for production. dev
command starts a development server.
These scripts needs to be replaced with:
"build": "vite build",
"dev": "vite serve",
Enter fullscreen mode
Exit fullscreen mode
On top of that, you can add one extra command:
"preview": "vite preview"
Enter fullscreen mode
Exit fullscreen mode
preview
command will start a server running your app built for production.
Let's run the development server!
vite v2.9.1 dev server running at:
> Local: http://localhost:3000/
> Network: use --host to expose
ready in 261ms.
Enter fullscreen mode
Exit fullscreen mode
👁👄👁 Wow, that is fast.
Teach Vite where the root is
If you started the development server now, Vite will look for index.html
in your project's root directory. If it's anywhere else, Vite will not be able to find it and will display an empty page instead.
To fix this, you need to either move index.html
to your root directory, or specify a different root directory for Vite to look for index.html
in. In my case, it's located at src/index.html
.
You can do this by adding root directory path to your commands, like this:
"build": "vite build src",
"dev": "vite serve src",
Enter fullscreen mode
Exit fullscreen mode
However, you can also do this by creating a vite.config.js
file in your project root. You will need it in a short while anyway, so why not create one now to keep all the configuration in one place?
import { defineConfig } from 'vite';
export default defineConfig({
root: 'src',
build: {
// Relative to the root
outDir: '../dist',
},
});
Enter fullscreen mode
Exit fullscreen mode
Configure vite-plugin-html
Now that Vite knows where to find your index.html
file, it will try and parse it.
You may encounter an error like me:
How to deal with it? I was using HtmlWebpackPlugin
's templateParameters
option to dynamically inject custom title and other info into index.html
file, like so:
<title><%= title %></title>
Enter fullscreen mode
Exit fullscreen mode
new HtmlWebpackPlugin({
template: 'index.html',
templateParameters: {
title: env === 'production' ? 'My site' : `My site [${env.toUpperCase()}]`,
},
}),
Enter fullscreen mode
Exit fullscreen mode
Thankfully, we can do the same with vite-plugin-html
. In your vite.config.js
, add the following bits:
import { createHtmlPlugin } from 'vite-plugin-html';
export default defineConfig({
// …
plugins: [
createHtmlPlugin({
inject: {
data: {
title: env === 'production' ? 'My site' : `My site [${env.toUpperCase()}]`,
},
},
}),
],
});
Enter fullscreen mode
Exit fullscreen mode
Add entry module to your index.html
file
At this point, your index.html
file should be served just fine. But the app still won't load!
If you used Webpack, you probably have also used html-webpack-plugin
to handle injecting <script>
tag(s) with your entry module(s) to index.html
.
Vite will not inject these tags automatically. You will need to add them by yourself. For example:
<script type="module" src="./index.jsx"></script>
Enter fullscreen mode
Exit fullscreen mode
Aaah, that's better. Something came to life.
Configure @vitejs/plugin-react
Okay, as you can see, we're not quite there yet. We need to configure @vitejs/plugin-react
to make it work with React.
If you still used classic JSX runtime, your app may already load at this point, but you'll want to follow these steps anyway. This plugin will not only handle automatic JSX runtime (the one thanks to which you don't need to manually import React in every file), but also add features like Fast Refresh, enable Babel integration, and much, much more.
Add it to your vite.config.js
file like so:
import react from '@vitejs/plugin-react';
export default defineConfig({
// …
plugins: [
// …
react({
// Use React plugin in all *.jsx and *.tsx files
include: '**/*.{jsx,tsx}',
}),
],
});
Enter fullscreen mode
Exit fullscreen mode
Babel plugins
You might not need Babel at all, as @babel/preset-env
and @babel/preset-react
are of no use.
But sometimes Babel plugins may still come in handy. For example, there's a plugin to remove PropTypes you can use to make bundle size a bit smaller, and there's a dedicated plugin for styled-components that makes development and testing easier by, among others, adding component display names.
@vitejs/plugin-react
will come to the rescue here, with babel
option. For example, to add babel-plugin-styled-components
plugin:
react({
// …
babel: {
plugins: ['babel-plugin-styled-components'],
},
},
Enter fullscreen mode
Exit fullscreen mode
Static files handling
By default, files from public
directory placed in your root directory are going to be copied over at build time. If you have these files elsewhere, you can use publicDir
option like so:
export default defineConfig({
// …
publicDir: '../public',
});
Enter fullscreen mode
Exit fullscreen mode
The process.env.*
problem
I was using process.env.NODE_ENV
in a bunch of places in my app. This resulted in the following error being thrown in the console:
Uncaught ReferenceError: process is not defined
Enter fullscreen mode
Exit fullscreen mode
In Vite, you can use import.meta.env.*
instead. For example, process.env.NODE_ENV
can be replaced with import.meta.env.NODE_ENV
.
Enjoy!
Now you should see your app, powered by Vite!
We're not done yet; we'll still need to tweak a few things before running it in production. For this, you'll have to wait for the second part of this guide. Subscribe to get notified!
Cleaning up
You can safely remove these dependencies, which are now unused:
-
webpack
(duh) webpack-cli
webpack-dev-server
-
*-loader
(e.g.babel-loader
,style-loader
) -
*-webpack-plugin
(e.g.html-webpack-plugin
,mini-css-extract-plugin
@babel/preset-env
@babel/preset-react
webpack.config.js
Webpack config file can also be deleted.
babel.config.js
, babel.config.json
, or .babelrc
can be deleted, provided that you didn't use it as your Babel config in @vitejs/plugin-react
configuration.
Anything missing?
Do you think there's anything else that needs to be addressed, that may be a common problem when migrating from Webpack to Vite? Please, please let me know in the comments!
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK