You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+78
Original file line number
Diff line number
Diff line change
@@ -2,6 +2,84 @@
2
2
3
3
## Unreleased
4
4
5
+
* Implement `composes` from CSS modules ([#20](https://github.com/evanw/esbuild/issues/20))
6
+
7
+
This release implements the `composes` annotation from the [CSS modules specification](https://github.com/css-modules/css-modules#composition). It provides a way for class selectors to reference other class selectors (assuming you are using the `local-css` loader). And with the `from` syntax, this can even work with local names across CSS files. For example:
8
+
9
+
```js
10
+
// app.js
11
+
import { submit } from'./style.css'
12
+
constdiv=document.createElement('div')
13
+
div.className= submit
14
+
document.body.appendChild(div)
15
+
```
16
+
17
+
```css
18
+
/* style.css */
19
+
.button {
20
+
composes: pulse from "anim.css";
21
+
display: inline-block;
22
+
}
23
+
.submit {
24
+
composes: button;
25
+
font-weight: bold;
26
+
}
27
+
```
28
+
29
+
```css
30
+
/* anim.css */
31
+
@keyframes pulse {
32
+
from, to { opacity: 1 }
33
+
50% { opacity: 0.5 }
34
+
}
35
+
.pulse {
36
+
animation: 2s ease-in-out infinite pulse;
37
+
}
38
+
```
39
+
40
+
Bundling thiswith esbuild using `--bundle --outdir=dist --loader:.css=local-css` now gives the following:
41
+
42
+
```js
43
+
(() => {
44
+
// style.css
45
+
var submit = "anim_pulse style_button style_submit";
46
+
47
+
// app.js
48
+
var div = document.createElement("div");
49
+
div.className = submit;
50
+
document.body.appendChild(div);
51
+
})();
52
+
```
53
+
54
+
```css
55
+
/* anim.css */
56
+
@keyframes anim_pulse {
57
+
from, to {
58
+
opacity: 1;
59
+
}
60
+
50% {
61
+
opacity: 0.5;
62
+
}
63
+
}
64
+
.anim_pulse {
65
+
animation: 2s ease-in-out infinite anim_pulse;
66
+
}
67
+
68
+
/* style.css */
69
+
.style_button {
70
+
display: inline-block;
71
+
}
72
+
.style_submit {
73
+
font-weight: bold;
74
+
}
75
+
```
76
+
77
+
Import paths in the `composes: ... from` syntax are resolved using the new`composes-from`import kind, which can be intercepted by plugins during import path resolution when bundling is enabled.
78
+
79
+
Note that the order in which composed CSS classes from separate files appear in the bundled output file is deliberately _**undefined**_ by design (see [the specification](https://github.com/css-modules/css-modules#composing-from-other-files) for details). You are not supposed to declare the same CSS property in two separate class selectors and then compose them together. You are only supposed to compose CSS class selectors that declare non-overlapping CSS properties.
80
+
81
+
Issue [#20](https://github.com/evanw/esbuild/issues/20) (the issue tracking CSS modules) is esbuild's most-upvoted issue! With this change, I now consider esbuild's implementation of CSS modules to be complete. There are still improvements to make and there may also be bugs with the current implementation, but these can be tracked in separate issues.
82
+
5
83
* Fix non-determinism with`tsconfig.json` and symlinks ([#3284](https://github.com/evanw/esbuild/issues/3284))
6
84
7
85
This release fixes an issue that could cause esbuild to sometimes emit incorrect build output in cases where a file under the effect of`tsconfig.json` is inconsistently referenced through a symlink. It can happen when using `npm link` to create a symlink within `node_modules` to an unpublished package. The build result was non-deterministic because esbuild runs module resolution in parallel and the result of the `tsconfig.json` lookup depended on whether the import through the symlink or not through the symlink was resolved first. This problem was fixed by moving the `realpath` operation before the `tsconfig.json` lookup.
0 commit comments