Skip to content

Commit 9a15e74

Browse files
kylorhall-atlassiandddlr
andauthoredSep 30, 2024··
Sort shorthand vs. longhand declarations — breaking change behind config (#1700)
* Sort shorthand vs. longhand declarations * Update sorting logic for a lot more shorthands and attempt runtime sorting as well. Concerns: - Runtime sorting does not work properly as we'd also need per-bucket nested sorting where `@media, :focus, border` needs to be sorted. - `shorthandFor` needs 40 more shorthand properties defined… * Add all known shorthand properties, constituents, and sibling constituents. This no longer sorts `border-top` vs. `border-block-start` as they are siblings, not a sibling of a constituent… * Remove unused buildSourceMap function as it was breaking builds * Minimise ./packages/react/dist/browser/runtime/style.js size increase by moving shorthandFor to @compiled/react/runtime * Make shorthand 'sorting' more rigorous, ensuring that border-related properties are sorted deterministically * Fix outdated bucket number * Add tests, reduce bucket numbers * Add docs * Strengthen typing (thanks Kylor) * Add changeset * Enable in Webpack example project, and fix docs * Address PR feedback * Reset ordering of longhand properties because it no longer matters --------- Co-authored-by: Grant Wong <gwong2@atlassian.com>
1 parent 7a2226c commit 9a15e74

36 files changed

+1751
-82
lines changed
 

‎.changeset/chatty-geese-invite.md

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
'@compiled/babel-plugin-strip-runtime': minor
3+
'@compiled/parcel-optimizer': minor
4+
'@compiled/webpack-loader': minor
5+
'@compiled/react': minor
6+
'@compiled/utils': minor
7+
'@compiled/ssr-app': minor
8+
'@compiled/css': minor
9+
---
10+
11+
Sort shorthand properties so that they come before longhand properties.
12+
13+
When using Compiled, one of the following will happen:
14+
15+
Option 1. If stylesheet extraction is turned off ("runtime mode"): shorthand properties will be sorted before longhand properties, as long as they are not in a pseudo-selector like `:hover` or `:active`. This is enabled by default and cannot be turned off.
16+
17+
Option 2. If stylesheet extraction is turned on and one of the below is true:
18+
19+
- You are using Webpack
20+
- You are using Parcel AND you are running in production mode
21+
22+
... shorthand properties will only be sorted if `sortShorthand: true` is passed to `CompiledExtractPlugin` (Webpack), or `sortShorthand: true` is passed to your Compiled config file like `.compiledcssrc` (Parcel). When sorting shorthand properties using this method (option 2), shorthand properties will always be sorted before longhand properties, taking precedence over pseudo-selectors like `:hover` or `:active`.

‎.changeset/curvy-scissors-double.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@compiled/webpack-app': patch
3+
---
4+
5+
Enable sortShorthand

‎.changeset/lucky-gorillas-wash.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@compiled/utils': minor
3+
---
4+
5+
Remove unused buildSourceMap function

‎examples/webpack/webpack.config.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ const classNameCompressionMap = require('./class-name-compression-map.json');
1111

1212
const extractCSS = process.env.EXTRACT_TO_CSS === 'true';
1313

14+
console.log('Stylesheet extraction enabled?', extractCSS);
15+
1416
module.exports = {
1517
entry: './src/index.jsx',
1618
mode: 'development',
@@ -62,7 +64,10 @@ module.exports = {
6264
},
6365
plugins: [
6466
...(extractCSS
65-
? [new MiniCssExtractPlugin({ filename: '[name].css' }), new CompiledExtractPlugin()]
67+
? [
68+
new MiniCssExtractPlugin({ filename: '[name].css' }),
69+
new CompiledExtractPlugin({ sortShorthand: true }),
70+
]
6671
: []),
6772
new HtmlWebpackPlugin(),
6873
new webpack.HotModuleReplacementPlugin(),

‎package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@
144144
},
145145
{
146146
"path": "./packages/react/dist/browser/runtime/style.js",
147-
"limit": "482B",
147+
"limit": "1000B",
148148
"import": "CS",
149149
"ignore": [
150150
"react"

‎packages/babel-plugin-strip-runtime/src/index.ts

+7-4
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,13 @@ export default declare<PluginPass>((api) => {
8686
cssFilename
8787
);
8888
mkdirSync(dirname(cssFilePath), { recursive: true });
89-
writeFileSync(
90-
cssFilePath,
91-
sort(this.styleRules.sort().join('\n'), this.opts.sortAtRules)
92-
);
89+
90+
const sortConfig = {
91+
sortAtRulesEnabled: this.opts.sortAtRules,
92+
sortShorthandEnabled: this.opts.sortShorthand,
93+
};
94+
95+
writeFileSync(cssFilePath, sort(this.styleRules.sort().join('\n'), sortConfig));
9396

9497
// Add css import to file
9598
path.unshiftContainer(

‎packages/babel-plugin-strip-runtime/src/types.ts

+7
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ export interface PluginOptions {
3131
* Defaults to `true`.
3232
*/
3333
sortAtRules?: boolean;
34+
35+
/**
36+
* Whether to sort shorthand and longhand properties,
37+
* eg. `margin` before `margin-top` for enforced determinism.
38+
* Defaults to `false`.
39+
*/
40+
sortShorthand?: boolean;
3441
}
3542

3643
export interface PluginPass extends OriginalPluginPass {

‎packages/css/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
},
3636
"devDependencies": {
3737
"@types/autoprefixer": "^10.2.0",
38-
"@types/cssnano": "^5.0.0"
38+
"@types/cssnano": "^5.0.0",
39+
"outdent": "^0.8.0"
3940
}
4041
}

‎packages/css/src/plugins/__tests__/sort-at-rules.test.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ import postcss from 'postcss';
33
import { sortAtomicStyleSheet } from '../sort-atomic-style-sheet';
44

55
const transform = (css: string) => {
6-
const result = postcss([sortAtomicStyleSheet(true)]).process(css, {
6+
const result = postcss([
7+
sortAtomicStyleSheet({ sortAtRulesEnabled: undefined, sortShorthandEnabled: undefined }),
8+
]).process(css, {
79
from: undefined,
810
});
911

‎packages/css/src/plugins/__tests__/sort-pseudo-selectors.test.ts

+10-7
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,23 @@ import { atomicifyRules } from '../atomicify-rules';
55
import { sortAtomicStyleSheet } from '../sort-atomic-style-sheet';
66

77
const transform = (css: TemplateStringsArray) => {
8-
const result = postcss([sortAtomicStyleSheet(true)]).process(css[0], {
8+
const result = postcss([
9+
sortAtomicStyleSheet({ sortAtRulesEnabled: undefined, sortShorthandEnabled: undefined }),
10+
]).process(css[0], {
911
from: undefined,
1012
});
1113

1214
return result.css;
1315
};
1416

1517
const transformWithAtomicClasses = (css: TemplateStringsArray) => {
16-
const result = postcss([atomicifyRules(), sortAtomicStyleSheet(true), whitespace()]).process(
17-
css[0],
18-
{
19-
from: undefined,
20-
}
21-
);
18+
const result = postcss([
19+
atomicifyRules(),
20+
sortAtomicStyleSheet({ sortAtRulesEnabled: undefined, sortShorthandEnabled: undefined }),
21+
whitespace(),
22+
]).process(css[0], {
23+
from: undefined,
24+
});
2225

2326
return result.css;
2427
};

0 commit comments

Comments
 (0)
Please sign in to comment.