Include SCSS files in TSUP build of Lit Library

2 min read 04-10-2024
Include SCSS files in TSUP build of Lit Library


Including SCSS Files in Your TSUP Build for a Lit Library

Building a custom web component library with Lit is a great way to create reusable UI elements that enhance your web development workflow. But what about styling these components? Lit provides a convenient way to style your components using CSS, but how do you incorporate SCSS (SASS) for more complex styling needs within a TSUP build environment? Let's explore a practical solution.

The Challenge: Bridging SCSS and TSUP

Imagine you're building a Lit library with components that require advanced styling options like nested selectors, variables, and mixins. You choose SCSS for its flexibility and power, but how do you integrate it with your TSUP build process? TSUP is primarily designed for JavaScript and TypeScript, so some configuration is needed to include your SCSS files.

Setting the Stage: Sample Code and Configuration

Let's assume you have a simple Lit component my-component.ts:

import { LitElement, html, css } from 'lit';
import { customElement, property } from 'lit/decorators.js';

@customElement('my-component')
export class MyComponent extends LitElement {
  @property({ type: String }) name = 'World';

  static styles = css`
    .container {
      color: blue;
    }
  `;

  render() {
    return html`<div class="container">Hello, ${this.name}!</div>`;
  }
}

Now, let's add SCSS styles to this component in a file my-component.scss:

.container {
  color: $primary-color;
  background-color: $secondary-color;
  font-size: 1.2em;
}

$primary-color: #333;
$secondary-color: #f0f0f0;

To incorporate this SCSS file into the TSUP build, you'll need to:

  1. Install necessary packages:

    npm install sass @types/sass
    
  2. Configure TSUP: Create a tsup.config.ts file in your project:

    import { defineConfig } from 'tsup';
    
    export default defineConfig({
      entry: ['./src/index.ts'],
      outDir: 'dist',
      format: ['esm'],
      sourcemap: true,
      plugins: [
        {
          name: 'sass',
          buildStart(ctx) {
            // Register the sass plugin with tsup
            ctx.on('build', async (outputOptions, inputOptions) => {
              const sass = require('sass');
              const { path } = inputOptions;
    
              for (const file of outputOptions.entryPoints) {
                if (file.endsWith('.scss')) {
                  const result = sass.renderSync({
                    file,
                    outFile: file.replace('.scss', '.css'),
                    sourceMap: true,
                  });
    
                  await ctx.writeFile(
                    file.replace('.scss', '.css'),
                    result.css.toString()
                  );
                }
              }
            });
          },
        },
      ],
    });
    
  3. Adapt Your Component: Import and use the generated CSS file in your Lit component:

    import { LitElement, html, css } from 'lit';
    import { customElement, property } from 'lit/decorators.js';
    import './my-component.scss'; // Import generated CSS file
    
    @customElement('my-component')
    export class MyComponent extends LitElement {
      // ...
    }
    

Breaking It Down: Explanation and Insights

  • TSUP Plugin: We define a custom TSUP plugin that utilizes the sass library to process your SCSS files during the build process. This plugin listens for build events and, upon encountering a .scss file, compiles it to a corresponding .css file.
  • CSS Import: The compiled CSS file is then imported into your component, allowing you to apply your SCSS styles within your Lit element.

Benefits and Considerations

  • Maintainability: Using SCSS allows you to structure your styles logically and maintain clean, organized code.
  • Reusability: Variables, mixins, and nested selectors make it easier to reuse styles throughout your library.
  • Scalability: SCSS helps manage complexity as your library grows, making it easier to handle larger projects.

However, keep in mind that this approach requires you to manually import the generated CSS file into your components. For larger projects, consider utilizing a CSS bundler or exploring alternative SCSS integration approaches.

Conclusion: SCSS Power for Your Lit Library

By incorporating this plugin and adjusting your Lit components, you can seamlessly integrate SCSS styling into your TSUP build process. This opens the door to more robust and expressive styling solutions within your Lit library, empowering you to create polished, visually appealing web components.