-
Notifications
You must be signed in to change notification settings - Fork 70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Compress atomic class names #1408
Changes from all commits
e2abdb1
ccbef95
b7b8602
1e2b969
f9c1e77
46fbdee
a0760fb
709f42e
9e367ec
fa61820
52b4398
f8201eb
4322536
c629e8e
0f4c9a8
cb7db29
447ff4a
43e5b5d
c3a4ac2
d405481
9b94342
bf5bed3
76e74f2
703ea6c
259be2d
5c2bf12
097cff1
d905599
bf5b751
fd93618
aad8d3a
5a26e15
956e2fc
9ef388d
476102c
f1a69e0
c18666f
f4b5e88
62aab19
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
--- | ||
'@compiled/parcel-transformer': minor | ||
'@compiled/webpack-loader': minor | ||
'@compiled/babel-plugin': minor | ||
'@compiled/react': minor | ||
'@compiled/css': minor | ||
--- | ||
|
||
Add an option to compress class names based on "classNameCompressionMap", which is provided by library consumers. | ||
Add a script to generate compressed class names. |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"1wyb12am": "a", | ||
"syaz5scu": "b", | ||
"syazruxl": "c", | ||
"k48pbfng": "d", | ||
"30l35scu": "e", | ||
"f8pj13q2": "f", | ||
"1e0c1o8l": "g", | ||
"ca0qftgi": "h", | ||
"u5f3ftgi": "i", | ||
"n3tdftgi": "j", | ||
"19bvftgi": "k", | ||
"19itak0l": "l", | ||
"2rko1l7b": "m", | ||
"syaz1aj3": "n", | ||
"1p1dangw": "o", | ||
"bfhkbf54": "p" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
const classNameCompressionMap = require('./class-name-compression-map.json'); | ||
|
||
module.exports = { | ||
importReact: false, | ||
extensions: ['.js', '.jsx', '.ts', '.tsx', '.customjsx'], | ||
parserBabelPlugins: ['typescript', 'jsx'], | ||
transformerBabelPlugins: [ | ||
[ | ||
'@babel/plugin-proposal-decorators', | ||
{ | ||
legacy: true, | ||
}, | ||
], | ||
], | ||
extract: true, | ||
optimizeCss: false, | ||
classNameCompressionMap: classNameCompressionMap, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
{ | ||
"1wyb12am": "a", | ||
"syaz32ev": "b", | ||
"k48pbfng": "c", | ||
"30l35scu": "d", | ||
"f8pj13q2": "e", | ||
"19itptrx": "f", | ||
"1kt92a4o": "g", | ||
"171dak0l": "h", | ||
"1swkri7e": "i", | ||
"1tjq14ap": "j", | ||
"yzbc5scu": "k", | ||
"19pk1ul9": "l", | ||
"syaz13q2": "m", | ||
"1wyb1ul9": "n", | ||
"19itlf8h": "o", | ||
"ca0q1vi7": "p", | ||
"u5f31vi7": "q", | ||
"n3td1vi7": "r", | ||
"19bv1vi7": "s", | ||
"k48p1fw0": "t", | ||
"syaz1cnh": "u", | ||
"19it1srw": "v", | ||
"bfhk1j28": "w", | ||
"syazruxl": "x", | ||
"bfhkbf54": "y" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -201,4 +201,160 @@ describe('babel plugin', () => { | |
|
||
expect(actual).toInclude('c_MyDiv'); | ||
}); | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we still have cases where compression is not safe, hence we should bail out? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Compression should be safe everywhere now. |
||
it('should compress class name for styled component', () => { | ||
const actual = transform( | ||
` | ||
import { styled } from '@compiled/react'; | ||
|
||
const MyDiv = styled.div\` | ||
font-size: 12px; | ||
\`; | ||
`, | ||
{ | ||
classNameCompressionMap: { | ||
'1wyb1fwx': 'a', | ||
}, | ||
} | ||
); | ||
|
||
expect(actual).toIncludeMultiple(['.a{font-size:12px}', 'ax(["_1wyb_a", __cmplp.className])']); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does the extracted CSS also contain There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, the extracted CSS looks like
|
||
}); | ||
|
||
it('should compress class name for css props', () => { | ||
const actual = transform( | ||
` | ||
import '@compiled/react'; | ||
|
||
<div css={{ fontSize: 12 }} /> | ||
`, | ||
{ | ||
classNameCompressionMap: { | ||
'1wyb1fwx': 'a', | ||
}, | ||
} | ||
); | ||
|
||
expect(actual).toIncludeMultiple(['.a{font-size:12px}', 'ax(["_1wyb_a"])']); | ||
}); | ||
|
||
it('should compress class name for ClassNames', () => { | ||
const actual = transform( | ||
` | ||
import { ClassNames } from '@compiled/react'; | ||
|
||
<ClassNames> | ||
{({ css }) => ( | ||
<div className={css({ fontSize: 12 })} /> | ||
)} | ||
</ClassNames> | ||
`, | ||
{ | ||
classNameCompressionMap: { | ||
'1wyb1fwx': 'a', | ||
}, | ||
} | ||
); | ||
|
||
expect(actual).toIncludeMultiple(['.a{font-size:12px}', 'className={ax(["_1wyb_a"])']); | ||
}); | ||
|
||
it('should compress class names with atrules', () => { | ||
const actual = transform( | ||
` | ||
import '@compiled/react'; | ||
<div css={{ "@media (max-width: 1250px) ": { fontSize: 12 } }} /> | ||
`, | ||
{ | ||
classNameCompressionMap: { | ||
pz521fwx: 'a', | ||
}, | ||
} | ||
); | ||
|
||
expect(actual).toIncludeMultiple([ | ||
'@media (max-width:1250px){.a{font-size:12px}}', | ||
'ax(["_pz52_a"])', | ||
]); | ||
}); | ||
|
||
it('should compress pseudo classes', () => { | ||
const actual = transform( | ||
` | ||
import '@compiled/react'; | ||
<div css={{ "&:hover": { fontSize: 12 }, "&:active": { color: 'red' } }} /> | ||
`, | ||
{ | ||
classNameCompressionMap: { | ||
'9h8h5scu': 'a', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: inconsistent quotes? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
e9151fwx: 'b', | ||
}, | ||
} | ||
); | ||
|
||
expect(actual).toIncludeMultiple([ | ||
'.a:active{color:red}', | ||
'.b:hover{font-size:12px}', | ||
'ax(["_e915_b _9h8h_a"])', | ||
]); | ||
}); | ||
|
||
it('should compress nested selector', () => { | ||
const actual = transform( | ||
` | ||
import '@compiled/react'; | ||
<div css={{ '>div': { 'div div:hover': { fontSize: 12 } } }} /> | ||
`, | ||
{ | ||
classNameCompressionMap: { | ||
'1jkf1fwx': 'a', | ||
}, | ||
} | ||
); | ||
|
||
expect(actual).toIncludeMultiple(['.a >div div div:hover{font-size:12px}', 'ax(["_1jkf_a"]']); | ||
}); | ||
|
||
it('should compress conditional class names', () => { | ||
const actual = transform( | ||
` | ||
import '@compiled/react'; | ||
<div css={[{ fontSize: ({ bar }) => bar ? 14 : 16 }, () => foo ? { fontSize: 12 } : {}, baz && { fontSize: 20 }]} /> | ||
`, | ||
{ | ||
classNameCompressionMap: { | ||
'1wyb19ub': 'a', | ||
'1wyb1fwx': 'b', | ||
}, | ||
} | ||
); | ||
|
||
expect(actual).toIncludeMultiple([ | ||
'.a{font-size:16}', | ||
'.b{font-size:12px}', | ||
'bar ? "_1wyb1o8a" : "_1wyb_a"', | ||
'foo && "_1wyb_b"', | ||
]); | ||
}); | ||
|
||
it('should compress class names according to the map', () => { | ||
const actual = transform( | ||
` | ||
import '@compiled/react'; | ||
<div css={{ fontSize: 12, color: 'red', marginTop: 10 }} /> | ||
`, | ||
{ | ||
classNameCompressionMap: { | ||
syaz5scu: 'a', | ||
}, | ||
} | ||
); | ||
|
||
expect(actual).toIncludeMultiple([ | ||
'._19pk19bv{margin-top:10px}', | ||
'.a{color:red}', | ||
'._1wyb1fwx{font-size:12px}', | ||
'ax(["_1wyb1fwx _syaz_a _19pk19bv"]', | ||
]); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where/how does this map get generated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question! For now it's assumed that library consumers manually curate the map and pass it to the babel-plugin. We will later create an automatic method to generate the map by statically analysing the codebase, and the map should be periodically updated by a build.