How to build SolidJS application with esbuild
Tags: solidjs, esbuild, javascript
Published: 2021-08-11 06:00:06

I this article, I'll show who to build [SolidJS](https://www.solidjs.com/) application with [esbuild](https://esbuild.github.io/).

# Code generation
First I generate code following [the documentation](https://www.solidjs.com/guide):
```sh
$ npx degit solidjs/templates/js esbuild-solid
npx: installed 1 in 0.664s
> cloned solidjs/templates#HEAD to esbuild-solid
```

# Add HTML

To add esbuild, without breaking the default Vite setup let's add a separate output directory. First, we will add `www/index.html`:
```HTML
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="shortcut icon" href="#" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <title>Solid App</title>
    <link href="./main.css" rel="stylesheet" />
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <script src="./main.js"></script>
  </body>
</html>
```

If you have HTTP access to the folder - as I do on http://localhost/github/esbuild-solid/www/ - you will see a white screen app, that complains in the browser console about files missing. We need to build the JS & CSS files for the app to work, but first, we need to install the dependencies.

# Dependencies

To install dependencies, we can run:
```sh
$ npm install --save-dev esbuild esbuild-plugin-solid

> esbuild@0.12.19 postinstall /home/marcin/workspace/github/esbuild-solid/node_modules/esbuild
> node install.js

npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN esbuild-plugin-solid@0.3.1 requires a peer of esbuild@^0.11 but none is installed. You must install peer dependencies yourself.
npm WARN esbuild-plugin-solid@0.3.1 requires a peer of solid-js@>= 0.26 but none is installed. You must install peer dependencies yourself.
npm WARN vite-template-solid@0.0.0 No repository field.

+ esbuild@0.12.19
+ esbuild-plugin-solid@0.3.1
added 61 packages from 62 contributors and audited 61 packages in 4.124s

3 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
```

* esbuild is already required by Vite, but it makes sense to add it explicitly as a dependency of our project - we are going to use it directly from here
* [esbuild-plugin-solid](https://github.com/Brendan-csel/esbuild-plugin-solid) - a neat plugin that allows us to use Solid's babel preset for compiling the JSX files. The JSX loader provided by esbuild outputs JS files in a format that is not compatible with Solid - so this plugin is currently the only way to have it all run together.

# Build script
Because we are using an esbuild plugin, we have to set up a build script instead of having a long CLI command. We can put the following code to `./build.js`:
```JS
const { build } = require("esbuild");
const { solidPlugin } = require("esbuild-plugin-solid");

build({
  entryPoints: ["src/index.jsx"],
  bundle: true,
  outfile: "www/main.js",
  minify: true,
  loader: {
    ".svg": "dataurl",
  },
  logLevel: "info",
  plugins: [solidPlugin()],
}).catch(() => process.exit(1));
```

The build passes correctly:
```sh
$ node build.js

  www/main.js   12.8kb
  www/main.css   674b 

⚡ Done in 82ms
```

# CSS gotcha
If you visit the output directory, the application is there, but the styling is not working as it should:

![solid-css-glitch.png](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x3bq6s07c0tjba67fg7w.png)

That's because the generated code uses [css-modules](https://github.com/css-modules/css-modules), ie. we have:
```JS
  2 import styles from "./App.module.css";                                         
  3             
  4 function App() {                               
  5   return (                     
  6     <div class={styles.App}>                            
  7       <header class={styles.header}>
```

Which is not yet supported in esbuild - [the ticket](https://github.com/evanw/esbuild/issues/20). The workaround, for now, would be replacing the CSS module with simply scoping the styles with classes.

# Links

The [repository](https://github.com/marcin-wosinek/esbuild-solid) & the [demo page](https://marcin-wosinek.github.io/esbuild-solid/www/) (with broken css).

# Summary
In this article, we have seen how to build a SolidJS application with esbuild. It's working pretty smoothly. The only issue is that we would need to refactor away the CSS modules pattern.