How to configure esbuild to use css-modules and sass/scss for when bundling?
Asked Answered
E

1

8

Background:

I am attempting to extend esbuild's CSS support to include CSS Modules and Sass/Scss. I have therefore been making use of custom made plugins--utilising the esbuild plugin API. First, I tried:

  • esbuild-sass-plugin: As the name suggests, this plugin took care of .scss interpretation/transpilation. However, it failed to accommodate for CSS Modules (despite advertising its extensibility).

In accommodating for the missing support for CSS Modules, I added another esbuild plugin:

Relevant Technologies

  • Node: 14.
  • esbuild: ^0.11.11.
  • esbuild-css-modules-plugin: ^2.3.2.
  • esbuild-sass-plugin: ^2.2.6.
  • sass: ^1.53.0.
  • typescript: ^4.2.3.

Advice/Help That I'd Consider GREAT:

  • How would I best debug why these plugins are failing to properly provide CSS Module support?
  • The culprit of what I am overlooking here and insights into what lack of understanding is causing this blindspot.

Relevant Code Snippets:

package.json - relevant build script

"build:dev": "node build.js esbuild-browser:dev"

build.js (entrypoint for esbuild)

const sassPlugin = require("esbuild-sass-plugin").default;
const cssModulesPlugin = require("esbuild-css-modules-plugin");

let options = {
  bundle: true,
  minify: true,
  minifyWhitespace: true,
  sourcemap: true,
  target: "es2018",
};

let builds = {
  "esbuild-browser": () => ({
    ...options,
    platform: "browser",
    format: "esm",
    sourcemap: "external",
    outfile: "build/esbuild/browser.js",
    entryPoints: ["src/browser.ts"],
    plugins: [sassPlugin()],
  }),
  "esbuild-browser:dev": () => ({
    ...options,
    watch: true,
    platform: "browser",
    format: "esm",
    outfile: "build/esbuild/browser.js",
    entryPoints: ["src/browser.ts"],
    plugins: [sassPlugin(), cssModulesPlugin()],
  }),
};

require("esbuild")
  .build(builds[process.argv[2]]())
  .catch(() => process.exit(1));

ScrawlComponent.tsx (note the className for <span/>)

import React from "react";
import styles from "./styles.scss";

type Props = {
  content: string;
};

const ScrawlComponent = (props: Props) => {
  const { content } = props;

  return (
    <span
      id="animation_link_target_text"
      className={styles.animation_link_target_text} 
    >
      {content}
    </span>
  );
};

export default ScrawlComponent;

Output HTML (note ABSENT className for <span/>)

<html>
<head></head>
  <body>
    <div id="root"><span id="animation_link_target_text"></span> </div>
    <script src="./esbuild/browser.js"></script>
    <link rel="stylesheet" type="text/css" href="./esbuild/browser.css">
</body>
</html>
Etana answered 17/7, 2022 at 4:32 Comment(1)
Have you tried debugging esbuild path resolution with the log level: debug/verbose?Galbanum
C
0

CSS Modules support requires your css files to be named with the suffix ".module.css" or ".module.scss" in your case.

See esbuild docs for CSS Modules

To use CSS Modules with .scss support, you will need use esbuild-scss-modules-plugin instead of esbuild-css-modules-plugin.

Connive answered 16/9, 2023 at 16:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.