DEV Community

Gyula Kerezsi
Gyula Kerezsi

Posted on • Originally published at gyulakerezsi.ro

Global scss in SvelteKit

TL;DR

Run: npm i -D nodemon concurrently

Add the following npm scripts

"dev:full": "concurrently --kill-others \"npm run scss:dev\" \"npm run dev:nodemon\"",
"dev:nodemon": "nodemon --exec \"npm run dev\"",
"scss": "sass src/scss/:static/style/",
"scss:dev": "sass -w src/scss/:static/style/"
Enter fullscreen mode Exit fullscreen mode

Add npm run scss && before the build, package, preview and
prepare scripts

"build": "npm run scss && svelte-kit build",
"package": "npm run scss && svelte-kit package",
"preview": "npm run scss && svelte-kit preview",
"prepare": "npm run scss && svelte-kit sync",
Enter fullscreen mode Exit fullscreen mode

The setup

So I started a little project (hopefully I will write about it soon) and I
tought I would write the frontend in svelte

Then I remembered that SvelteKit was a thing, and I meant to learn it as well,
so I started a new project with it.

I was pleasantly surprised when the new project setup asked about both
Typescript and Sass (scss), I like both, but when I looked into changing the
full body style I was a bit disappointed

No support for directly compiling an scss file for the body, to include in the
app.html file

Well, let's see what options we got

The first thing that jumps out is perhaps the best option

SvelteKit's preprocessor for styles has a special :global selector, so you
could have the following block in your main __layout.svelte

<style lang="scss">
  :global {
    @import '<path to global scss>';
  }
</style>
Enter fullscreen mode Exit fullscreen mode

Which works just fine, but it generates a lot of warnings in other components,
paths, that don't have any element matching some selector in your global file.

Annoying.

let's try something else

If you run sass -w <path to global>:<path to static> to have Sass compile your
stylesheet, adding <link rel="stylesheet" href="%sveltekit.assets%/global.css">
to your app.html

It works fine...

When you start svelte-kit dev

If you modify your file afterwards, it won't change even if you reload your page.

It's static why should it?

Enter nodemon

nodemon is a wonderful little node package/application, it watches your files,
if something changes it stops and restarts your process(es)

Which is nice, you can tell it to run the npm cript for svelte-kit and watch
your global file

So let's install nodemon with npm i -D nodemon, and to keep the npm script
short let's add a nodemon.json file

{
  "delay": 0.25,
  "watch": [
    "<path to static file>"
  ]
}
Enter fullscreen mode Exit fullscreen mode

This will tell nodemon to watch the file for changes, and to wait for 250ms to
restart (might not be needed, but it helps with giving sass time to settle files)

Let's add a new npm script:

"dev:nodemon": "nodemon --exec \"npm run dev\""
Enter fullscreen mode Exit fullscreen mode

I like leaving the original alone, as hopefully global styles will rarely change.

The only thing missing is a single command that will start both the Sass
compilation. Thankfully someone made concurrently

Adding concurrently

concurrently is a node package made for running things side by side...
conurrently

It's cross platform, so it will run on pretty much all development environments.
It has the --kill-others option which will make sure that everything dies
together

You can install it by running npm i -D concurrently

We're almost there, last thing we need to do is add a few more npm scripts

"dev:full": "concurrently --kill-others \"npm run scss:dev\" \"npm run dev:nodemon\"",
"scss": "sass <path to global>:<path to static>",
"scss:dev": "sass -w <path to global>:<path to static>"
Enter fullscreen mode Exit fullscreen mode

Now running npm run dev:full will start the Sass compiler in watch mode

One more preventative measure

Just to make sure that you always have the global css compiled when packaging,
we'll modify a few of the default SvelteKit npm scripts

Let's add npm run scss && before the build, package, preview and
prepare scripts

"build": "npm run scss && svelte-kit build",
"package": "npm run scss && svelte-kit package",
"preview": "npm run scss && svelte-kit preview",
"prepare": "npm run scss && svelte-kit sync"
Enter fullscreen mode Exit fullscreen mode

And that's it, now you can run npm run dev:full to get your global css
recompiling. No hot reload I'm afraid, but hitting refresh is not that hard.

PS.: should I add the generated css to .gitignore

Personally i'm not going to, it's really not that big in the first place, and
it's not likely to change a lot, at least in my setup, where I mostly just set a
few css variables

On the other hand, you are more likely to notice it missing, than seeing that
some change hasn't propagared into it.

This one is up to you

Top comments (0)