@teacss/rsbuild 0.3.0
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 +22 -0
- package/README.md +47 -0
- package/dist/index.d.ts +118 -0
- package/dist/index.js +1 -0
- package/package.json +47 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021-PRESENT Anthony Fu <https://github.com/antfu>
|
|
4
|
+
Copyright (c) 2026-PRESENT Billgo <hi@billgo.me>
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# @teacss/rsbuild
|
|
2
|
+
|
|
3
|
+
**Rsbuild integration for TeaCSS.**
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
The plugin replaces `@teacss` in the configured CSS entry with generated
|
|
8
|
+
utilities and can optimize the result with `lightningcss`.
|
|
9
|
+
|
|
10
|
+
Use this package in Rsbuild applications that want TeaCSS generation,
|
|
11
|
+
dependency tracking, directive transforms, and CSS optimization in the Rsbuild
|
|
12
|
+
lifecycle. It is a native Rsbuild plugin and does not require the PostCSS
|
|
13
|
+
integration; non-Rsbuild projects should choose the adapter for their own build
|
|
14
|
+
tool.
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import { defineConfig } from "@rsbuild/core";
|
|
20
|
+
import { pluginTeacss } from "teacss/rsbuild";
|
|
21
|
+
|
|
22
|
+
export default defineConfig({
|
|
23
|
+
plugins: [pluginTeacss()],
|
|
24
|
+
});
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```css
|
|
28
|
+
@preset "standard";
|
|
29
|
+
@source "./src/**/*.{ts,tsx}";
|
|
30
|
+
@teacss;
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Positive `@source` globs register their stable base directories as Rsbuild
|
|
34
|
+
context dependencies. New files matching an include therefore trigger a
|
|
35
|
+
rebuild; negative source patterns are not registered as watch roots.
|
|
36
|
+
When directive transforms are enabled, their default CSS matcher is combined
|
|
37
|
+
with a custom entry `test`, so configured non-`.css` entries such as `.pcss`
|
|
38
|
+
still reach TeaCSS.
|
|
39
|
+
|
|
40
|
+
Low-level helpers such as `generate`, `transformCss`, and `optimize` are
|
|
41
|
+
exported for integration tests and advanced tooling.
|
|
42
|
+
|
|
43
|
+
## Status
|
|
44
|
+
|
|
45
|
+
Pre-1.0. Install `@teacss/rsbuild` beside `teacss`, then use the stable
|
|
46
|
+
`teacss/rsbuild` facade subpath in applications. Integration authors may import
|
|
47
|
+
`@teacss/rsbuild` directly when they intentionally do not use the facade.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { Minify, RsbuildPlugin } from "@rsbuild/core";
|
|
2
|
+
import { UserConfig } from "@teacss/core";
|
|
3
|
+
import { Targets } from "lightningcss";
|
|
4
|
+
//#region src/index.d.ts
|
|
5
|
+
declare const DEFAULT_TARGETS: Targets;
|
|
6
|
+
interface TeacssGenerateOptions {
|
|
7
|
+
/** Project root to scan + resolve config from. @default process.cwd() */
|
|
8
|
+
cwd?: string;
|
|
9
|
+
/** Path to the CSS entry, or a directory to discover it from. Ignored when `config` is given. */
|
|
10
|
+
configPath?: string;
|
|
11
|
+
/** Inline config — skips file loading (useful for tests / programmatic use). */
|
|
12
|
+
config?: UserConfig;
|
|
13
|
+
/** Inline source contents to extract utilities from — skips the filesystem scan. */
|
|
14
|
+
contents?: string[];
|
|
15
|
+
/** Globs ignored during the filesystem scan. */
|
|
16
|
+
ignore?: string[];
|
|
17
|
+
}
|
|
18
|
+
interface TeacssPluginOptions extends TeacssGenerateOptions {
|
|
19
|
+
/**
|
|
20
|
+
* Optimize the output with lightningcss (minify + vendor prefixing).
|
|
21
|
+
* `true`/`false` toggles it; `{ minify }` overrides just minification.
|
|
22
|
+
* @default optimize in production, skip in development.
|
|
23
|
+
*/
|
|
24
|
+
optimize?: boolean | {
|
|
25
|
+
minify?: boolean;
|
|
26
|
+
};
|
|
27
|
+
/** lightningcss targets override. @default derived from the environment's browserslist. */
|
|
28
|
+
targets?: Targets;
|
|
29
|
+
/** Which CSS entry carries the `@teacss` directive. @default /index\.css$/ */
|
|
30
|
+
test?: RegExp;
|
|
31
|
+
/**
|
|
32
|
+
* Inline `@apply` (plus `@screen` / `theme()` / `icon()`) in `.css` files —
|
|
33
|
+
* `@apply p:4 radius:2x;` inside a rule becomes the resolved declarations,
|
|
34
|
+
* conditioned tokens (`@apply p:4@hover`) become host-scoped rules. A lexical
|
|
35
|
+
* guard skips config and transformer setup for ordinary CSS. `false` disables
|
|
36
|
+
* it; `{ test }` narrows the scope (default: all CSS).
|
|
37
|
+
* @default enabled, scope = all `.css`
|
|
38
|
+
*/
|
|
39
|
+
apply?: boolean | {
|
|
40
|
+
test?: RegExp;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Scan content (or use inline `contents`) and generate the utilities used.
|
|
45
|
+
* Returns the raw layered CSS (preflight vars + utilities, no optimization),
|
|
46
|
+
* the match count, and the absolute paths scanned (for watch registration).
|
|
47
|
+
*/
|
|
48
|
+
declare function generate(options?: TeacssGenerateOptions): Promise<{
|
|
49
|
+
css: string;
|
|
50
|
+
utilities: number;
|
|
51
|
+
files: string[];
|
|
52
|
+
}>;
|
|
53
|
+
/** Build a `readSources` that scans `@source` include/exclude globs relative to the entry dir. */
|
|
54
|
+
declare function makeReadSources(base: string, ignore?: string[]): (includes: string[], excludes: string[]) => Promise<{
|
|
55
|
+
files: string[];
|
|
56
|
+
sources: string[];
|
|
57
|
+
}>;
|
|
58
|
+
interface GenerateEntryCssOptions {
|
|
59
|
+
/** Entry file directory — base for `@preset` relative specifiers and `@source` globs. */
|
|
60
|
+
base: string;
|
|
61
|
+
/** Read scanned content for include/exclude globs. Omit when `contents` is given. */
|
|
62
|
+
readSources?: (includes: string[], excludes: string[]) => Promise<{
|
|
63
|
+
files: string[];
|
|
64
|
+
sources: string[];
|
|
65
|
+
}>;
|
|
66
|
+
/** Inline content (tests / programmatic use) — skips `readSources`. */
|
|
67
|
+
contents?: string[];
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* The entry-CSS-driven build: parse the entry's directives, generate, and splice
|
|
71
|
+
* the layers back in (replace `@teacss`, strip consumed directives, hoist
|
|
72
|
+
* `@import`). Returns the final (unoptimized) CSS, the scanned files, and the
|
|
73
|
+
* utility count. Optimization (lightningcss) is the caller's step.
|
|
74
|
+
*/
|
|
75
|
+
declare function generateEntryCss(entryCss: string, options: GenerateEntryCssOptions): Promise<{
|
|
76
|
+
css: string;
|
|
77
|
+
files: string[];
|
|
78
|
+
matched: number;
|
|
79
|
+
unknown: string[];
|
|
80
|
+
hasPreset: boolean;
|
|
81
|
+
}>;
|
|
82
|
+
/**
|
|
83
|
+
* Optimize CSS with lightningcss: minify + vendor prefixing. Targets come from
|
|
84
|
+
* `targets`, else the given `browserslist`, else a sensible default. `errorRecovery`
|
|
85
|
+
* skips any single malformed rule instead of failing the build.
|
|
86
|
+
*/
|
|
87
|
+
declare function optimize(css: string, { minify, targets, browserslist }?: {
|
|
88
|
+
minify?: boolean;
|
|
89
|
+
targets?: Targets;
|
|
90
|
+
browserslist?: string[];
|
|
91
|
+
}): Promise<{
|
|
92
|
+
css: string;
|
|
93
|
+
skipped: number;
|
|
94
|
+
}>;
|
|
95
|
+
/** Whether to minify, from Rsbuild's `output.minify` config + build mode. */
|
|
96
|
+
declare function resolveMinify(minify: Minify | undefined, isProd: boolean): boolean;
|
|
97
|
+
/**
|
|
98
|
+
* Inline `@apply` (+ `@screen` / `theme()` / `icon()`) in a CSS string, resolving
|
|
99
|
+
* tokens against the config (inline `config`, or discovered from `cwd`/`configPath`).
|
|
100
|
+
* The programmatic form of the plugin's per-`.css` pass; fast-bails to a
|
|
101
|
+
* byte-identical string when the input has none of those directives.
|
|
102
|
+
*/
|
|
103
|
+
declare function transformCss(code: string, options?: TeacssGenerateOptions, id?: string): Promise<string>;
|
|
104
|
+
/**
|
|
105
|
+
* Rsbuild plugin: replace the `@teacss` directive in a CSS entry with generated
|
|
106
|
+
* utilities, optimized with lightningcss, and inline `@apply` in any `.css`.
|
|
107
|
+
* PostCSS-free.
|
|
108
|
+
*
|
|
109
|
+
* - Optimizes (minify + prefix) in production, skips it in development for fast
|
|
110
|
+
* rebuilds — overridable via `optimize`.
|
|
111
|
+
* - Registers scanned files as build dependencies, so editing content re-runs
|
|
112
|
+
* generation in watch/dev mode.
|
|
113
|
+
* - `@apply` (+ `@screen`/`theme()`/`icon()`) is inlined in every `.css`
|
|
114
|
+
* (fast-bailed), configurable via `apply`.
|
|
115
|
+
*/
|
|
116
|
+
declare function pluginTeacss(options?: TeacssPluginOptions): RsbuildPlugin;
|
|
117
|
+
//#endregion
|
|
118
|
+
export { DEFAULT_TARGETS, GenerateEntryCssOptions, TeacssGenerateOptions, TeacssPluginOptions, generate, generateEntryCss, makeReadSources, optimize, pluginTeacss, resolveMinify, transformCss };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createRequire as e}from"node:module";import{statSync as t}from"node:fs";import{dirname as n,isAbsolute as r,resolve as i}from"node:path";import a from"node:process";import{DEFAULT_SOURCE_IGNORE as o,generateSources as s,readSourceFile as c}from"@teacss/runtime/source-generation";const l=/\.(css|postcss|sass|scss|less|stylus|styl)(\?|$)/,u=(e,t=0)=>e<<16|t<<8,d={safari:u(14),chrome:u(90),firefox:u(88),edge:u(90)};function f(e,t){e.lastIndex=0;let n=e.test(t);return e.lastIndex=0,n}function p(e){return e.includes(`@apply`)||e.includes(`--at-apply`)||e.includes(`@screen`)||e.includes(`theme(`)||e.includes(`icon(`)}function m(e,n,r,i){let a=t(e,{throwIfNoEntry:!1});a?a.isDirectory()?i(e):n(e):r(e)}const h=/[*?[\]{}()]/;function ee(e,t){let r=t;for(;h.test(r);)r=n(r);return i(e,r)}async function g(e,t,n){let{glob:r}=await import(`tinyglobby`),i=await r(t,{cwd:e,absolute:!0,ignore:n});return{files:i,sources:i.map(c)}}async function _(e={}){let[{defaultFilesystemGlobs:t},n]=await Promise.all([import(`@teacss/runtime`),O(e)]);return v(e,n,t)}async function v(e,t,n){let{cwd:r=a.cwd(),contents:i,ignore:c=o}=e,l=n??(await import(`@teacss/runtime`)).defaultFilesystemGlobs,u=t.config.content?.filesystem??l,{files:d,sources:f}=i?{files:[],sources:i}:await g(r,u,c),p=await s(t,d,f);return{css:p.getLayers()||``,utilities:p.matched.size,files:d}}function y(e,t=o){return async(n,r)=>{let{glob:i}=await import(`tinyglobby`),a=await i(n,{cwd:e,absolute:!0,ignore:[...r,...t]});return{files:a,sources:await Promise.all(a.map(c))}}}const b={articles:`@teacss/preset-articles`,icons:`@teacss/preset-icons`,standard:`@teacss/preset-standard`};function x(t,n){try{return n.resolve(t)}catch(r){let i;try{i=n.resolve(`teacss/package.json`)}catch{throw r}return e(i).resolve(t)}}function te(e){return e.filter(e=>!e.startsWith(`.`)&&!r(e))}function ne(t,n){let r=e(i(n,`_`));return t.map(e=>{let t=Object.hasOwn(b,e)?b[e]:void 0;return t?x(t,r):r.resolve(e)})}function re(e,t){return e.length===t.length&&e.every((e,n)=>e===t[n])}async function S(e,t){return C(e,t,await A(e,t.base))}async function C(e,t,n){let[{parseEntry:r},{spliceEntry:i}]=await Promise.all([import(`@teacss/config`),import(`@teacss/directives`)]),a=r(e),o=a.sources.filter(e=>!e.exclude).map(e=>e.glob),c=a.sources.filter(e=>e.exclude).map(e=>e.glob),{files:l,sources:u}=t.contents?{files:[],sources:t.contents}:t.readSources?await t.readSources(o,c):{files:[],sources:[]},d=await s(n.generator,l,u);return{css:i(e,d.getLayers()||``),files:l,matched:d.matched.size,unknown:n.unknown,hasPreset:n.hasPreset}}async function w(e,{minify:t=!0,targets:n,browserslist:r}={}){let{transform:i,browserslistToTargets:a}=await import(`lightningcss`),o=n??(r?.length?a(r):d),s=E(e),c=i({filename:`teacss.css`,code:Buffer.from(s.css),minify:t,errorRecovery:!0,targets:o});return{css:s.restore(c.code.toString()),skipped:c.warnings?.length??0}}const T=/(^|[;{])((?:\s|\/\*[\s\S]*?\*\/)*)all((?:\s|\/\*[\s\S]*?\*\/)*):((?:\s|\/\*[\s\S]*?\*\/)*)(?=(?:var|env)\()/gi;function E(e){let t=`--teacss-optimized-all`;for(;e.includes(t);)t+=`-x`;return{css:e.replace(T,(e,n,r,i,a)=>`${n}${r}${t}${i}:${a}`),restore:e=>e.replaceAll(t,`all`)}}function D(e,t){return typeof e==`boolean`||e==null?(e??!0)&&t:e.css!==!1&&(e.css===`always`||t)}async function O(e){return(await k(e)).generator}async function k(e,t){let{cwd:n=a.cwd(),configPath:r,config:i}=e,{createGenerator:o}=await import(`@teacss/core`),s=t??(await import(`@teacss/config`)).createRecoveryConfigLoader(),c=i?{config:i,sources:[]}:await s(n,r);return{generator:await o(c.config),sources:c.sources}}async function A(e,t){let[{resolveEntryConfig:n},{createGenerator:r}]=await Promise.all([import(`@teacss/config`),import(`@teacss/core`)]),{config:i,sources:a,unknown:o}=await n(e,t);return{generator:await r(i),sources:a,unknown:o,hasPreset:!!i.presets?.length}}async function j(e,t,n){let[{transformDirectives:r},{default:i}]=await Promise.all([import(`@teacss/directives`),import(`magic-string`)]),a=new i(e);return await r(a,n,{},t),a.toString()}async function M(e,t={},n){return p(e)?j(e,n,await O(t)):e}function N(e={}){let{optimize:r,targets:o,test:s=/index\.css$/,apply:c,...u}=e,d=c!==!1,h=typeof c==`object`&&c.test||l;return{name:`teacss`,setup(e){let c,g=()=>c??=import(`@teacss/config`).then(({createRecoveryConfigLoader:e})=>e()),_=new Map,b=new Map,x=new Map,S=e=>{let t=_.get(e);if(t)return t;let n=g().then(e=>k(u,e));return _.set(e,n),n};e.onBeforeEnvironmentCompile(({environment:e})=>{_.delete(e.name),b.delete(e.name)}),e.transform({test:d?[l,s]:s},async({code:c,environment:l,addDependency:g,addMissingDependency:T,addContextDependency:E,resourcePath:O})=>{let k=O||``,M=f(s,k),N=d&&p(c),P=N&&f(h,k);if(!M&&!P)return c;let{parseEntry:ie}=await import(`@teacss/config`),F=M?ie(c):void 0,I=F?.hasTeacss===!0;if(!I&&!P)return c;let L=!!(F&&(F.presets.length>0||F.sources.length>0||F.custom.length>0)),R=n(O||`${u.cwd??a.cwd()}/index.css`),z=O||i(R,`index.css`);for(let e of F?.sources??[])e.exclude||m(ee(R,e.glob),g,T,E);let B=te(F?.presets??[]),V,H,U;I&&(L?(V=A(c,R).then(e=>(H={...e,sources:Array.from(new Set([z,...e.sources]))},H)).catch(async t=>{let{getConfigSourcesFromError:n}=await import(`@teacss/config`),r=n(t);for(let e of r)m(e,g,T,E);let i=x.get(l.name);if(!i||i.id!==z)throw t;let a=Array.from(new Set([...i.state.sources,...r]));return e.logger.warn(`@teacss/rsbuild: keeping the last valid config for ${z} while its preset graph is invalid`),a.length===i.state.sources.length?i.state:{...i.state,sources:a}}),b.set(l.name,V),d?_.set(l.name,V):_.delete(l.name)):(_.delete(l.name),b.delete(l.name),x.delete(l.name)));let W=()=>{H&&U&&V&&b.get(l.name)===V&&x.set(l.name,{id:z,packagePresetDependencies:U,packagePresetSpecifiers:B,state:H})},G=c,K;if(N&&(I||P)){try{K=await S(l.name)}catch(e){if(!V){let{getConfigSourcesFromError:t}=await import(`@teacss/config`);for(let n of t(e))m(n,g,T,E)}throw e}for(let e of K.sources)m(e,g,T,E);G=await j(c,k,K.generator)}if(!I)return G===c?c:{code:G};let q,J,Y,X=[],Z=!0,Q=[];if(L){let n=V?await V:await A(G,R);({css:q,files:Y,matched:J,unknown:X,hasPreset:Z}=await C(G,{base:R,readSources:y(R,u.ignore)},n));try{U=ne(B,R)}catch(n){let r=x.get(l.name);if(!(r?.id===z&&re(r.packagePresetSpecifiers,B)&&r.packagePresetDependencies.some(e=>!t(e,{throwIfNoEntry:!1}))))throw n;U=r.packagePresetDependencies,e.logger.warn(`@teacss/rsbuild: keeping the last valid package preset dependencies for ${z} while package entries are unavailable`)}Q=Array.from(new Set([...U,...n.sources]))}else{K??=await S(l.name);let e=await v(u,K.generator),{spliceEntry:t}=await import(`@teacss/directives`);q=t(G,e.css),J=e.utilities,Y=e.files,Q=K.sources}Z||e.logger.warn(`@teacss/rsbuild: ${O||`entry`} declares no @preset — no utilities generated. Add one, e.g. \`@preset "standard";\``),X.length&&e.logger.warn(`@teacss/rsbuild: ${X.length} @custom var(s) not registered (unknown namespace / illegal color step): ${X.join(`, `)}`);for(let e of Y)g(e);for(let e of Q)m(e,g,T,E);let $=(l.config.mode??a.env.NODE_ENV)===`production`;if(!(r??$))return e.logger.info(`@teacss/rsbuild: ${J} utilities (dev, unoptimized) → ${(q.length/1024).toFixed(1)}KB`),W(),{code:q};let ae=typeof r==`object`&&r.minify!==void 0?r.minify:D(l.config.output.minify,$),{css:oe,skipped:se}=await w(q,{minify:ae,targets:o,browserslist:l.browserslist});return e.logger.info(`@teacss/rsbuild: ${J} utilities${se?`, ${se} skipped`:``} → ${(oe.length/1024).toFixed(1)}KB`),W(),{code:oe}})}}}export{d as DEFAULT_TARGETS,_ as generate,S as generateEntryCss,y as makeReadSources,w as optimize,N as pluginTeacss,D as resolveMinify,M as transformCss};
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@teacss/rsbuild",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Rsbuild integration for TeaCSS — generate utilities and optimize with lightningcss, no PostCSS.",
|
|
5
|
+
"homepage": "https://css.teasim.com",
|
|
6
|
+
"funding": "https://github.com/sponsors/billgo",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"author": "Billgo <hi@billgo.me>",
|
|
9
|
+
"sideEffects": false,
|
|
10
|
+
"type": "module",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": "./dist/index.js",
|
|
13
|
+
"./package.json": "./package.json"
|
|
14
|
+
},
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"README.md"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "bunx tsdown --config tsdown.config.mts",
|
|
22
|
+
"dev": "tsdown --watch"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@teacss/config": "0.3.0",
|
|
26
|
+
"@teacss/core": "0.3.0",
|
|
27
|
+
"@teacss/directives": "0.3.0",
|
|
28
|
+
"@teacss/runtime": "0.3.0",
|
|
29
|
+
"lightningcss": "^1.33.0",
|
|
30
|
+
"magic-string": "^1.1.0",
|
|
31
|
+
"tinyglobby": "^0.2.17"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@rsbuild/core": "^2.1.8",
|
|
35
|
+
"@teacss/preset-articles": "0.3.0",
|
|
36
|
+
"@teacss/preset-standard": "0.3.0"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"@rsbuild/core": "^2"
|
|
40
|
+
},
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=22.12.0"
|
|
43
|
+
},
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"access": "public"
|
|
46
|
+
}
|
|
47
|
+
}
|