Package Exports
- babel-plugin-react-css-modules
- babel-plugin-react-css-modules/dist/browser/getClassName
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (babel-plugin-react-css-modules) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
babel-plugin-react-css-modules
Transforms styleName to className using compile time CSS module resolution.
In contrast to react-css-modules, babel-plugin-react-css-modules has a loot smaller performance overhead (0-10% vs +50%; see Performance) and a lot smaller size footprint (less than 2kb vs 17kb reaact-css-modules + lodash dependency).
- Background
- Performance
- How does it work?
- Conventions
- Configuration
- Example transpilations
- Limitations
- Have a question or want to suggest an improvement?
Background
react-css-modules introduced a convention of using styleName attribute to reference CSS module. react-css-modules is a higher-order React component. It is using the styleName value to construct the className at the run-time. This abstraction frees a developer from needing to reference the imported styles object when using CSS modules (What's the problem?). However, this approach has a measurable performance penalty at the cost of better developer experience (DX).
babel-plugin-react-css-modules solves the DX problem without impacting the performance.
Performance
The important metric here is "Difference from base" (DFB). "base" is defined as using React with hardcoded className values. The lesser the DFB value, the bigger the performance impact.
Note: This benchmark suite does not include a scenario when
babel-plugin-react-css-modulescan statically construct the value ofclassName. If a literal value of theclassNameis constructed at the compile time, the performance is equal to the base benchmark.
| Name | Operations per second (relative margin of error) | Sample size | Difference from the base benchmark |
|---|---|---|---|
| Using className (base) | 8556 (±1.59) | 546 | -0% |
| Using styleName with react-css-modules | 5204 (±1.84) | 335 | -64% |
| Using styleName with babel-plugin-react-css-modules (runtime anonymous resolution) | 7821 (±1.89) | 481 | -9% |
| Using styleName with babel-plugin-react-css-modules (runtime named resolution) | 8155 (±1.63) | 499 | -4% |
Platform info: Darwin 16.1.0 x64 Node.JS 7.1.0 V8 5.4.500.36 NODE_ENV=production Intel(R) Core(TM) i7-4870HQ CPU @ 2.50GHz × 8
View the ./benchmark.
Run the benchmark:
git clone git@github.com:gajus/babel-plugin-react-css-modules.git
cd ./babel-plugin-react-css-modules
npm install
npm run build
cd ./benchmark
npm install
NODE_ENV=production ./testHow does it work?
- Builds index of all stylesheet imports per file.
- Uses postcss to parse the matching CSS files.
- Iterates through all JSX element declarations.
- Uses the
styleNamevalue to resolve the generated CSS class name of the CSS module.
- If
styleNamevalue is a string literal, generates a string literal value. - If
styleNamevalue is non-string (variable, condition, etc.), uses a helper function to constructclassNamevalue at the runtime.
- Removes the
styleNameattribute from the element. - Appends the resulting
classNameto the existingclassNamevalue (or createsclassNameattribute if one does not exist).
Configuration
| Name | Description | Default |
|---|---|---|
generateScopedName |
Refer to Generating scoped names | N/A (delegates default resolution to postcss-modules) |
Missing a configuration? Raise an issue.
Conventions
Named reference
Named reference is used to refer to a specific stylesheet import.
Format: [name of the import].[CSS module name].
Example:
import foo from './foo1.css';
import bar from './bar1.css';
// Imports "a" CSS module from ./foo1.css.
<div styleName="foo.a"></div>;
// Imports "a" CSS module from ./bar1.css.
<div styleName="bar.a"></div>;Example transpilations
Anonymous styleName resolution
When styleName is a literal string value, babel-plugin-react-css-modules resolves the value of className at the compile time.
Input:
import './bar.css';
<div styleName="a"></div>;
Output:
import './bar.css';
<div className="bar___a"></div>;
Named styleName resolution
When file imports multiple stylesheets, you must use a named reference.
Input:
import foo from './foo1.css';
import bar from './bar1.css';
<div styleName="foo.a"></div>;
<div styleName="bar.a"></div>;Output:
import foo from './bar.css';
<div className="bar___a"></div>;
Runtime styleName resolution
When the value of styleName cannot be determined at the compile time, babel-plugin-react-css-modules inlines all possible styles into the file. It then uses getClassName helper function to resolve the styleName value at the runtime.
Input:
import './bar.css';
<div styleName={Math.random() > .5 ? 'a' : 'b'}></div>;
Output:
import _getClassName from 'babel-plugin-react-css-modules/dist/browser/getClassName';
import foo from './bar.css';
const _styleModuleImportMap = {
foo: {
a: 'bar__a',
b: 'bar__b'
}
};
<div styleName={_getClassName(Math.random() > .5 ? 'a' : 'b', _styleModuleImportMap)}></div>;
Limitations
Have a question or want to suggest an improvement?
- Have a technical questions? http://stackoverflow.com/questions/ask?tags=babel-plugin-react-css-modules
- Have a feature suggestion or want to report an issue? https://github.com/gajus/babel-plugin-react-css-modules/issues
- Want to say hello to other
babel-plugin-react-css-modulesusers? https://gitter.im/babel-plugin-react-css-modules