Skip to content

Commit 064c030

Browse files
committed
feat: release initial version
0 parents  commit 064c030

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+991
-0
lines changed
52.7 KB
Loading
96 KB
Binary file not shown.

.babelrc

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"plugins": [
3+
"transform-es2015-modules-commonjs",
4+
"transform-es2015-parameters",
5+
"transform-es2015-destructuring",
6+
"transform-flow-strip-types"
7+
]
8+
}

.editorconfig

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
root = true
2+
3+
[*]
4+
end_of_line = lf
5+
insert_final_newline = true
6+
indent_style = space
7+
indent_size = 2

.eslintrc

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"extends": [
3+
"canonical"
4+
],
5+
"root": true
6+
}

.flowconfig

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[ignore]
2+
<PROJECT_ROOT>/node_modules/config-chain/test/broken.json
3+
<PROJECT_ROOT>/node_modules/conventional-changelog-core/test/fixtures/_malformation.json
4+
<PROJECT_ROOT>/node_modules/npmconf/test/fixtures/package.json

.gitignore

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
coverage
2+
dist
3+
node_modules
4+
*.log
5+
.*
6+
!.babelrc
7+
!.editorconfig
8+
!.eslintrc
9+
!.flowconfig
10+
!.gitignore
11+
!.npmignore
12+
!.README
13+
!.travis.yml

.npmignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
src
2+
test
3+
coverage
4+
.*
5+
*.log

.travis.yml

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
language: node_js
2+
node_js:
3+
- 7
4+
- 6
5+
- 5
6+
after_success:
7+
- semantic-release pre && npm publish && semantic-release post
8+
notifications:
9+
email: false
10+
sudo: false

ISSUE_TEMPLATE.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<!--
2+
Have a technical question? Raise a question on http://stackoverflow.com/ using "babel-plugin-react-css-modules" tag.
3+
4+
Use https://github.com/gajus/babel-plugin-react-css-modules/issues to report issues and suggest new features.
5+
-->

