skeletonlabs / skeleton

A complete design system and component solution, built on Tailwind.
https://skeleton.dev
MIT License
5.02k stars 321 forks source link

Build error custom class, make sure it is defined within a `@layer` directive. #1371

Closed git-no closed 1 year ago

git-no commented 1 year ago

Current Behavior

Error at build svelte: The bg-surface-50-900-token class does not exist. If bg-surface-50-900-token is a custom class, make sure it is defined within a @layer directive.

By the way, it would be helpful if you would document the default configs. CLI is nice, but not helpful for a existing project. Manual installation and configuration needs proper documentation, not only npm install and tailwind config.

Reproduction / Steps To Reproduce

Latest Svelte, Sveltekit, Tailwind and Skeleton.

Anything else?

Tailwind and Svelte did work before the installation of Skeleton.

Sarenor commented 1 year ago

By the way, it would be helpful if you would document the default configs. CLI is nice, but not helpful for a existing project. Manual installation and configuration needs proper documentation, not only npm install and tailwind config.

What else should we document?

The bg-surface-50-900-token class does not exist. If bg-surface-50-900-token is a custom class, make sure it is defined within a @layer directive.

This alone is not enough information to debug your issue. I assume you're using it in @apply which is currently not possible.

Do you have a link to a repository or a reproduction?

endigo9740 commented 1 year ago

@git-no Echoing what Dom said. We do document the full manual installation process. It's the same steps that the CLI handles for you when using that. Please provide specifics if you feel we've left something out.

It's recommended you use utility classes inline rather than abstracting them to @apply. Currently there's a known issue on Vite/Tailwind's end that prevents this from working. The classes are out of scope when used in this fashion.

We are aware one work around that we may consider in the future. However I recommend caution as this is currently untested on our end:

In short, move your CSS imports from the root layout to the top of your global stylesheet. But again, this is not currently our official recommendation. Use at your own risk.

git-no commented 1 year ago

@endigo9740 @Sarenor Thank you for quick response time.

I tried different approaches. It is a Turborepo and I tried also a very simple app and aligned the settings (tailwind, app.postcss, svelte, layout.svelte etc.) with a Skeleton default installation (separate installation).

Right now the error message is

Internal server error: [postcss] ...turborepo-svelte/node_modules/.pnpm/@skeletonlabs+skeleton@1.2.5/node_modules/@skeletonlabs/skeleton/src/lib/styles/tailwind.css:13:1: The `font-mono` class does not exist. If `font-mono` is a custom class, make sure it is defined within a `@layer` directive.
  Plugin: vite:css
  File: /..turborepo-svelte/node_modules/.pnpm/@skeletonlabs+skeleton@1.2.5/node_modules/@skeletonlabs/skeleton/src/lib/styles/tailwind.css:13:1
  11 |  /* Typographical Settings */
  12 |  @import 'typography.css';
  13 |  
     |   ^
  14 |  /* Imports all Tailwind Elements */
  15 |  @import 'elements.css';

Of course "@tailwindcss/typography" is installed. I keep you posted. Cheers.

endigo9740 commented 1 year ago

@git-no Just FYI we cover monorepo support in our FAQs here: https://www.skeleton.dev/docs/introduction#faqs

image

As far as we're aware, they should work, we just don't specifically spell out configuration changes needed to support them. However I'll ping contributors @niktek and @AdrianGonz97, who are a bit more knowledge on this topic and may be able to provide some guidance.

Of course "@tailwindcss/typography" is installed.

Unfortunately I'm not sure this plugin is relevant to your issue. Per their documentation this provides "Beautiful typographic defaults for HTML you don't control." The font-mono class is a core Tailwind utility class style, so the issue should be unrelated to that plugin.

Btw, do you have a repo or reproduction you could share? It might be valuable in troubleshooting what's going wrong here. Per the error above it's essentially saying it can't find a default Tailwind class. That makes me think there's a config issue here, which may be due to the monorepo setup.

