Webpack Killed Again 😢: Guide to Migrate Electron Forge Webpack Project to Vite
Tags: electron, vite, react, webpack
Published: 2023-12-24 07:52:34

In this blog post, I'll take you through the steps I took to bid farewell to Webpack and welcome Vite into the world of Electron Forge. You'll find this guide incredibly beneficial if you're looking to streamline your development process, leverage Vite's lightning-fast bundling, and make your Electron app development smoother than ever before.

So Let's get started...

I assume that you are already having the a project running on `Electron Forge Webpack Template`

If you don't know what is Electron Forge and why you should use it. Check out this link -

https://www.electronforge.io/core-concepts/why-electron-forge

If you want to migrate to an existing Electron App to Electron Forge, then checkout this link. 

https://www.electronforge.io/import-existing-project

_So, Now I assume that you are having already having a project running on Electron Forge with Webpack template. When I first started using Electron Forge, there was not Vite template. So I use the webpack one._ 

**The Problem -** 😑

The webpack is no doubt a good old trusted bundler but when it comes to startup times and bundling, it's slow. Also if you are using frameworks like Vue or Lib's like React, Then it becomes more slow in bundling those assets.
Whereas, Vite is very fast in this and also Vite is gaining popularity everyday due to it's features. 

**The Simple Solution** 🙂
Electron Forge team has introduced the Vite template now and you can create a Electron Project with Vite as a tooling and bundling.
That's good right? Yeah, It's superb.

**Again There is a problem** 🫡

I don't know why but I found sometimes the Electron Forge document is not accurate which create issues. Right now there is no proper migration Guide. The is lack of information in migrating a new project. Current Document is about the Vite plugin https://www.electronforge.io/config/plugins/vite
but it's not enough for migrating the project.

I also faced the issues in migrating my existing project. I though let's figure it out and share it with my folks. 😎

Let's Get started now ... 

- First of all we have to install the Vite plugin for Electron Forge

```bash
npm install --save-dev @electron-forge/plugin-vite
```

- Now create three files in your root folder just in the same level as your `src` directory.

`vite.main.config.js` or `.ts` 
```js
import { defineConfig } from "vite";

// https://vitejs.dev/config
export default defineConfig({
  resolve: {
    // Some libs that can run in both Web and Node.js, such as `axios`, we need to tell Vite to build them in Node.js.
    browserField: false,
    conditions: ["node"],
    mainFields: ["module", "jsnext:main", "jsnext"],
  },
});

```
`vite.preload.config.js` or `.ts`

```js
import { defineConfig } from "vite";

// https://vitejs.dev/config
export default defineConfig({});

```
`vite.renderer.config.js` or `.ts`

```js
import { defineConfig } from "vite";

// https://vitejs.dev/config
export default defineConfig({});

```

- Now move your `index.html` from `src` to the root of the project. And paste the following lines - 

```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello World!</title>
  </head>
  <body>
    <h1>💖 Hello World!</h1>
    <p>Welcome to your Electron application.</p>
    <script type="module" src="./src/renderer.js"></script>
  </body>
</html>

```

- Update your `forge.config.js` 
```js
module.exports = {
  packagerConfig: {},
  rebuildConfig: {},
  makers: [
    {
      name: "@electron-forge/maker-squirrel",
      config: {},
    },
    {
      name: "@electron-forge/maker-zip",
      platforms: ["darwin"],
    },
    {
      name: "@electron-forge/maker-deb",
      config: {},
    },
    {
      name: "@electron-forge/maker-rpm",
      config: {},
    },
  ],
  plugins: [
    {
      name: "@electron-forge/plugin-vite",
      config: {
        // `build` can specify multiple entry builds, which can be Main process, Preload scripts, Worker process, etc.
        // If you are familiar with Vite configuration, it will look really familiar.
        build: [
          {
            // `entry` is just an alias for `build.lib.entry` in the corresponding file of `config`.
            entry: "src/main.js",
            config: "vite.main.config.js",
          },
          {
            entry: "src/preload.js",
            config: "vite.preload.config.js",
          },
        ],
        renderer: [
          {
            name: "main_window",
            config: "vite.renderer.config.js",
          },
        ],
      },
    },
  ],
};

```
- Update your `package.json` main entry from webpack to Vite.

```json
  "main": ".vite/build/main.js",
```

- Final step is to update our `main.js` with `Vite` specific variables to load our app. 

`main.js`

```js
const { app, BrowserWindow } = require("electron");
const path = require("path");

// Handle creating/removing shortcuts on Windows when installing/uninstalling.
if (require("electron-squirrel-startup")) {
  app.quit();
}

const createWindow = () => {
  // Create the browser window.
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, "preload.js"),
    },
  });

  console.log(MAIN_WINDOW_VITE_DEV_SERVER_URL);
  // and load the index.html of the app.
  if (MAIN_WINDOW_VITE_DEV_SERVER_URL) {
    mainWindow.loadURL(MAIN_WINDOW_VITE_DEV_SERVER_URL);
  } else {
    mainWindow.loadFile(
      path.join(__dirname, `../renderer/${MAIN_WINDOW_VITE_NAME}/index.html`)
    );
  }

  // Open the DevTools.
  mainWindow.webContents.openDevTools();
};

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on("ready", createWindow);

// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on("window-all-closed", () => {
  if (process.platform !== "darwin") {
    app.quit();
  }
});

app.on("activate", () => {
  // On OS X it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (BrowserWindow.getAllWindows().length === 0) {
    createWindow();
  }
});

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and import them here.
```

That's it. I know little long but worth doing. 

Now final step is to run our app and see `Vite` in action.

Run 

```bash
yarn start
# if using npm
# npm start
```

![Electron App Image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yha044h4vk1or97f49ev.png)

_That's it...Enjoy Vite with your existing Electron App_ 😎

If you have any issues, Let me know in the comment section. I would be happy to answer them all.

Save it for future and Like 👍 and Follow 👈 for more content. ✨