Setting up Svelte and Tailwind... with minimal extra dependencies
Tags: tailwindcss, svelte, rollup, webdev
Published: 2020-08-19 22:47:52

In this post I'll show how to properly setup *TailwindCss* within a *Svelte* application. I'll show all the required dependencies and changes that should be made while maintaining a minimal number of additional dependencies and script changes.

## TL;DR

In a hurry? Then just checkout [this commit](https://github.com/rodolphocastro/editorconfig-io/commit/bb63ebb36a6ce6e4f757e821afff4aae5dfd8d06) over at GitHub!

{% github rodolphocastro/editorconfig-io no-readme %}

The basics are:

1. Add `tailwindcss` + `postcss-load-config` to your dependencies
2. Init *tailwindcss.config* + *postcss.config*
3. Create a component to host tailwindcss and import that component into the App
4. Change `rollup`'s pipeline to run `postcss`
5. Change `build` command to **set `NODE_ENV` to `production`**

## TailwindCss

### Initial Setup

First and foremost we need to add all the required dependencies to our project. Run `npm install tailwindcss postcss-load-config`.

Those dependencies are needed for setting up tailwind itself and enabling us to **load poscss configuration from a separate file**.

After npm finishes download the dependencies run `npx tailwindcss init` to create the `tailwind.config.js` file.

### Purging unwanted classes

In order for tailwind to know which classes are used we need to point it into the correct files. This is done by editing the `tailwind.config.js` file and telling it to take into account **all `.svelte` and `.html` files we have**.

This is done by the following snippet:

```javascript
module.exports = {
  purge: [
           "./**/*.svelte",  // Look for .svelte files
           "./**/*.html" // Look for .html files
        ],
  theme: {
    extend: {},
  },
  variants: {},
  plugins: [],
}
```

### Setting up PostCSS Config

Now create a new file called `postcss.config.js`. This file will **hold all the PostCSS related configuration**.

In this file you'll point out which plugins the postcss pipeline should use. The following snippet does that for the basic taildwindcss configuration:

```javascript
module.exports = {
        plugins: [
                require("tailwindcss"),
                require("autoprefixer")
        ]
}
```

### Importing Tailwind into the Application

Finally, importing tailwind into our App can be done in many ways, such as:

1. Importing it from a `.css` file
2. Importing it from within a `styles` tag
3. Importing it from the `styles` tag of a specific component

I'll do it as a **separate component** with a `global styles` section. The following snippets creates the component that bootstraps tailwindcss:

```svelte
/* Tailwind.svelte */
<style global>

@tailwind base;
@tailwind components;
@tailwind utilities;

</style>
```

After the component is created all we need to do is import it into our App:

```svelte
<script lang="ts">
        import Tailwindcss from './Tailwind.svelte';
</script>

// Omitting unrelated lines

<Tailwindcss />

```

### Cleaning up

*This is optional, I guess you could keep the old styles if desired.*

Delete the `public/global.css` file and its `<link rel="stylesheet">` tag from `index.html`.

## Enabling Postcss in Svelte's Rollup

Open up `rollup.config.js` and find the *plugins > svelte* section.

Here we'll point out that svelte **needs to run some sort of preprocessing** and we'll tell svelte **which preprocessing should be executed**.

The following snippet shows this allongside the default configuration:

```javascript
export default {
        // Omitted for brevity
        plugins: [
                svelte({
                        // This tells svelte to run some preprocessing
                        preprocess: sveltePreprocess({
                                postcss: true,  // And tells it to specifically run postcss!
                        }),
                        
                        // Omitted for brevity
                }),

                // Omitted for brevity
        ],
        watch: {
                clearScreen: false
        }
};
```

## Ensuring NPM builds for Production

If you run `npm run build` you'll see that the generated `bundle.css` is quite heavy. That's because, by default, **the Svelte's build command doesn't set up NODE_ENV to production!**

In order to fix this all we need to do is use the `--environment` options built into `rollup.js` to set the `NODE_ENV` variable to `production` whenever we run a build script.

To do this simply change the following line within your `packages.json` file:

```json
"name": "your-svelte-app",
  "scripts": {
    "build": "rollup -c --environment NODE_ENV:production",    
  },
}
```

This will ensure every time `npm run build` is called it locally sets the `NODE_ENV` to production. This means **it doesn't impact** your **hot reload experience** at all!

## Possible Impacts

Unlike the other methods I've seen on the internet this one doesn't seem to have any side effects on your build (for production) and hot reload experiences! 😀