@astryxdesign/build 0.0.0-bootstrap.0 → 0.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +245 -1
- package/dist/vite.mjs +284 -0
- package/package.json +54 -5
- package/src/babel.js +106 -0
- package/src/babel.test.mjs +73 -0
- package/src/config.js +92 -0
- package/src/index.js +251 -0
- package/src/next.js +66 -0
- package/src/vite.test.ts +45 -0
- package/src/vite.ts +427 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Meta Platforms, Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,247 @@
|
|
|
1
1
|
# @astryxdesign/build
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Build plugins for XDS source builds. Provides babel, PostCSS, and Vite integrations that compile XDS library and product code with separate class name prefixes, which enables independent CSS layers:
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
reset < astryx-base (library, astryx prefix) < astryx-theme < product (app, x prefix)
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Why?
|
|
10
|
+
|
|
11
|
+
StyleX generates atomic CSS: same declaration = same class name. Without separate prefixes, library and product classes collide and can't be placed in independent CSS layers, which breaks theme overrides.
|
|
12
|
+
|
|
13
|
+
`@astryxdesign/build` solves this by:
|
|
14
|
+
|
|
15
|
+
1. Compiling XDS library code with `astryx` prefix (`.astryx78zum5`)
|
|
16
|
+
2. Compiling product code with default `x` prefix (`.x78zum5`)
|
|
17
|
+
3. Placing each group in its own CSS `@layer`
|
|
18
|
+
|
|
19
|
+
## Packages
|
|
20
|
+
|
|
21
|
+
| Export | Purpose | Platform |
|
|
22
|
+
| -------------------- | --------------------------------------------- | --------------------------- |
|
|
23
|
+
| `@astryxdesign/build/babel` | Babel plugin: splits class prefixes per file | Next.js, any babel pipeline |
|
|
24
|
+
| `@astryxdesign/build/postcss` | PostCSS plugin: compiles + splits CSS layers | Next.js |
|
|
25
|
+
| `@astryxdesign/build/vite` | Vite plugin: wraps unplugin + splits layers | Vite, Storybook |
|
|
26
|
+
|
|
27
|
+
## Install
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm install -D @astryxdesign/build @stylexjs/babel-plugin @babel/core
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
For Vite, also install:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install -D @stylexjs/unplugin
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Next.js Setup
|
|
42
|
+
|
|
43
|
+
### 1. babel.config.js
|
|
44
|
+
|
|
45
|
+
```js
|
|
46
|
+
const path = require('path');
|
|
47
|
+
|
|
48
|
+
module.exports = {
|
|
49
|
+
presets: ['next/babel'],
|
|
50
|
+
plugins: [
|
|
51
|
+
[
|
|
52
|
+
'@astryxdesign/build/babel',
|
|
53
|
+
{
|
|
54
|
+
dev: process.env.NODE_ENV !== 'production',
|
|
55
|
+
runtimeInjection: false,
|
|
56
|
+
treeshakeCompensation: true,
|
|
57
|
+
enableInlinedConditionalMerge: true,
|
|
58
|
+
aliases: {
|
|
59
|
+
'@astryxdesign/core/*': [path.join(__dirname, 'node_modules/@astryxdesign/core/*')],
|
|
60
|
+
'@astryxdesign/core': [path.join(__dirname, 'node_modules/@astryxdesign/core')],
|
|
61
|
+
},
|
|
62
|
+
unstable_moduleResolution: {type: 'commonJS'},
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
],
|
|
66
|
+
};
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 2. postcss.config.js
|
|
70
|
+
|
|
71
|
+
```js
|
|
72
|
+
const path = require('path');
|
|
73
|
+
|
|
74
|
+
module.exports = {
|
|
75
|
+
plugins: {
|
|
76
|
+
'@astryxdesign/build/postcss': {
|
|
77
|
+
appDir: 'src',
|
|
78
|
+
babelPlugins: [
|
|
79
|
+
[
|
|
80
|
+
'@stylexjs/babel-plugin',
|
|
81
|
+
{
|
|
82
|
+
dev: process.env.NODE_ENV !== 'production',
|
|
83
|
+
runtimeInjection: false,
|
|
84
|
+
treeshakeCompensation: true,
|
|
85
|
+
enableInlinedConditionalMerge: true,
|
|
86
|
+
aliases: {
|
|
87
|
+
'@astryxdesign/core/*': [path.join(__dirname, 'node_modules/@astryxdesign/core/*')],
|
|
88
|
+
'@astryxdesign/core': [path.join(__dirname, 'node_modules/@astryxdesign/core')],
|
|
89
|
+
},
|
|
90
|
+
unstable_moduleResolution: {type: 'commonJS'},
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
],
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### 3. next.config.mjs
|
|
100
|
+
|
|
101
|
+
```js
|
|
102
|
+
const nextConfig = {
|
|
103
|
+
transpilePackages: ['@astryxdesign/core', '@astryxdesign/theme-default'],
|
|
104
|
+
webpack: config => {
|
|
105
|
+
// Resolve to source TypeScript instead of dist
|
|
106
|
+
config.resolve.conditionNames = ['source', 'import', 'require', 'default'];
|
|
107
|
+
return config;
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export default nextConfig;
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### 4. CSS files
|
|
115
|
+
|
|
116
|
+
`src/app/layers.css`:
|
|
117
|
+
|
|
118
|
+
```css
|
|
119
|
+
@layer reset, astryx-base, astryx-theme, product;
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
`src/app/globals.css`:
|
|
123
|
+
|
|
124
|
+
```css
|
|
125
|
+
@import './layers.css';
|
|
126
|
+
@import '@astryxdesign/core/reset.css';
|
|
127
|
+
@import '@astryxdesign/theme-default/theme.css';
|
|
128
|
+
|
|
129
|
+
@stylex;
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
> `layers.css` must be a separate file because webpack hoists `@import` content above inline CSS.
|
|
133
|
+
|
|
134
|
+
### 5. Browserslist
|
|
135
|
+
|
|
136
|
+
```json
|
|
137
|
+
{
|
|
138
|
+
"browserslist": ["last 1 Chrome version"]
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Vite Setup
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
import {xdsStylex} from '@astryxdesign/build/vite';
|
|
148
|
+
import react from '@vitejs/plugin-react';
|
|
149
|
+
|
|
150
|
+
export default defineConfig({
|
|
151
|
+
plugins: [
|
|
152
|
+
...xdsStylex({
|
|
153
|
+
stylexOptions: {
|
|
154
|
+
dev: process.env.NODE_ENV === 'development',
|
|
155
|
+
runtimeInjection: false,
|
|
156
|
+
treeshakeCompensation: true,
|
|
157
|
+
unstable_moduleResolution: {
|
|
158
|
+
type: 'commonJS',
|
|
159
|
+
rootDir: __dirname,
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
}),
|
|
163
|
+
react(),
|
|
164
|
+
],
|
|
165
|
+
resolve: {
|
|
166
|
+
alias: {
|
|
167
|
+
'@astryxdesign/core': path.resolve(__dirname, 'node_modules/@astryxdesign/core/src'),
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
optimizeDeps: {
|
|
171
|
+
exclude: ['@astryxdesign/core', '@astryxdesign/theme-default'],
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## How it works
|
|
179
|
+
|
|
180
|
+
### Babel plugin (`@astryxdesign/build/babel`)
|
|
181
|
+
|
|
182
|
+
Wraps `@stylexjs/babel-plugin` with two internal instances: one with `classNamePrefix: 'astryx'` for library files, one with default `'x'` for product files. Routes each file to the correct instance based on its path.
|
|
183
|
+
|
|
184
|
+
Library patterns (configurable):
|
|
185
|
+
|
|
186
|
+
- `packages/core/`
|
|
187
|
+
- `packages/themes/`
|
|
188
|
+
- `node_modules/@astryxdesign/`
|
|
189
|
+
|
|
190
|
+
### PostCSS plugin (`@astryxdesign/build/postcss`)
|
|
191
|
+
|
|
192
|
+
Compiles StyleX from both library and product source files in two separate passes with different prefixes. Wraps the results in named `@layer` blocks:
|
|
193
|
+
|
|
194
|
+
- Library rules → `@layer astryx-base`
|
|
195
|
+
- Product rules → `@layer product`
|
|
196
|
+
|
|
197
|
+
### Vite plugin (`@astryxdesign/build/vite`)
|
|
198
|
+
|
|
199
|
+
Wraps `@stylexjs/unplugin` and intercepts the dev CSS endpoint (`/virtual:stylex.css`). Partitions the collected rules by file path and serves split-layer CSS.
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Advanced Options
|
|
204
|
+
|
|
205
|
+
### Babel plugin
|
|
206
|
+
|
|
207
|
+
```js
|
|
208
|
+
[
|
|
209
|
+
'@astryxdesign/build/babel',
|
|
210
|
+
{
|
|
211
|
+
// Patterns to identify library files (default shown)
|
|
212
|
+
libraryPatterns: [
|
|
213
|
+
'packages/core/',
|
|
214
|
+
'packages/themes/',
|
|
215
|
+
'node_modules/@astryxdesign/',
|
|
216
|
+
],
|
|
217
|
+
|
|
218
|
+
// Class name prefix for library styles (default: 'astryx')
|
|
219
|
+
libraryPrefix: 'astryx',
|
|
220
|
+
|
|
221
|
+
// Class name prefix for product styles (default: 'x')
|
|
222
|
+
classNamePrefix: 'x',
|
|
223
|
+
|
|
224
|
+
// ... all @stylexjs/babel-plugin options
|
|
225
|
+
},
|
|
226
|
+
];
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### PostCSS plugin
|
|
230
|
+
|
|
231
|
+
```js
|
|
232
|
+
'@astryxdesign/build/postcss': {
|
|
233
|
+
appDir: 'src', // Your app source directory
|
|
234
|
+
babelPlugins: [...], // StyleX babel plugin config
|
|
235
|
+
libraryPrefix: 'astryx', // Prefix for library CSS (default: 'astryx')
|
|
236
|
+
extraInclude: [...], // Additional glob patterns
|
|
237
|
+
layers: { // Layer names (defaults shown)
|
|
238
|
+
library: 'astryx-base',
|
|
239
|
+
product: 'product',
|
|
240
|
+
},
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## Related
|
|
245
|
+
|
|
246
|
+
- [example-nextjs-source](../../apps/example-nextjs-source/): full Next.js source build example
|
|
247
|
+
- [`@stylexjs/babel-plugin`](https://github.com/facebook/stylex): the underlying StyleX compiler
|
package/dist/vite.mjs
ADDED
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
// Built from src/vite.ts — do not edit directly
|
|
2
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
3
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
4
|
+
}) : x)(function(x) {
|
|
5
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
6
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
// src/vite.ts
|
|
10
|
+
import stylexBabelPlugin from "@stylexjs/babel-plugin";
|
|
11
|
+
import stylex from "@stylexjs/unplugin";
|
|
12
|
+
import path from "path";
|
|
13
|
+
import { fileURLToPath } from "url";
|
|
14
|
+
var __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
15
|
+
var LIBRARY_PATTERN = "node_modules/@astryxdesign/";
|
|
16
|
+
var STYLEX_CSS_PATH = "/virtual:stylex.css";
|
|
17
|
+
var LIGHTNINGCSS_TARGETS = {
|
|
18
|
+
chrome: 123 << 16,
|
|
19
|
+
firefox: 120 << 16,
|
|
20
|
+
safari: 17 << 16 | 5 << 8
|
|
21
|
+
};
|
|
22
|
+
function xdsStylex(options = {}) {
|
|
23
|
+
if ("stylexOptions" in options && options.stylexOptions) {
|
|
24
|
+
return xdsStylexLegacy(options);
|
|
25
|
+
}
|
|
26
|
+
const opts = options;
|
|
27
|
+
const {
|
|
28
|
+
dev = process.env.NODE_ENV !== "production",
|
|
29
|
+
rootDir = process.cwd(),
|
|
30
|
+
libraryPattern = LIBRARY_PATTERN,
|
|
31
|
+
layers = {},
|
|
32
|
+
lightningcssTargets,
|
|
33
|
+
stylexPrefix = "astryx",
|
|
34
|
+
stylexOverrides = {}
|
|
35
|
+
} = opts;
|
|
36
|
+
const libraryLayer = layers.library ?? "astryx-base";
|
|
37
|
+
const productLayer = layers.product ?? "product";
|
|
38
|
+
const stylexOptions = {
|
|
39
|
+
dev,
|
|
40
|
+
runtimeInjection: false,
|
|
41
|
+
treeshakeCompensation: true,
|
|
42
|
+
unstable_moduleResolution: {
|
|
43
|
+
type: "commonJS",
|
|
44
|
+
rootDir
|
|
45
|
+
},
|
|
46
|
+
...lightningcssTargets && {
|
|
47
|
+
lightningcssOptions: { targets: lightningcssTargets }
|
|
48
|
+
},
|
|
49
|
+
...stylexOverrides
|
|
50
|
+
};
|
|
51
|
+
const xdsBabelPlugin = path.resolve(__dirname, "../src/babel.js");
|
|
52
|
+
const basePlugin = stylex.vite({
|
|
53
|
+
...stylexOptions,
|
|
54
|
+
useCSSLayers: true,
|
|
55
|
+
babelConfig: {
|
|
56
|
+
plugins: [
|
|
57
|
+
[
|
|
58
|
+
xdsBabelPlugin,
|
|
59
|
+
{
|
|
60
|
+
...stylexOptions,
|
|
61
|
+
libraryPrefix: stylexPrefix,
|
|
62
|
+
babelConfig: void 0
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
const layerOrderPlugin = {
|
|
69
|
+
name: "xds-css-layer-order",
|
|
70
|
+
transformIndexHtml() {
|
|
71
|
+
return [
|
|
72
|
+
{
|
|
73
|
+
tag: "style",
|
|
74
|
+
children: `@layer reset, ${libraryLayer}, astryx-theme, ${productLayer};`,
|
|
75
|
+
injectTo: "head-prepend"
|
|
76
|
+
}
|
|
77
|
+
];
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
const configPlugin = {
|
|
81
|
+
name: "xds-config",
|
|
82
|
+
config() {
|
|
83
|
+
let xdsPackages = ["@astryxdesign/core"];
|
|
84
|
+
try {
|
|
85
|
+
const fs = __require("fs");
|
|
86
|
+
const xdsDir = path.resolve(rootDir, "node_modules/@astryxdesign");
|
|
87
|
+
if (fs.existsSync(xdsDir)) {
|
|
88
|
+
xdsPackages = fs.readdirSync(xdsDir).filter((name) => !name.startsWith(".")).map((name) => `@astryxdesign/${name}`);
|
|
89
|
+
}
|
|
90
|
+
} catch {
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
resolve: {
|
|
94
|
+
alias: {
|
|
95
|
+
"@astryxdesign/core/theme/tokens.stylex": path.resolve(
|
|
96
|
+
rootDir,
|
|
97
|
+
"node_modules/@astryxdesign/core/src/theme/tokens.stylex.ts"
|
|
98
|
+
),
|
|
99
|
+
"@astryxdesign/core": path.resolve(rootDir, "node_modules/@astryxdesign/core/src")
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
optimizeDeps: {
|
|
103
|
+
exclude: xdsPackages
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
const splitLayerPlugin = {
|
|
109
|
+
name: "xds-split-layers",
|
|
110
|
+
configureServer(server) {
|
|
111
|
+
let stylexPlugin = null;
|
|
112
|
+
return () => {
|
|
113
|
+
for (const p of server.config.plugins.flat()) {
|
|
114
|
+
if (p?.__stylexGetSharedStore) {
|
|
115
|
+
stylexPlugin = p;
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
server.middlewares.stack.unshift({
|
|
120
|
+
route: "",
|
|
121
|
+
handle: (req, res, next) => {
|
|
122
|
+
if (!req.url?.startsWith(STYLEX_CSS_PATH)) {
|
|
123
|
+
return next();
|
|
124
|
+
}
|
|
125
|
+
if (!stylexPlugin) {
|
|
126
|
+
res.statusCode = 200;
|
|
127
|
+
res.setHeader("Content-Type", "text/css");
|
|
128
|
+
res.end("");
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const shared = stylexPlugin.__stylexGetSharedStore?.();
|
|
132
|
+
const rulesById = shared?.rulesById;
|
|
133
|
+
if (!rulesById || rulesById.size === 0) {
|
|
134
|
+
res.statusCode = 200;
|
|
135
|
+
res.setHeader("Content-Type", "text/css");
|
|
136
|
+
res.end("");
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const libraryRules = [];
|
|
140
|
+
const productRules = [];
|
|
141
|
+
for (const [filePath, rules] of rulesById.entries()) {
|
|
142
|
+
if (filePath.includes(libraryPattern)) {
|
|
143
|
+
libraryRules.push(...rules);
|
|
144
|
+
} else {
|
|
145
|
+
productRules.push(...rules);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
const libraryCss = libraryRules.length ? stylexBabelPlugin.processStylexRules(libraryRules, {
|
|
149
|
+
useLayers: true
|
|
150
|
+
}) : "";
|
|
151
|
+
const productCss = productRules.length ? stylexBabelPlugin.processStylexRules(productRules, {
|
|
152
|
+
useLayers: true
|
|
153
|
+
}) : "";
|
|
154
|
+
const parts = [];
|
|
155
|
+
if (libraryCss)
|
|
156
|
+
parts.push(`@layer ${libraryLayer} {
|
|
157
|
+
${libraryCss}
|
|
158
|
+
}`);
|
|
159
|
+
if (productCss)
|
|
160
|
+
parts.push(`@layer ${productLayer} {
|
|
161
|
+
${productCss}
|
|
162
|
+
}`);
|
|
163
|
+
res.statusCode = 200;
|
|
164
|
+
res.setHeader("Content-Type", "text/css");
|
|
165
|
+
res.setHeader("Cache-Control", "no-store");
|
|
166
|
+
res.end(parts.join("\n\n"));
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
return [configPlugin, layerOrderPlugin, basePlugin, splitLayerPlugin];
|
|
173
|
+
}
|
|
174
|
+
function xdsStylexLegacy(options) {
|
|
175
|
+
const {
|
|
176
|
+
stylexOptions,
|
|
177
|
+
libraryPattern = LIBRARY_PATTERN,
|
|
178
|
+
stylexPrefix = "astryx",
|
|
179
|
+
layers = {}
|
|
180
|
+
} = options;
|
|
181
|
+
const libraryLayer = layers.library ?? "astryx-base";
|
|
182
|
+
const productLayer = layers.product ?? "product";
|
|
183
|
+
const xdsBabelPlugin = path.resolve(__dirname, "../src/babel.js");
|
|
184
|
+
const existingPlugins = stylexOptions.babelConfig?.plugins ?? [];
|
|
185
|
+
const basePlugin = stylex.vite({
|
|
186
|
+
...stylexOptions,
|
|
187
|
+
useCSSLayers: true,
|
|
188
|
+
babelConfig: {
|
|
189
|
+
...stylexOptions.babelConfig,
|
|
190
|
+
plugins: [
|
|
191
|
+
[
|
|
192
|
+
xdsBabelPlugin,
|
|
193
|
+
{
|
|
194
|
+
...stylexOptions,
|
|
195
|
+
libraryPrefix: stylexPrefix,
|
|
196
|
+
babelConfig: void 0
|
|
197
|
+
}
|
|
198
|
+
],
|
|
199
|
+
...existingPlugins
|
|
200
|
+
]
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
const layerOrderPlugin = {
|
|
204
|
+
name: "xds-css-layer-order",
|
|
205
|
+
transformIndexHtml() {
|
|
206
|
+
return [
|
|
207
|
+
{
|
|
208
|
+
tag: "style",
|
|
209
|
+
children: `@layer reset, ${libraryLayer}, astryx-theme, ${productLayer};`,
|
|
210
|
+
injectTo: "head-prepend"
|
|
211
|
+
}
|
|
212
|
+
];
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
const splitLayerPlugin = {
|
|
216
|
+
name: "xds-split-layers",
|
|
217
|
+
configureServer(server) {
|
|
218
|
+
let stylexPlugin = null;
|
|
219
|
+
return () => {
|
|
220
|
+
for (const p of server.config.plugins.flat()) {
|
|
221
|
+
if (p?.__stylexGetSharedStore) {
|
|
222
|
+
stylexPlugin = p;
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
server.middlewares.stack.unshift({
|
|
227
|
+
route: "",
|
|
228
|
+
handle: (req, res, next) => {
|
|
229
|
+
if (!req.url?.startsWith(STYLEX_CSS_PATH)) {
|
|
230
|
+
return next();
|
|
231
|
+
}
|
|
232
|
+
if (!stylexPlugin) {
|
|
233
|
+
res.statusCode = 200;
|
|
234
|
+
res.setHeader("Content-Type", "text/css");
|
|
235
|
+
res.end("");
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
const shared = stylexPlugin.__stylexGetSharedStore?.();
|
|
239
|
+
const rulesById = shared?.rulesById;
|
|
240
|
+
if (!rulesById || rulesById.size === 0) {
|
|
241
|
+
res.statusCode = 200;
|
|
242
|
+
res.setHeader("Content-Type", "text/css");
|
|
243
|
+
res.end("");
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
const libraryRules = [];
|
|
247
|
+
const productRules = [];
|
|
248
|
+
for (const [filePath, rules] of rulesById.entries()) {
|
|
249
|
+
if (filePath.includes(libraryPattern)) {
|
|
250
|
+
libraryRules.push(...rules);
|
|
251
|
+
} else {
|
|
252
|
+
productRules.push(...rules);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
const libraryCss = libraryRules.length ? stylexBabelPlugin.processStylexRules(libraryRules, {
|
|
256
|
+
useLayers: true
|
|
257
|
+
}) : "";
|
|
258
|
+
const productCss = productRules.length ? stylexBabelPlugin.processStylexRules(productRules, {
|
|
259
|
+
useLayers: true
|
|
260
|
+
}) : "";
|
|
261
|
+
const parts = [];
|
|
262
|
+
if (libraryCss)
|
|
263
|
+
parts.push(`@layer ${libraryLayer} {
|
|
264
|
+
${libraryCss}
|
|
265
|
+
}`);
|
|
266
|
+
if (productCss)
|
|
267
|
+
parts.push(`@layer ${productLayer} {
|
|
268
|
+
${productCss}
|
|
269
|
+
}`);
|
|
270
|
+
res.statusCode = 200;
|
|
271
|
+
res.setHeader("Content-Type", "text/css");
|
|
272
|
+
res.setHeader("Cache-Control", "no-store");
|
|
273
|
+
res.end(parts.join("\n\n"));
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
return [layerOrderPlugin, basePlugin, splitLayerPlugin];
|
|
280
|
+
}
|
|
281
|
+
export {
|
|
282
|
+
LIGHTNINGCSS_TARGETS,
|
|
283
|
+
xdsStylex
|
|
284
|
+
};
|
package/package.json
CHANGED
|
@@ -1,11 +1,60 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astryxdesign/build",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "
|
|
5
|
-
"
|
|
3
|
+
"version": "0.0.15",
|
|
4
|
+
"description": "Build plugins for XDS source builds — babel, PostCSS, and Vite integrations",
|
|
5
|
+
"author": "Meta Open Source",
|
|
6
6
|
"license": "MIT",
|
|
7
|
+
"homepage": "https://github.com/facebook/astryx#readme",
|
|
7
8
|
"repository": {
|
|
8
9
|
"type": "git",
|
|
9
|
-
"url": "git+https://github.com/facebook/astryx.git"
|
|
10
|
+
"url": "git+https://github.com/facebook/astryx.git",
|
|
11
|
+
"directory": "packages/build"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/facebook/astryx/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"xds",
|
|
18
|
+
"postcss",
|
|
19
|
+
"stylex",
|
|
20
|
+
"css-layers",
|
|
21
|
+
"design-system"
|
|
22
|
+
],
|
|
23
|
+
"main": "./src/config.js",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": "./src/config.js",
|
|
26
|
+
"./babel": "./src/babel.js",
|
|
27
|
+
"./postcss": "./src/index.js",
|
|
28
|
+
"./vite": "./dist/vite.mjs",
|
|
29
|
+
"./next": "./src/next.js"
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"src",
|
|
33
|
+
"dist"
|
|
34
|
+
],
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"@stylexjs/babel-plugin": ">=0.18.0",
|
|
37
|
+
"@babel/core": ">=7.0.0",
|
|
38
|
+
"@stylexjs/unplugin": ">=0.18.0",
|
|
39
|
+
"vite": ">=5.0.0"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"fast-glob": "^3.3.0",
|
|
43
|
+
"glob-parent": "^6.0.0",
|
|
44
|
+
"is-glob": "^4.0.0"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"esbuild": "^0.28.1"
|
|
48
|
+
},
|
|
49
|
+
"peerDependenciesMeta": {
|
|
50
|
+
"@stylexjs/unplugin": {
|
|
51
|
+
"optional": true
|
|
52
|
+
},
|
|
53
|
+
"vite": {
|
|
54
|
+
"optional": true
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"scripts": {
|
|
58
|
+
"build": "node build.mjs"
|
|
10
59
|
}
|
|
11
|
-
}
|
|
60
|
+
}
|