Tips for sharing a React component with CSS modules that is compatible with both ES Modules and CommonJs for CSS modules integration

Some frameworks, like Gatsby version 3 and above, import CSS modules as ES modules by default:

import { class1, class2 } from 'styles.modules.css'
// or
import * as styles from 'styles.modules.css'

However, other projects, such as Create React App, still use the default export method:

import styles from 'styles.modules.css'

Is it possible to publish a react-component (that internally uses CSS modules) in a way that allows it to be imported and used in both scenarios without having to extract the CSS?

Answer №1

I've discovered a clever workaround that involves generating hashed classes for CSS modules and extracting the stylesheet. Instead of importing the regular CSS module stylesheet, I import the one with hashed classes. Most bundlers capable of importing CSS modules should be able to handle the extracted CSS file.

To achieve this, I utilize babel-plugin-css-modules-transform with the following setup:

  …
  "plugins": [
    [
      "css-modules-transform",
      {
        "extractCss": {
          "dir": "./lib/",
          "relativeRoot": "./src/",
          "filename": "[path]/[name].compiled.css"
        },
        "keepImport": true,
        "importPathFormatter": "./importPathFormatter"
      }
    ]
  ]
  …

The keepImport setting retains the import statement but changes it from something like

import * as styles from 'styles.module.css'
to import 'styles.module.css'. I combine this option with an undocumented feature called importPathFormatter to import the transformed CSS. Any CSS preprocessing such as postCSS is deferred to the consuming application.

This is how the contents of ./importPathFormatter.js look:

module.exports = path => path.replace(/\.css$/, '.compiled.css');

In the future, I plan to transition my projects to vanilla extract and leverage rollup/vite for bundling. However, for now, this solution serves me well.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Opera browser fails to render CSS3 box shadow effect

My menu features CSS3 effects on hover and active states, giving it a unique appearance. Below is the CSS3 styling I have implemented: #Menu a:active, #Menu a.active:before,#Menu a:hover:before { Content: ' '; position:absolute; z-i ...

Using jQuery to swap an image with a div element and then using the image as the

I have a collection of images in a div, like so: <div class="image-container"> <img width="174" height="174" src="http://mysite.com/images/portfolio/p1.jpg" class="image-style" typeof="foaf:Image"> <img width="174" height="174" src= ...

What is the best way to attach a button to a mat-drawer?

I am facing an issue with aligning a button to a mat drawer located to the right of the screen to ensure a clear overall design. Check out this example How can I achieve this alignment? My current approach involves placing the button inside the drawer an ...

What are the steps to create a ListView in a ChatApp for organizing and viewing all conversations?

In developing my chat application, I am considering using a List to organize all the chats. Since my app is integrated with Firebase, I am faced with the decision of whether to utilize a FlatList and store all data locally or in a Firebase database. What ...

Postgres Array intersection: finding elements common to two arrays

I'm currently developing a search function based on tags, within a table structure like this CREATE TABLE permission ( id serial primary key, tags varchar(255)[], ); After adding a row with the tags "artist" and "default," I aim ...

Achieving consistent spacing between elements within a column in Bootstrap 5

Picture a bootstrap column filled with various elements such as divs, paragraphs, and links. How can I evenly space these elements inside the column without using margins or padding? I am looking for an automatic way for the elements to be spaced equally a ...

JavaScript popup is no more visible on the webpage

Recently, I implemented a pop-up on my website that used cookies to prevent it from appearing every time a user visited a page. However, after making this change, the pop-up stopped showing altogether. Despite my best efforts in testing, researching, and s ...

Is it possible for Next.js to send a 304 Not Modified status for a server-side rendered page?

Is it known if Next.js is capable of returning a 304 Not Modified HTTP status for SSG pages, and whether it can do so for real-time rendered pages? On the flip side, does Next.js include an ETag header when serving an SSR page upon initial request? Appre ...

Tips for preserving dynamically generated HTML through Javascript during page reload

I have a straightforward question, but I haven't been able to find a suitable answer. Here's my situation: On my HTML page, I have a form. Using jQuery and AJAX, I submit the form and then use some JavaScript code to change the content of a spec ...

Innovative resources for designing an operational online shopping cart

I'm in the process of developing an e-commerce platform with Reactjs for the frontend and Nodejs (along with Express) for the backend. My current focus is on creating a seamless shopping cart experience tied to user accounts, where users can navigate ...

Is it possible to test a Node CLI tool that is able to read from standard input with

I'm looking for a way to test and verify the different behaviors of stdin.isTTY in my Node CLI tool implementation. In my Node CLI tool, data can be passed either through the terminal or as command line arguments: cli.js #!/usr/bin/env node const ...

Guide on adding a Link component from react-router-dom to a Material-UI table

In my current project, I am facing an issue where I need to place a Link inside a table from Material UI. However, I am encountering two errors: "<td> cannot appear as a child of <a>" and "<a> cannot appear as a child of <tr>". Whil ...

Issues with CORS on PUT and POST requests in AngularJS and Node.js are preventing successful communication between the two

I'm encountering a CORS issue with my application. My tech stack consists of Node.js using Express 4 and AngularJS Despite attempting various solutions, I continue to receive the following error for all POST/PUT requests: No 'Access-Control-Al ...

What is the method for obtaining multiple indices on an Array?

Attempting to find multiple index positions in an Array for a Boolean value. Experimenting with while and for loops to iterate through more than one index position without success so far. Below is the code snippet: let jo = [1,2,3,4,5] let ji = [1,2,3] ...

Deciphering JSON data in an Express.js application

In a Node.js/Express.js application, an API call is made to another server which responds with JSON data. However, the received JSON response is not being properly parsed into new variables. What specific modifications should be applied to the code below i ...

Having trouble displaying the time in the middle square when pressing TouchableOpacity in React Native?

Having trouble pressing the TouchableOpacity button as it's not responding, and even after pressing it, I need to access the time picker to select a specific time to display inside the square view in the center. Any suggestions on how to resolve this ...

Encountered a problem while trying to inherit from the BrowserWindow class in

I utilized the https://github.com/SimulatedGREG/electron-vue template to craft a vue electron blueprint. Alongside the primary process index.js, I fashioned a file named MainWindow.js which holds the subsequent code: import { BrowserWindow } from 'el ...

Center align Bootstrap 4 dropdown menu

I am attempting to center align my dropdown menu using Bootstrap 4. Following the given example: [ This is the result I am achieving: [ This is the code I have implemented: <div class="container"> <div class="row"> <div class=" ...

Using jQuery to Retrieve Check Box Labels and Populate Them into Textboxes

I would like to display the name of the selected checkbox label in a textbox. If multiple checkboxes are selected, I want their labels to be separated by commas and displayed in the textbox. Please excuse my poor English. $(document).ready(function() { ...

What is the best way to design a regular expression that will only match up to 12 numbers?

Is there a way to construct a regular expression that will validate a string containing up to 12 digits only? Thank you! ...