AdrianGonz97 commented 1 year ago

@git-no Typically when I see The bg-surface-50-900-token class does not exist. If bg-surface-50-900-token is a custom class, make sure it is defined within a @layer directive., that points me in the direction that something in your tailwind.config.cjs is misconfigured, especially with how our plugin is being imported. Please be sure that it is similar to the following:

// tailwind.config.cjs

/** @type {import('tailwindcss').Config} */
module.exports = {
    // 1. Apply the dark mode class setting:
    darkMode: 'class',
    content: [
        './src/**/*.{html,js,svelte,ts}',
        // 2. Append the path for the Skeleton NPM package and files:
        require('path').join(require.resolve(
            '@skeletonlabs/skeleton'),
            '../**/*.{html,js,svelte,ts}'
        )
    ],
    theme: {
        extend: {},
    },
    plugins: [
        // 3. Append the Skeleton plugin to the end of this list
        ...require('@skeletonlabs/skeleton/tailwind/skeleton.cjs')()
    ]
}

More specifically, make sure that our plugin is being added properly like so:

plugins: [
    // 3. Append the Skeleton plugin to the end of this list
    ...require('@skeletonlabs/skeleton/tailwind/skeleton.cjs')()
]

The spread operator ... is very important and is often missed. Equally as important is the function invocation () at the end of the require.

If this doesn't solve the issue, then a reproduction is needed.

endigo9740 commented 1 year ago

