From webpack to vite: custom module resolution, sass import, babel config
Tags: webdev, vite, webpack
Published: 2023-04-30 10:44:53

## Background

Being a long time Webpack user and mastering most of its features, i was reluctant to migrate to other build tool. 

On the other side, news like [Storybook improving vite support](https://storybook.js.org/blog/first-class-vite-support-in-storybook/) or how [Vite is getting fast](https://vitejs.dev/blog/announcing-vite4-3.html) lead me to consider migrating away from the ageing tool. The main Webpack developer [moving to another project](https://vercel.com/blog/turbopack) helped in the decision to modernize the build stack.

I could try [Turbopack](https://turbo.build/pack) or [Rspack](https://www.rspack.dev/) that explicitly aims to be a webpack successor but i decided to go with [Vite](https://vitejs.dev/) which is more mature at this time.

Below are the issues i faced and how i overcome them.

## Custom module resolution

I have configured Webpack to lookup for modules in `./src` and `./src/common`. The `resolve.modules` option makes it straight forward:

```js
 {
   //.. 
   resolve: {
     modules: [
        path.resolve(__dirname, './src/common'),
        path.resolve(__dirname, './src'),
        'node_modules',
     ],
   },
 } 
```

This is an option that i was expecting to be exposed by Vite, but is not and [will not be](https://github.com/vitejs/vite/issues/8439#issuecomment-1492976222).  

Following suggestion in the issue, i looked at [vite-tsconfig-paths](https://github.com/aleclarson/vite-tsconfig-paths) which is even better because i already have configured vscode  through typescript config:

```json
{
  "compilerOptions": {
    "experimentalDecorators": true,
    // This must be specified if "paths" is set
    "baseUrl": "./src/",
    // Relative to "baseUrl"
    "paths": {
      "*": [
        "./common/*",
        "*"
      ]
    }
  }
}
```

One small problem delayed a bit the migration: [lack of support to jsconfig.json](https://github.com/aleclarson/vite-tsconfig-paths/issues/22). Renaming jsconfig.json to tsconfig.json and adding `allowJs` option made it work.

As a bonus, the module lookup configuration is now in only one place. 

## Importing external sass modules 

With Webpack i have to add a "~" in front of module name in order of a sass import.

Vite does not require it.

```scss
@import '~bootstrap/scss/bootstrap';
```
becomes

```scss
@import 'bootstrap/scss/bootstrap';
```

## Babel configuration

I use decorators extensively in my projects, so Babel is required. [vite-plugin-babel](https://github.com/owlsdepartment/vite-plugin-babel) does what i need: transpile both in development and in production. 

It worked at first just by following project instructions, but needs some tweaking to match my requirements:

- Add source maps in development. Option `babelConfig: { sourceMaps: mode === 'development' ? 'inline' : false }` made it work.
- Exclude node_modules. By default vite-plugin-babel transpile all javascript including the ones from external packages. Setting `filter: /^(?!.*node_modules(?!.*luipack)).*\.jsx?$/` did the trick (luipack module needs to be transpiled) 

## Initial impressions

So far, the result is what i expected: faster startup and reload with less configuration. 

I only migrated a starter application but i hope to get same benefits with the actual / big projects.