Skip to content

Commit

Permalink
Update README.md (#7)
Browse files Browse the repository at this point in the history
This PR removes the installation steps and set up for Babel.

We do not support hooking to the Babel entry point anymore.
  • Loading branch information
tusharsnx authored Jun 15, 2024
1 parent 9b83288 commit c8b64c6
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 131 deletions.
196 changes: 65 additions & 131 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,206 +1,140 @@
# Introduction

This is a babel plugin to transform all your string classes into css-module classes automatically.
🚀 A Webpack plugin to transform your React `classNames` into CSS module classnames automatically 🚀

Its lets you use css-module classes without style object.
It is faster to write, improves code readability and supports multiple css-module using [named-module](#introducing-named-css-modules)
- Faster to write ⚡
- Improves code readability 📖
- Supports multiple CSS Modules using [Named modules](#named-modules)
- Works with CSS, SASS, and SCSS modules 🔥

Also supports \*sass/scss modules.

_\*you may need to use sass-loader with webpack_

# Installation

- Install the plugin with npm:

```sh
npm install --save-dev jsx-css-module-transforms
```

- If you are using babel, add this to your plugins:
```jsx
// Original:

```jsonc
// .babelrc
import "./style.module.css"

{
"plugins": ["module:jsx-css-module-transforms"]
function Component() {
return <div className="foo bar"></div>
}
```

- For Webpack, modify the babel-loader options to include the plugin:
// Transformed:

```js
// webpack.config.js

module.exports = {
module: {
rules: [
{
loader: "babel-loader",
options: {
plugins: [ "module:jsx-css-module-transforms", ... ],
},
},
],
},
import style from "./style.module.css"

function Component() {
return <div className={ style.foo + " " + style.bar }></div>
}
```

> Note: _The plugin relies on the **JSX** syntax. Other plugins that executes early might transform JSX
> before it reaches to the plugin which might cause some problems. jsx-css-module-transforms plugin needs
> to be placed before(ideally, at the beginning) other plugins that transform JSX._
# Usage

We can import the css-module like normal css import without any import variable.

```jsx
import "./m1.module.css"
```
# Installation

The plugin will automatically change the import statement to include style object,
which will be used to access the css-module classes.
- Install the plugin:

```jsx
import _style from "./m1.module.css" // modified
```bash
npm install --save-dev jsx-css-module-transforms
```

If we want to use the css-module, we need to write all our css classes using
style object that we just imported:
- Add the plugin to the list of plugins in `webpack.config.js`:

```jsx
import _style from "./m1.module.css"
```js
import JsxCssModuleTransforms from "jsx-css-module-transforms"

function Component() {
return <h1 className={`${_style.foo} ${_style.bar}`}> ... </h1>
let config = {
plugins: [JsxCssModuleTransforms, ...otherPlugins]
}
```

This sometimes can get too verbose and hurts **code readibility**.
It would be nice if we could write classnames within a string and not
having to deal with any style objects.
export default config;
```

# Usage

With the help of plugin, we don't have to use style object anymore, instead we can specify our classes by just using strings:
The plugin automatically transforms CSS module imports and CSS classnames as required.

Without the plugin, you may write your code like this:
```jsx
import "./m1.module.css"
import style from "./style.module.css"

function Component() {
return <h1 className="foo bar"> ... </h1>
return <>
<div className={style.card1}></div>
<div className={style.card2}></div>
<div className={`${style.card2} ${style.cardFlipped}`}></div>
</>
}
```
This can get quite verbose at times and hurts **code readibility** 😵

This looks more readable and is faster to write as well.
__jsx-css-modules-transforms__ will modify the code to use css-module and its style object automatically without
us having to do anything:
With the help of this plugin, we can fix that! You can simply write your
classnames as strings and let the plugin handle the rest:

```jsx
// modified
import _style from "./m1.module.css"
import "./style.module.css"

function Component() {
return <h1 className={`${_style["foo"]} ${_style["bar"]}`}> ..... </h1>
return <>
<div className="card-1"></div>
<div className="card-2"></div>
<div className="card-2 card-flipped"></div>
</>
}
```

The transformed code uses object bracket-notation instead of dot-notation as this allows
us to use `-` (dash) within our classnames (eg. `className="foo-bar"`).

## Global Styles
This improves readability and follows the same pattern as regular CSS.

By default, If plugin finds **any** `'*.module.css'` import, it will transform **all** the css classes
to use style objects. To use global css classnames, we need to add `':g'` at the end of the classname.
This tells plugin not to transform these classes and keep them as is:

```jsx
import "./m1.module.css"
## Global styles

function Component() {
return <h1 className="foo bar:g baz"> ... </h1>
}
```
When the plugin finds `'.module.css'` import in the file, it will transform
**all** CSS classnames to use the imported CSS module. However, you may want
to use regular CSS classnames and prevent transformations on them. This
can be done by adding `:g` at the end of the classname:

```jsx
// modified
import _style from "./m1.module.css"
import "./style.module.css"

function Component() {
return <h1 className={`${_style["foo"]} bar ${_style["baz"]}`}> ... </h1>
return <div className="card-layout:g card-rnd-1"></div>
}
```

In this example, `'bar'` might be declared in the global style-sheet, while `'foo'` and `'baz'` are
scoped to the imported css module.
In this example, `card-layout` may be declared in the global style-sheet,
whereas `card-rnd-1` is declared in the the imported CSS module.

## Imported CSS module

## Usage With Already Imported CSS-Module

If you are already using CSS-Modules, the plugin will transform string (containing classnames)
that is given to any `className` attr. For example:

```jsx
import style from "./component.module.css"

function Component() {
return (
<div className={style.foo}>
<h1 className="bar baz"> ... </h1>
</div>
)
}
```
If you've been using CSS modules in your project, you can keep the old
code as-is, while the new code can use strings for the classnames:

```jsx
// modified
import style from "./component.module.css"

function Component() {
return (
<div className={style.foo}>
<h1 className={`${style["bar"]} ${style["baz"]}`}> ... </h1>
<h1 className="bar baz"></h1>
</div>
)
}
```

# Introducing Named CSS-Modules
## Named modules

In most cases, we would be using single CSS-Module inside a component but sometimes,
It might make sense to create reusable CSS-Modules and apply them in multiple different components.
You can use multiple CSS module within a file using Named modules.

In order to work with named CSS-Modules, we need to give names to each css-module import
by adding `:<module-name>` at the end of the path:
To use Named CSS modules, you can add labels to each CSS module import
in the file by adding `:<module-name>` at the end of the path:

```jsx
import "./layout.module.css:layout"
import "./component.module.css:com"
```

To access CSS-Module class, simply add `:<module-name>` at the end of the classname that specifies which CSS-Module
to use for the class:
And use the same labels for writing your classnames:

```jsx
function Component() {
return (
<ul className="food-items:layout">
<li className="food-item:com"> ... </li>
<li className="food-item:com"> ... </li>
</ul>
)
}
```
Transformed code would look like this:

```jsx
import _layout from "./layout.module.css"
import _com from "./component.module.css"

function Component() {
return (
<ul className={`${_layout["food-items"]}`}>
<li className={`${_com["food-item"]}`}> ... </li>
<li className={`${_com["food-item"]}`}> ... </li>
<li className="food-item:com"></li>
<li className="food-item:com"></li>
</ul>
)
}
Expand Down
6 changes: 6 additions & 0 deletions src/transforms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ export function createModuleMemberExpression(classname: string, module: string,
moduleIdentifier = t.identifier(modules.namedModules[module]);
}

// When a class has dashes in its name, e.g. `.my-class`, it can be
// read from the imported style object in two ways:
// - Remove dash and camelCase the class name: `style.myClass`.
// - Use the bracket syntax for reading object property: `style["my-class"]`.
// The latter has the benefit that we can avoid transforming the classname string
// and just use it in the generated MemberExpression. Set `computed` to true to use the bracket syntax
return t.memberExpression(moduleIdentifier, classnameStringLiteral, true);
}

Expand Down

0 comments on commit c8b64c6

Please sign in to comment.