npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

postcss-modules-component-plugin

v0.0.4

Published

A Webpack plugin to provide connectivity between `postcss-modules` JSON output and React (or other) component classNames

Readme

This module provides linkage between postcss-modules output and React (or other view component) import / require statements.

You will find this very useful if you wish to create component-oriented style modules that you can import directly from your JavaScript modules; and also easily share code with external libraries.

But be warned, this module is a dirty hack around various limitations in css-loader, postcss-modules, postcss-import and Webpack, and will probably go away once one of these tools / ecosystems evolves to a sufficient featureset. It was created out of frustration after many hours of head-banging — so if you're reading this thinking, "this sounds dumb...", then please open an issue explaining to me how to get these things working the right way.

What it does

The current problem with "the done thing" in Webpack-land is that css-loader does its module parsing at the end of the compilation process, leaving it unable (AFAIK) to make decisions about source files from their original locations. This is very annoying when you want to set default CSS scopes based on file location. Ideally you want a dependency graph that says:

MyComponent.js ──┐
   ┌─────────────┘
   └──> ./MyComponent.scss (LOCAL) ──┐
           ┌─────────────────────────┘
           │
           ├──> ${root}/src/framework.scss (LOCAL) ──┐
           │       ┌─────────────────────────────────┘
           │       │
           │       ├──> ${root}/node_modules/some-lib/_variables.scss (GLOBAL)
           │       │
           │       ├──> ./_variables.scss (LOCAL)
           │       │
           │       └──> ${root}/node_modules/some-lib/_mixins.scss (GLOBAL)
           │
           │
           └──> ${root}/node_modules/some-lib/ComponentBase.scss (GLOBAL)

This module allows you to achieve this, so that a class of .currentElement in MyComponent.scss will compile to something like .MyComponent🇮🇳_currentElement_7KOWY while in ComponentBase.scss it will come out as simply .currentElement. All in a way you can access directly from your JavaScript view components.

Caveats

  • If local components use the same class names as global components which have been previously loaded, these will come out global.
  • Stylesheets which load other local styles will end up with the inner class names localised twice.

Usage

Simply make the following additions to your webpack config. Note the configuration is setup for use with an .scss file extension but you can import css, less, pcss or whatever you want so long as you have the rest of your postcss plugins configured to deal with them.

const loaderUtils = require('loader-utils');
const postCSSModuleComponents = require('postcss-modules-component-plugin');

// optional:

postCSSModuleComponents.setLocalModuleNameFormat('[name][emoji]_[localName]_[hash:base64:5]');
postCSSModuleComponents.setGlobalModulesWhitelist([
  /\/node_modules\//,               // <-- this is the default
  /src\/views\/globalView\.scss$/,
]);

//...

const moduleLoaderPlugin = postcssModules({
  generateScopedName: postCSSModuleComponents.scopedName,
  getJSON: postCSSModuleComponents.writer,
});

//...

module.exports = {
    
  //...   

  module: {
    loaders: [

      //...

      {
        test: /\.(scss)$/,  // or whichever
        exclude: [/\/node_modules/],
        loaders: [
          { loader: 'style-loader' },
          { loader: postCSSModuleComponents.loader() },
          { loader: 'css-loader', query: { sourceMap: true, importLoaders: 1 } },
          { loader: 'postcss-loader' },
        ],
      },

      //...

    ]
  },

  //...

  postcss: function(webpack) {
    return {
      plugins: [
        // :IMPORTANT: must be first
        partialImport({
          extension: 'scss',
          addDependencyTo: webpack,
          plugins: [moduleLoaderPlugin],
        }),
        moduleLoaderPlugin,

        //...

      ],
    };
  },

  //...

};

Note that moduleLoaderPlugin appears TWICE in the postcss plugin definition. This is very important- the plugin needs to run over modules before flattening partials, as well as over the final compiled module before continuing.

How it works

If you study the above diagram you'll notice that MyComponent.scss has to render and return the classes it defines as local by default, and those ComponentBase.scss defines as global. The only way this can be done is during the PostCSS compilation phase, specifically by postcss-modules within postcss-import's plugins within PostCSS. Phrew. And then we need another postcss-modules pass on top of all of that to send out the class names differently, because in the toplevel case we want to emit a mix of local and global classes.

In the plugin, we:

  1. Bind to the getJSON feature of postcss-modules to retain the parsed classname output for each module.
  2. Intervene before postcss-import picks up each file and mark all encountered class names as global if the filename matches one of our global whitelist regexes. If the filename doesn't define an automatic global context we return a localised class name.
  3. Intervene again after postcss-import has merged all the @imported files together and, using the flags we picked up in step 2, emit either global or local classnames accordingly.
  4. Bind to the webpack loader stack after css-loader has generated its code in order to inject the cached JSON from step 1 into the final payload (which will be empty, since css-loader isn't running in module mode.

Todo

  • Attempts with multiple instances of postcss-modules plugin resulted in issues, if we can revisit with two separate instances may be able to solve the "local classnames can be shadowed by globals" problem.

Author

Made with love at everledger.io

(...and OK yes, some frustration :p)

License

MIT