@AdrianGonz97 thanks, to catch you up, that's relevant to the original issue. I outlined the solution in my first reply above. There's a (I'm assuming) scoping issue when importing our stylesheets in the root layout versus importing them in the global stylesheet. I'm chalking that up to be a weird Vite edge case kind of issue. The former doesn't allow these classes to be ingested via @apply while the latter does. I linked to an issue where we're proposing testing this and moving to make this the default recommendation for our setup configuration.

That aside, not sure if you caught it but @git-no followed up with another error that's coming from a default Tailwind class, font-mono to be specific. They also mentioned using Turborepo, but not sure if that's relevant.

@git-no one more thing that just occurred to me, there's a way you can override default styles in your Tailwind config. It's an easy mistake to make, I've seen a few people do this by mistake. Can you share the contents of your tailwind.config.cjs. I can review and let you know if that's what's going on here.

git-no commented 1 year ago

@endigo9740 @AdrianGonz97 First, thank you for the valuable feedback.

I got it running in a small app. My findings on tailwind.config.cjs is

This does not work:

// tailwind config is required for editor support
// const tailwindConfig = require('tailwind-config/tailwind.config.cjs');
const colors = require('tailwindcss/colors');
// const typography = require('@tailwindcss/typography');
const defaultTheme = require('tailwindcss/defaultTheme');

/** @type {import('tailwindcss').Config} */
const config = {
    // ...tailwindConfig,
    content: [
        './src/**/*.{html,js,svelte,ts}',
        // 2. Append the path for the Skeleton NPM package and files:
        require('path').join(require.resolve('@skeletonlabs/skeleton'), '../**/*.{html,js,svelte,ts}')
    ],
    theme: {
        extend: {
            colors: {
                primary: colors.sky,
                accent: colors.lime

                // accent2: 'var(--color-accent)'
            },
            animation: {
                text12: 'text 12s ease infinite'
            },
            keyframes: {
                text: {
                    '0%, 100%': {
                        'background-size': '200% 200%',
                        'background-position': 'left center'
                    },
                    '50%': {
                        'background-size': '200% 200%',
                        'background-position': 'right center'
                    }
                }
            }
        },
        fontFamily: {
            sans: ['Nunito', ...defaultTheme.fontFamily.sans]
        }
    },
    // plugins: [typography, require('@tailwindcss/forms')]
    plugins: [...require('@skeletonlabs/skeleton/tailwind/skeleton.cjs')()]
};

module.exports = config;

This does work:

// tailwind config is required for editor support
// const tailwindConfig = require('tailwind-config/tailwind.config.cjs');
const colors = require('tailwindcss/colors');
// const typography = require('@tailwindcss/typography');
const defaultTheme = require('tailwindcss/defaultTheme');

/** @type {import('tailwindcss').Config} */
const config = {
    // ...tailwindConfig,
    content: [
        './src/**/*.{html,js,svelte,ts}',
        // 2. Append the path for the Skeleton NPM package and files:
        require('path').join(require.resolve('@skeletonlabs/skeleton'), '../**/*.{html,js,svelte,ts}')
    ],
    // plugins: [typography, require('@tailwindcss/forms')]
    plugins: [...require('@skeletonlabs/skeleton/tailwind/skeleton.cjs')()]
};

module.exports = config;

My conclusion is, the configuration, like keyframes etc. are not allowed. I hope Skeleton has the same approach like Tailwind to keep the at the end generated css at small as possible, with only styles used in the app.

Thank you for your feedback.

endigo9740 commented 1 year ago

@git-no glad to hear you've made progress. Just as I suspected at least part of your issue lies in the config. I've highlighted this below. Note I've abbreviated a bit here:

const config = {
    // You'll want to add this, per our manual install instructions:
    darkMode: 'class',
    // ...
    theme: {
        extend: {
            // ...
        },
        // (this is your issue!)
        fontFamily: {
            sans: ['Nunito', ...defaultTheme.fontFamily.sans]
        }
    },
    // ...
};

So two issues here in fact:

  1. You've missed the darkMode setting we recommend in our manual install instruction.
  2. The bigger issue is you're fontFamily updates fall outside the config.theme.extend section.

Per number two, Tailwind allows you to either extend styles, using config.theme.extend or to completely override and start from the ground up, by placing the changes directly under config.theme. By placing this outside of extend it's opting wipe all default font families and only insert the one you've added (Nunito). This is undesired behavior, as Skeleton relies on many default styles, including built in fonts like font-mono. Hence your error.

I hope Skeleton has the same approach like Tailwind to keep the at the end generated css at small as possible, with only styles used in the app.

Remember that Skeleton is using Tailwind, so yes we do strive for small bundles. That said, Tailwind has a bit of a flaw in that in order to use a third party library like Skeleton, you have to point the content section of your config towards the node_modules directory where these elements/components exist. In our install instructions we include this:

content: [
        './src/**/*.{html,js,svelte,ts}',
        // 2. Append the path for the Skeleton NPM package and files:
        require('path').join(require.resolve('@skeletonlabs/skeleton'), '../**/*.{html,js,svelte,ts}')
],

This appended path does just that, point Tailwind at our source files. Unfortunately Tailwind is not keen enough to know that not all these components, stylesheets, etc are being used in your project. The Tailwind processor just assumes any Tailwind classes visible are being used and must be included. This means your bundle will be a bit larger than if you built everything locally within your project.

However, @AdrianGonz97 is working on Vite-friendly PurgeCSS plugin that will become part of our normal instruction and recommendations going forward, as soon as that's ready. This will prune unused CSS from the final version of the bundle, which should be bring you back to the minimal bundle sizes. So please do take that into consideration for now if your bundle is larger than anticipated for now.

That said, this should have minimal impact on most projects. In fact I'm running several projects in production built with Skeleton, including the Skeleton and Skeleton Labs website, and these run just fine!

endigo9740 commented 1 year ago

Give the original and follow up issues have been resolved, I'm going to go ahead and close out this ticket. Please follow up in new tickets if new issues arise. Thanks!

xeno commented 1 year ago

Although this is closed, I wanted to say I ran into the same issue, also related to my placement of fontFamily. Edit: I forgot you can either provide fontFamily directly as a child of theme, or within extend.