LICENSE

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
Copyright (c) 2016, Gajus Kuizinas (http://gajus.com/)
2+
All rights reserved.
3+
4+
Redistribution and use in source and binary forms, with or without
5+
modification, are permitted provided that the following conditions are met:
6+
* Redistributions of source code must retain the above copyright
7+
notice, this list of conditions and the following disclaimer.
8+
* Redistributions in binary form must reproduce the above copyright
9+
notice, this list of conditions and the following disclaimer in the
10+
documentation and/or other materials provided with the distribution.
11+
* Neither the name of the Gajus Kuizinas (http://gajus.com/) nor the
12+
names of its contributors may be used to endorse or promote products
13+
derived from this software without specific prior written permission.
14+
15+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18+
DISCLAIMED. IN NO EVENT SHALL ANUARY BE LIABLE FOR ANY
19+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

README.md

+194
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
# babel-plugin-react-css-modules
2+
3+
[![Travis build status](http://img.shields.io/travis/gajus/babel-plugin-react-css-modules/master.svg?style=flat-square)](https://travis-ci.org/gajus/babel-plugin-react-css-modules)
4+
[![NPM version](http://img.shields.io/npm/v/babel-plugin-react-css-modules.svg?style=flat-square)](https://www.npmjs.org/package/babel-plugin-react-css-modules)
5+
[![Canonical Code Style](https://img.shields.io/badge/code%20style-canonical-blue.svg?style=flat-square)](https://github.com/gajus/canonical)
6+
[![Twitter Follow](https://img.shields.io/twitter/follow/kuizinas.svg?style=social&label=Follow)](https://twitter.com/kuizinas)
7+
8+
<img src='./.README/babel-plugin-react-css-modules.png' height='150' />
9+
10+
Transforms `styleName` to `className` using compile time [CSS module](https://github.com/css-modules/css-modules) resolution.
11+
12+
In contrast to [`react-css-modules`](https://github.com/gajus/react-css-modules), `babel-plugin-react-css-modules` has a loot smaller performance overhead (0-10% vs +50%; see [Performance](#performance)) and a lot smaller size footprint (less than 2kb vs 17kb reaact-css-modules + lodash dependency).
13+
14+
* [Background](#background)
15+
* [Performance](#performance)
16+
* [How does it work?](#how-does-it-work)
17+
* [Conventions](#conventions)
18+
* [Named reference](#named-reference)
19+
* [Configuration](#configuration)
20+
* [Example transpilations](#example-transpilations)
21+
* [Anonymous `styleName` resolution](#anonymous-stylename-resolution)
22+
* [Named `styleName` resolution](#named-stylename-resolution)
23+
* [Runtime `styleName` resolution](#runtime-stylename-resolution)
24+
* [Limitations](#limitations)
25+
* [Have a question or want to suggest an improvement?](#have-a-question-or-want-to-suggest-an-improvement)
26+
27+
## Background
28+
29+
[`react-css-modules`](https://github.com/gajus/react-css-modules) introduced a convention of using `styleName` attribute to reference [CSS module](https://github.com/css-modules/css-modules). `react-css-modules` is a higher-order [React](https://facebook.github.io/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?](https://github.com/gajus/react-css-modules#whats-the-problem)). However, this approach has a measurable performance penalty at the cost of better developer experience (DX).
30+
31+
`babel-plugin-react-css-modules` solves the DX problem without impacting the performance.
32+
33+
## Performance
34+
35+
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.
36+
37+
> Note:
38+
> This benchmark suite does not include a scenario when `babel-plugin-react-css-modules` can statically construct the value of `className`.
39+
> If a literal value of the `className` is constructed at the compile time, the performance is equal to the base benchmark.
40+
41+
|Name|Operations per second (relative margin of error)|Sample size|Difference from the base benchmark|
42+
|---|---|---|---|
43+
|Using className (base)|8556 (±1.59)|546|-0%|
44+
|Using styleName with react-css-modules|5204 (±1.84)|335|-64%|
45+
|Using styleName with babel-plugin-react-css-modules (runtime anonymous resolution)|7821 (±1.89)|481|-9%|
46+
|Using styleName with babel-plugin-react-css-modules (runtime named resolution)|8155 (±1.63)|499|-4%|
47+
48+
> Platform info:
49+
> Darwin 16.1.0 x64
50+
> Node.JS 7.1.0
51+
> V8 5.4.500.36
52+
> NODE_ENV=production
53+
> Intel(R) Core(TM) i7-4870HQ CPU @ 2.50GHz × 8
54+
55+
View the [./benchmark](./benchmark).
56+
57+
Run the benchmark:
58+
59+
```bash
60+
git clone [email protected]:gajus/babel-plugin-react-css-modules.git
61+
cd ./babel-plugin-react-css-modules
62+
npm install
63+
npm run build
64+
cd ./benchmark
65+
npm install
66+
NODE_ENV=production ./test
67+
```
68+
69+
## How does it work?
70+
71+
1. Builds index of all stylesheet imports per file.
72+
1. Uses [postcss](https://github.com/postcss/postcss) to parse the matching CSS files.
73+
1. Iterates through all [JSX](https://facebook.github.io/react/docs/jsx-in-depth.html) element declarations.
74+
1. Uses the `styleName` value to resolve the generated CSS class name of the CSS module.
75+
* If `styleName` value is a string literal, generates a string literal value.
76+
* If `styleName` value is non-string (variable, condition, etc.), uses a helper function to construct `className` value at the runtime.
77+
1. Removes the `styleName` attribute from the element.
78+
1. Appends the resulting `className` to the existing `className` value (or creates `className` attribute if one does not exist).
79+
80+
## Configuration
81+
82+
|Name|Description|Default|
83+
|---|---|---|
84+
|`generateScopedName`|Refer to [Generating scoped names](https://github.com/css-modules/postcss-modules#generating-scoped-names)|N/A (delegates default resolution to [postcss-modules](https://github.com/css-modules/postcss-modules))|
85+
86+
Missing a configuration? [Raise an issue](https://github.com/gajus/babel-plugin-react-css-modules/issues/new?title=New%20configuration:).
87+
88+
## Conventions
89+
90+
### Named reference
91+
92+
Named reference is used to refer to a specific stylesheet import.
93+
94+
Format: `[name of the import].[CSS module name]`.
95+
96+
Example:
97+
98+
```js
99+
import foo from './foo1.css';
100+
import bar from './bar1.css';
101+
102+
// Imports "a" CSS module from ./foo1.css.
103+
<div styleName="foo.a"></div>;
104+
105+
// Imports "a" CSS module from ./bar1.css.
106+
<div styleName="bar.a"></div>;
107+
```
108+
109+
## Example transpilations
110+
111+
### Anonymous `styleName` resolution
112+
113+
When `styleName` is a literal string value, `babel-plugin-react-css-modules` resolves the value of `className` at the compile time.
114+
115+
Input:
116+
117+
```js
118+
import './bar.css';
119+
120+
<div styleName="a"></div>;
121+
122+
```
123+
124+
Output:
125+
126+
```js
127+
import './bar.css';
128+
129+
<div className="bar___a"></div>;
130+
131+
```
132+
133+
### Named `styleName` resolution
134+
135+
When file imports multiple stylesheets, you must use a [named reference](#named-reference).
136+
137+
Input:
138+
139+
```js
140+
import foo from './foo1.css';
141+
import bar from './bar1.css';
142+
143+
<div styleName="foo.a"></div>;
144+
<div styleName="bar.a"></div>;
145+
```
146+
147+
Output:
148+
149+
```js
150+
import foo from './bar.css';
151+
152+
<div className="bar___a"></div>;
153+
154+
```
155+
156+
### Runtime `styleName` resolution
157+
158+
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.
159+
160+
Input:
161+
162+
```js
163+
import './bar.css';
164+
165+
<div styleName={Math.random() > .5 ? 'a' : 'b'}></div>;
166+
167+
```
168+
169+
Output:
170+
171+
```js
172+
import _getClassName from 'babel-plugin-react-css-modules/dist/browser/getClassName';
173+
import foo from './bar.css';
174+
175+
const _styleModuleImportMap = {
176+
foo: {
177+
a: 'bar__a',
178+
b: 'bar__b'
179+
}
180+
};
181+
182+
<div styleName={_getClassName(Math.random() > .5 ? 'a' : 'b', _styleModuleImportMap)}></div>;
183+
184+
```
185+
186+
## Limitations
187+
188+
* [Establish a convention for extending the styles object at the runtime](https://github.com/gajus/babel-plugin-react-css-modules/issues/1)
189+
190+
## Have a question or want to suggest an improvement?
191+
192+
* Have a technical questions? http://stackoverflow.com/questions/ask?tags=babel-plugin-react-css-modules
193+
* Have a feature suggestion or want to report an issue? https://github.com/gajus/babel-plugin-react-css-modules/issues
194+
* Want to say hello to other `babel-plugin-react-css-modules` users? https://gitter.im/babel-plugin-react-css-modules

benchmark/package.json

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"dependencies": {
3+
"benchmark": "^2.1.2",
4+
"react": "^15.4.1",
5+
"react-css-modules": "^4.1.0",
6+
"react-dom": "^15.4.1"
7+
}
8+
}

0 commit comments

Comments
 (0)