6

In my SvelteKit project I am using SCSS and in order to include some mixins that are used throughout the project, I switched from vitePreprocess to svelte-preprocess and prepended them with scss.prependData. Now my config looks like this:

const config = {
  preprocess: preprocess({
    scss: {
      prependData: `@import './src/styles/prepend.scss';`,
    },
  }),
  // ..
  // Other options not relevant to the question
}

Since the official SvelteKit docs suggest that vitePreprocess might be faster, I was wondering if I can set up global mixins with it.

I tried importing prepend.scss in my root +layout.svelte file but now I'm getting an Undefined mixin error.

Can I use mixins with vitePreprocess or is svelte-preprocess the only way to achieve this at the moment?

Yulian
  • 6,262
  • 10
  • 65
  • 92
  • Hi, i also have the same issue, i still don't no how to use mixin and global files with sveltekit. I migrate my SPA from Svelte to SvelteKit, i also had to change the preprocess :( – nevradub Feb 22 '23 at 21:50
  • It looks like at the moment, you can't. vitePreprocess does not support global styles. I had to revert to svelte-preprocess. – Sebastian Feb 25 '23 at 21:23

3 Answers3

5

As @SlavenIvanov's answer suggests, you have to import the variables and mixins from vite.config.js.


Here is a complete example of Sass configuration on a new SvelteKit project:
  1. Create the project (npm create svelte@latest my-app)
  2. Add vitePreprocess in svelte.config.js (see SvelteKit Preprocessors)
  3. Add Sass support with npm install -D sass
  4. Import variables and mixins from vite.config.js (see Vite documentation)
  5. Import global styles from main layout (like described here)
// svelte.config.js
import { vitePreprocess } from '@sveltejs/kit/vite';
 
export default {
  preprocess: [vitePreprocess()]
};
// vite.config.js
export default defineConfig({
  css: {
    preprocessorOptions: {
      sass: {
        additionalData: `
          @import '$lib/sass/variables'
          @import '$lib/sass/mixins'
        `,
      }
    },
  }
});
// src/lib/sass/_variables.sass
$red: #d34a
$green: #9c3
$blue: #0bc
// src/lib/sass/_mixins.sass
=tablet
  @media (min-width: 768px)
    @content

=desktop
  @media (min-width: 1024px)
    @content
// src/lib/sass/global.sass

html
  background: $red

  +tablet
    background: $blue
<!-- src/routes/+layout.svelte -->
<script>
  import '$lib/sass/global.sass'
</script>

<slot />
<!-- src/routes/+page.svelte -->
<h1>Hello world</h1>

<style lang="sass">
  h1
    color: $green

    +desktop
      color: $red
</style>

Notes:

  1. I don't know why but you have to add an extra line break at the beginning of the global.sass file (otherwise it crashes)
  2. You can disable WebStorm warnings such as Element is resolved only by name... by unchecking the box in Settings... "Editor / Inspections / Sass/SCSS / Missing import"
Cyril
  • 171
  • 1
  • 7
  • Hi, I'm trying to use your solution (with scss but I guess it's the same process) but I'm stuck. In your 4. the link you provide ask to make the import in a JS file and not in +layout.svelte. Is it supposed to be the same ? Also, I don't understand how _mixins and _variables can be imported if you don't link them somewhere. Maybe the "_" prefix ? I'm starting my first sveltekit project and like you I Have been wandering around for a solution that you seem confident with. Thank you for your help ! – 16ar Mar 13 '23 at 21:34
2

Some good answers here, but there still seems to be some confusions in the answers, let me clear them up.

You need to update two files, svelte.config.js and vite.config.js to get this working.

Update svelte.config.js

import adapter from '@sveltejs/adapter-auto';
import { vitePreprocess } from '@sveltejs/kit/vite'; // Add this


const config = {
    kit: {
        adapter: adapter()
    },
    preprocess: [vitePreprocess()] // And this
};

export default config;

Update vite.config.js

This is the confusing part, since this config will vary from person to person and what you are trying to do.

  • You must be using either .scss or .sass, figure out which one you are using and don't mix them in the config.
  • Figure out the path of your .scss or .sass files that you want to include throughout the project. In this case, it's /src/lib/scss/, for you it could be /src/ or /src/scss/
  • With this config vite will include all the sass/scss and if some of them are actual styles and not just variables, those styles will be duplicated in the final bundle. For the same reason, we will use @use and not @import.
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';

export default defineConfig({
    plugins: [sveltekit()],
    // Add this
    css: {
        preprocessorOptions: {
            // if using SCSS
            scss: {                                 
                additionalData: `
                @use '$lib/scss/variables' as *;    
                @use '$lib/scss/mixins' as *;
            `,
            },
            // if using SASS
            sass: {                                 
                additionalData: `
                @use '$lib/sass/variables' as *;    
                @use '$lib/sass/mixins' as *;
            `,
            },
        },
    }
});

Usage

// src/lib/scss/_variables.scss

$color: red;

// src/lib/scss/_mixins.scss

@mixin big-font {
    font-size: 32px;
    font-weight: 900;
}

<!-- src/routes/+page.svelte -->

...

<style lang="scss">
    h2 {
        color: $color;
        @include big-font;
    }
</style>

To explicitly use variables and mixins you can give them an alias

scss: {
    additionalData: `
    @use '$lib/scss/variables' as vr;   
    @use '$lib/scss/mixins' as mx;
    `,
},
<!-- src/routes/+page.svelte -->

...

<style lang="scss">
    h2 {
        color: vr.$color;
        @include mx.big-font;
    }
</style>

dexbyte
  • 65
  • 11
  • Thank you mate! A simple solution that works flawlessly with the current version of SvelteKit (as of 16th Aug 23). Cheers and take care o/ – SMEETT Aug 16 '23 at 21:30
0

You need to add your prependData to vite.config.ts as explained here.

It should look like this:

// vite.config.ts

const config: UserConfig = {
    plugins: [sveltekit()],
    test: {
        include: ['src/**/*.{test,spec}.{js,ts}']
    },
//  This is the magic 
    css: {
        preprocessorOptions: {
            scss: {
                additionalData: `@import './src/styles/prepend.scss';`
            }
        }
    }
}
SlavenIvanov
  • 57
  • 1
  • 9