Search code examples
vue.jsbuildvuejs3viterollup

How to build from the same code source different bundles?


I am working on a web app and trying to build a "light" version of it without all the features that are going to be served on a different address.

I don't want to fork the project and have to maintain 2 codebases.

For the most part, just commenting the routes I want excluded for the "light" build gives me the expected result. I just have to hide the links to these routes on the client side, which can be done conditionally with an env variable.

However, I don't know how to filter the routes I don't want at build time. I tried with an env variable without success:

import App from "@/App.vue";

const routes = [
  {
    path: "/",
    name: "main",
    component: App
  },
  {
    path: "/login",
    name: "login",
    component: () => import("@/routes/Login.vue")
  },
  {
    path: "/sign-up",
    name: "sign-up",
    component: () => import("@/routes/CreateAccount.vue"),
  },
  {
    path: "/settings",
    name: "settings",
    component: () => import("@/routes/Settings.vue"),
  },
  ...
]

const filteredRoutes = process.env.VITE_BUILD_MODE === 'light' ? routes.filter(route => route.path !== '/settings') : routes;

const router = createRouter({
  history: createWebHistory(),
  routes: filteredRoutes,
});

export default router;

This bundles the whole project and when served doesn't allow navigation to the filtered routes, but the code is still present in the bundle.

Is there a way to exclude those routes at build time and have a smaller bundle ?


Solution

  • I managed to find a solution.

    First I created a route.js file with all my routes and a routes-light.js file with a subset for the "light" version.

    Then I used an alias @routes to import the routes in my router file:

    import { createRouter, createWebHashHistory } from "vue-router";
    import routes from "@routes";
    
    const router = createRouter({
      history: createWebHashHistory(),
      routes,
    });
    
    export default router;
    

    In the vite.config.js file I defined the alias:

    export default defineConfig({
      resolve: {
        alias: {
          "@": fileURLToPath(new URL("./src", import.meta.url)),
          "@routes": fileURLToPath(new URL("./src/router/routes.js", import.meta.url)),
        },
      },
    //...
    });
    

    And I created a new config file for the light mode vite.config.light.js with the alias @routes pointing to the route-light.js file:

    export default defineConfig({
      resolve: {
        alias: {
          "@": fileURLToPath(new URL("./src", import.meta.url)),
          "@routes": fileURLToPath(new URL("./src/router/routes-light.js", import.meta.url)),
        },
      },
    //...
    });
    

    Now if I build using:

    vite build --config vite.config.light.js

    I get the expected result.