Converts React components using imported CSS stylesheets to equivalent CSS Modules syntax.
Given this (simpilified) CSS file and React component:
/* button.css */
.button {
flex: 1;
background-color: #eee;
color: #222;
}
/* button.tsx */
import "./button.css";
export default ({ children }) => <div className="button">{children}</div>;
It will product the following, modified component:
/* button.tsx */
import * as styles from "./button.css";
export default ({ children }) => (
<div className={styles["button"]}>{children}</div>
);
Running the following command will codemod
all files in dir/
(Make sure they're checked into source control!):
npx codemod -p babel-plugin-codemod-react-css-modules dir/
You can also pass options to the plugin like so
npx codemod \
-p babel-plugin-codemod-react-css-modules \
-o react-css-modules='{ "importIdentifier": "css" }' \
path/to/file
Or store them in a file e.g. options.json
and reference them using the @
syntax:
npx codemod \
-p babel-plugin-codemod-react-css-modules \
-o react-css-modules=@options.json \
path/to/file
For a list of valid options see src/index.ts:PluginOptions
The plugin will attempt to convert any string literals specifically that have a value within the list of CSS class names of the imported .css
file.
It will also attempt to process strings within variables referenced in the className
expression e.g. className={className}
will result in the scoped className
variable being recursively processed as outlined above.
This logic is scoped to only affect statements within JSX className
declarations, which might not pick up 100% of edge cases. In particular, it won't pick up stuff like... className={"button--"+variant}
, since the full class name wouldn't be known until runtime. You'll need to handle this case manually
This plugin uses postcss
and the postcss-modules
plugin to get a list of valid CSS class names from the imported .css
file. If it isn't picking up one of your classes, you might need to include a custom postcss
plugin to handle your CSS. See below for details.
You'll need to modify your webpack
or other bundling environment to load the CSS files using the CSS Modules
specification for this to work once the codemod is done.
css-loader
supports CSS Modules
out the box, or if you prefer you can use postcss-loader
and the postcss-modules
plugin instead.
Yes, the plugin will look for your postcss.config.js
file (or similar) thanks to it using the postcss-load-config
module.
Yes, see above.
Yes, see PluginOptions
in src/index.ts