Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough

Svelte TypeScript Tailwind Setup

Parent Feed: 

In this walk through I show my preferred setup for SPAs with Svelte, Typescript and Tailwind.

TL;DR

For the very impatient among us:

npx degit munxar/svelte-template my-svelte-project
cd my-svelte-project
npm i
npm run dev

Enjoy!

Overview

In this article I'll give you some insights how I set up Svelte with TypeScript and style components with Tailwind. There are plenty of articles around, but I found a lot of them overcomplicate things, or don't fit my requirements.

So here are my goals for the setup:

  • stay as close to the default template as possible, to make updates easy
  • production build should only generate css that is used
  • use typescript wherever possible

What Do I Need?

You'll need at least some node version with npm on your machine. At time of writing I have node version 15.6.0 and npm version 7.4.0 installed on my machine.

node -v && npm -v
v15.6.0
7.4.0

Install the Svelte Default Template

To setup Svelte I open a terminal and use the command from the official Svelte homepage. TypeScript support has been already added to this template, so nothing special here.

npx degit sveltejs/template my-svelte-project
# or download and extract 
cd my-svelte-project

Enable TypeScript

# enable typescript support
node scripts/setupTypeScript.js

At this point I try out if the setup works by installing all dependencies and start the development server.

# install npm dependencies
npm i
# run dev server
npm run dev

If everything worked so far, pointing my browser at http://localhost:5000 displays a friendly HELLO WORLD. Let's stop the development server by hitting ctrl-c in the terminal.

Install Tailwind

Back in the Terminal I add Tailwind as described in their documentation.

npm install -D tailwindcss@latest postcss@latest

After this step I generate a default tailwind.config.js file with

npx tailwindcss init

If you prefer a full Tailwind config use the --full argument:
npm tailwindcss init --full
See the Tailwind documentation for more infos about this topic.

Configure Rollup to use Postcss

The default Svelte template uses Rollup as a bundler. When I run the setupTypeScript.js from the first setup step, I get the famous svelte-preprocess plugin already integrated into the rollup setup. The only thing left is that I add the config for postcss as options to the svelte-preprocess plugin. Here are the changes that I make in rollup.config.js:

// rollup.config.js (partial)
...
export default {
  ...
  plugins: [
    svelte({      
       preprocess: sveltePreprocess({
         postcss: {
           plugins: [require("tailwindcss")],
         },
       }),
    }),
    ...
  ],
  ...
};

At this point Rollup should trigger postcss and therefore the Tailwind plugin. To enable it in my application, I still need one important step.

Adding a Tailwind Component to the App

Now it's time to create a Svelte component that contains the postcss to generate all the classes. I call mine Tailwind.svelte but the name doesn't really matter.

// src/Tailwind.svelte

Some things to note here:

  • The component only has a single style element with no markup.
  • The attribute global tells the svelte-preprocess plugin to not scope the css to this component. Remember by default Svelte scopes every css to the component it was declared, in this case I don't want this.
  • The lang="postcss" attribute is telling svelte-preprocess to use postcss for the content. As a goody, some IDE extensions now display the content with the correct syntax highlighting for postcss.

Now use the Tailwind component in src/App.svelte

// src/App.svelte


Hello Tailwind!

Now my browser displays a Tailwind styled div. Very nice!
Let's clean up the public/index.html and remove the global.css link tag and remove the corresponding file from public/global.css I don't use it.





    Svelte app

Let's finish the setup for production builds. Right now it's perfect for development. I can use any Tailwind class and except for the first start of the development server, where all the Tailwind classes get generated, it behaves very snappy on rebuilds.

Production Builds

Purge

When it comes to production builds, right now I have not configured anything so I'll get a bundle.css with all Tailwind classes. I don't want that for a production build, so I modify the tailwind.conf.js to use it's integrated purgecss for that purpose.

// tailwind.config.js
module.exports = {
  purge: ["src/**/*.svelte", "public/index.html"],
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
};

With this modification Tailwind removes all classes that are not used in .svelte files and in the public/index.html html file. I added the public/index.html file because sometimes I add containers or some responsive design utilities directly on the <body> tag. If you don't need this, you can remove the index.html file from the purge list, or add additional files I don't have listed here. For example: if I use some plugins that contain .js, .ts, .html, ... files that use Tailwind classes, I would add them to this purge array too.

There is one little detail about the Tailwind purge: it only is executed if NODE_ENV=production which makes sense. I set this environment directly in my package.json scripts:

// package.json (partial)
{
  ...
  "scripts": {
      "build": "NODE_ENV=production rollup -c",
      ...
  },
  ...
}

With these settings my bundle.css only contains the Tailwind classed I really use, plus the mandatory css reset code that Tailwind provides.

Autoprefixer

One last thing to add for production is vendor prefixes. I usually go with the defaults and just add autoprefixer as postcss plugin. If you need more control, add configuration as you please.

Install autoprefixer with npm:

npm i -D autoprefixer

Add it as postcss plugin in rollup.config.js:

// rollup.config.js (partial)
{
  ...        
  preprocess: sveltePreprocess({
    postcss: {
      plugins: [
        require("tailwindcss"), 
        require("autoprefixer"),
      ],
    },
  })
  ...      
}

That's it.

Features of this Setup

Tailwind Classes

I can apply every Tailwind class on a every html element even in the index.html template.

Tailwind @apply

Additionaly I can use @apply inside a style tag of a Svelte component like this:




This will generate a class scoped to the button of this component. Important part here is the attribute lang="postcss", without this postcss would not process the content of the style tag.

Typesave Components

Let's implement a simple logo component with an attribute name of type string and a default value of "Logo".

  
  
  

{name}

When I use this component the svelte language service of my IDE (visual studio code) will yell at me, if I try to pass something as the name attribute that is not of type string.

  
  
  
  

If you have a IDE that supports the svelte language service, you get all the intellisense stuff you would expect inside your editor. I use Visual Studio Code with the very good svelte.svelte-vscode extension.

Recap

I demonstrated how easy it is to setup a Svelte project with the default template enable TypeScript and add production ready Tailwind support.

I hope you find some helpful information and write some amazing apps!

The source code is available at: https://github.com/munxar/svelte-template

Original Post: 

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web