Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
@dr.pogodin/babel-plugin-react-css-modules
Advanced tools
Transforms styleName to className using compile time CSS module resolution.
This Babel plugin for React transforms styleName
attribute of
JSX components into className
using compile-time CSS Modules resolution,
allowing for a cleaner use of CSS Modules in React.
Assuming style.css
in the following examples is compiled as CSS Module.
Without this plugin
import S from './styles.css';
export default function Component() {
return (
<div className={S.container}>
<h1 className={S.title}>Example</div>
<p className={`${S.text} ${S.special}`}>
This is just a simple example.
</p>
</div>
);
}
With this plugin
import './styles.css';
export default function Component() {
return (
<div styleName="container">
<h1 styleName="title">Example</div>
<p styleName="text">Sample text paragraph.</p>
<p styleName="text special">
Sample text paragraph with special style.
</p>
</div>
);
}
With this plugin and multiple stylesheets
import S1 from './styles-01.css';
import S2 from './styles-02.css';
export default function Component() {
return (
<div styleName="S1.container">
<h1 styleName="S1.title">Example</div>
<p styleName="S1.text">Sample text paragraph.</p>
<p styleName="S1.text S2.special">
Sample text paragraph with special style.
</p>
</div>
);
}
In this example the plugin understands S1.
and S2.
prefixes as import
names of stylesheets from where each style should be taken.
With autoResolveMultipleImports
option enabled (by default), the plugin will
resolve the correct stylesheet automatically (if possible), and the example will
work as this, assuming each style is defined only in one of these CSS files:
import './styles-01.css';
import './styles-02.css';
export default function Component() {
return (
<div styleName="container">
<h1 styleName="title">Example</div>
<p styleName="text">Sample text paragraph.</p>
<p styleName="text special">
Sample text paragraph with special style.
</p>
</div>
);
}
With this plugin and runtime resolution
import './styles-01.css';
import './styles-02.css';
export default function Component({ special }) {
let textStyle = 'text';
if (special) textStyle += ' special';
return (
<div styleName="container">
<h1 styleName="title">Example</div>
<p styleName={textStyle}>Sample text paragraph.</p>
<p styleName={textStyle}>
Sample text paragraph with special style.
</p>
</div>
);
}
In the case when the exact style value is not known at the compile time, like in
this example, the plugin will inject necessary code to correctly resolve the
styleName
at runtime (which is somewhat less performant, but otherwise works
fine).
The core CSS Modules functionality should be enabled and configured elsewhere in your React project:
modules
option of css-loader
.Install this plugin as a direct dependency (in edge-cases not allowing for
a compile-time styleName
resolution, the plugin falls back to the runtime
resolution).
npm install --save @dr.pogodin/babel-plugin-react-css-modules
Install Webpack at least as a dev dependency:
npm install --save-dev webpack
Add the plugin to Babel configuration:
{
"plugins": [
["@dr.pogodin/react-css-modules", {
// The default localIdentName in "css-loader" is "[hash:base64]",
// it is highly-recommended to explicitly specify the same value
// both here, and in "css-loader" options, including the hash length
// (the last digit in the template below).
"generateScopedName": "[hash:base64:6]"
// See below for all valid options.
}]
]
}
The generateScopedName
option value MUST match localIdentName
option of
css-loader
to ensure both Webpack and this plugin generate matching class
names. The same goes for other options impacting class names
(e.g. the default length of hashes generated by Webpack, which is used
if you don't specify the hash length explicitly in localIdentName
hash
placeholders), and also the actuals version of this plugin and css-loader
(see css-loader
compatibility).
Optional. css-loader
is known for eventual minor updates in their default
class name generation logic that require counterpart upgrades of this plugin
to keep it compatible.
They denied
to expose the default class name generator for re-used by 3rd party libraries,
and suggested to rely on
getLocalIdent
option if unwanted class name changes due to css-loader
updates are
a problem for a particular project.
To alleviate this issue, this plugin provides stable default implementation
for getLocalIdent
function (taken from a selected earlier version of
css-loader
). Consider to use it:
Within Webpack Config
const { getLocalIdent } = require('@dr.pogodin/babel-plugin-react-css-modules/utils');
const cssLoaderOptions = {
modules: {
getLocalIdent,
localIdentName: '[path]___[name]__[local]___[hash:base64:6]'
}
};
Within Babel Config
const { generateScopedNameFactory } = require('@dr.pogodin/babel-plugin-react-css-modules/utils');
module.exports = {
plugins: [
["@dr.pogodin/react-css-modules", {
generateScopedName:
// The classname template MUST match "localIdentName" option value
// you passed to "css-loader".
generateScopedNameFactory("[path]___[name]__[local]___[hash:base64:6]"),
}]
]
};
In addition to the standard class name template placeholders mentioned in
css-loader
documentation
the version of getLocalIdent()
and generateScopedName()
provided by this
plugin also support [package]
placeholder. If used, it looks up from CSS
file for the closest package.json
file, takes the package name from it,
and inserts it into the class name (this is useful for CSS bundling for
libraries).
If you'd like to get this working in React Native, you're going to have to allow
custom import extensions, via a rn-cli.config.js
file:
module.exports = {
getAssetExts() {
return ["scss"];
}
}
Remember, also, that the bundler caches things like plugins and presets. If you
want to change your .babelrc
(to add this plugin) then you'll want to add the
--reset-cache
flag to the end of the package command.
These are valid plugin options. All are optional, but the overall configuration
should be compatible with that of css-loader
, thus defaults may not work for
you.
context
- string - Must match webpack
context
configuration. css-loader
inherits context
values from webpack. Other CSS
module implementations might use different context resolution logic.
Defaults process.cwd()
.exclude
- string - A RegExp that will exclude otherwise included files
e.g., to exclude all styles from node_modules: exclude: 'node_modules'
.filetypes
- Configurate syntax loaders like sugarss, LESS and SCSS,
and extra plugins for them.generateScopedName
- function | string - Allows to customize the exact
styleName
to className
conversion algorithm. For details see
Generating scoped names.
Defaults [path]___[name]__[local]___[hash:base64:5]
.removeImport
- boolean - Remove the matching style import.
This option is used to enable server-side rendering. Defaults false.webpackHotModuleReloading
- boolean - Enables hot reloading of CSS
in webpack. Defaults false.handleMissingStyleName
- string - Determines what should be done for
undefined CSS modules (using a styleName
for which there is no CSS module
defined). Valid values: "throw"
, "warn"
, "ignore"
. Setting this option
to "ignore"
is equivalent to setting errorWhenNotFound: false
in
react-css-modules. Defaults "throw"
.attributeNames
- Custom Attribute Mappingskip
- boolean - Whether to apply plugin if no matching attributeNames
found in the file. Defaults false.autoResolveMultipleImports
- boolean Allow multiple anonymous imports if
styleName
is only in one of them. Defaults true.To add support for different CSS syntaxes (e.g. SCSS), perform the following two steps:
Add the postcss syntax loader as a development dependency:
npm install postcss-scss --save-dev
Add a filetypes
syntax mapping to the Babel plugin configuration.
For example for SCSS:
"filetypes": {
".scss": {
"syntax": "postcss-scss"
}
}
And optionally specify extra plugins:
"filetypes": {
".scss": {
"syntax": "postcss-scss",
"plugins": [
"postcss-nested"
]
}
}
NOTE:
postcss-nested
is added as an extra plugin for demonstration purposes only. It's not needed withpostcss-scss
because SCSS already supports nesting.
Postcss plugins can have options specified by wrapping the name and an options object in an array inside your config:
"plugins": [
["postcss-import-sync2", {
"path": ["src/styles", "shared/styles"]
}],
"postcss-nested"
]
You can set your own attribute mapping rules using the attributeNames
option.
It's an object, where keys are source attribute names and values are destination attribute names.
For example, the
<NavLink>
component from React Router
has an activeClassName
attribute to accept an additional class name. You can
set "attributeNames": { "activeStyleName": "activeClassName" }
to transform it.
The default styleName
-> className
transformation will not be affected
by an attributeNames
value without a styleName
key. Of course you can use
{ "styleName": "somethingOther" }
to change it, or use { "styleName": null }
to disable it.
This plugin does the following:
.css
or .scss
extension).styleName
attribute value into anonymous and named CSS module
references.styleName
value is a string literal, generates a string literal value.styleName
value is a
jSXExpressionContainer
,
uses a helper function (getClassName
)
to construct the className
value at the runtime.styleName
attribute from the element.className
to the existing className
value
(creates className
attribute if one does not exist).This plugin is an up-to-date, well-maintained fork of the original
babel-plugin-react-css-modules
:
css-loader
versions (see
css-loader
compatibility for details).The original babel-plugin-react-css-modules
plugin is largely abandoned by
its author since March 2019. When an year later updates of css-loader
and
Webpack broke dependant projects, with no reaction from
babel-plugin-react-css-modules
author on emerging issue reports in GitHub,
I (birdofpreyru) created this fork to ensure stability of my own projects
relying on it.
I am banned from commenting in the original project repo since I tried a little self-promo, trying to encourage people to switch over to my fork. If you read this, consider to spread the word to encourage more users to move to this fork.
babel-plugin-react-css-modules
Prefix plugin name in your Babel config by @dr.pogodin/
scope, i.e.:
@dr.pogodin/babel-plugin-react-css-modules
or @dr.pogodin/react-css-moudles
instead of babel-plugin-react-css-modules
or react-css-modules
.
Be sure to have webpack
installed (it is a must-to-have peer dependency
of this plugin starting from v6.2.0
).
css-loader
compatibilitycss-loader versions | this plugin versions |
---|---|
6.0.0 ÷ 6.3.0 (current) | 6.2.1 - 6.3.0 (current) |
5.2.5 ÷ 5.2.7 | 6.1.1 |
5.2.4 | 6.1.0 |
5.1.3 ÷ 5.2.3 | 6.0.11 /6.1.0 (1) |
5.0.0 ÷ 5.1.2 | 6.0.7 ÷ 6.0.11 |
4.2.0 ÷ 4.3.0 | 6.0.3 ÷ 6.0.6 |
<= 3.6.0 | original plugin |
1) There might be some corner-case differences in class name transformation between these versions of css-loader
and this plugin, but most probably they won't break compatibility for most users.
FAQs
Transforms styleName to className using compile time CSS module resolution.
The npm package @dr.pogodin/babel-plugin-react-css-modules receives a total of 3,308 weekly downloads. As such, @dr.pogodin/babel-plugin-react-css-modules popularity was classified as popular.
We found that @dr.pogodin/babel-plugin-react-css-modules demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.