@teacss/rsbuild 0.4.7 → 0.5.1

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/README.md CHANGED
@@ -1,19 +1,6 @@
1
1
  # @teacss/rsbuild
2
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
3
+ Native Rsbuild integration for TeaCSS.
17
4
 
18
5
  ```ts
19
6
  import { defineConfig } from "@rsbuild/core";
@@ -30,19 +17,30 @@ export default defineConfig({
30
17
  @teacss;
31
18
  ```
32
19
 
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
- Default source discovery skips dependency and common build-output directories,
37
- while explicit `@source` globs can include them.
38
- When directive transforms are enabled, their default CSS matcher is combined
39
- with a custom entry `test`, so configured non-`.css` entries such as `.pcss`
40
- still reach TeaCSS.
41
-
42
- Low-level helpers such as `generate`, `transformCss`, and `optimize` are
43
- exported for integration tests and advanced tooling.
44
-
45
- ## Status
46
-
47
- Pre-1.0. `@teacss/rsbuild` is the owning Rsbuild adapter. Applications install
48
- it beside the `teacss` runtime and import it directly from `@teacss/rsbuild`.
20
+ The plugin generates utilities, transforms TeaCSS directives, tracks positive
21
+ `@source` roots, and can optimize output with Lightning CSS. Stable source
22
+ roots let new matching files trigger rebuilds; negative patterns are not watch
23
+ roots. Explicit sources may include directories skipped by default discovery.
24
+ The resolved source graph includes directives from unconditional local CSS
25
+ imports, with paths relative to the declaring file. Entries without `@source`
26
+ use default discovery, excluding dependencies and build output. The `contents`
27
+ option replaces content scanning even when the entry declares its own preset;
28
+ an empty array scans no content.
29
+
30
+ An entry may keep all its configuration in imported CSS. Its utilities and
31
+ `@apply` share that resolved configuration. Ordinary CSS imports preserve
32
+ programmatic configuration, and imported safelists augment it.
33
+
34
+ A custom entry `test` is combined with the directive transform matcher, so
35
+ entries such as `.pcss` still reach TeaCSS.
36
+
37
+ Advanced tooling may use the exported `generate`, `transformCss`, and
38
+ `optimize` helpers.
39
+
40
+ The optimizer preserves native `:dir()` selectors. The plugin also excludes
41
+ their language-based rewrite in Rsbuild's CSS loader and inherited minimizer
42
+ defaults, so explicit and nested `dir` values stay correct. Other browser
43
+ targets and transformations are unchanged; directional styles require native
44
+ `:dir()` support. Custom host CSS options must preserve this exclusion.
45
+
46
+ Pre-1.0. No PostCSS plugin is required beside this adapter.
package/dist/index.d.ts CHANGED
@@ -2,8 +2,8 @@ import { Minify, RsbuildPlugin } from "@rsbuild/core";
2
2
  import { UserConfig } from "@teacss/core";
3
3
  import { Targets } from "lightningcss";
4
4
  //#region src/index.d.ts
5
- declare const DEFAULT_TARGETS: Targets;
6
- interface TeacssGenerateOptions {
5
+ export declare const DEFAULT_TARGETS: Targets;
6
+ export interface TeacssGenerateOptions {
7
7
  /** Project root to scan + resolve config from. @default process.cwd() */
8
8
  cwd?: string;
9
9
  /** Path to the CSS entry, or a directory to discover it from. Ignored when `config` is given. */
@@ -15,7 +15,7 @@ interface TeacssGenerateOptions {
15
15
  /** Globs ignored during the filesystem scan. */
16
16
  ignore?: string[];
17
17
  }
18
- interface TeacssPluginOptions extends TeacssGenerateOptions {
18
+ export interface TeacssPluginOptions extends TeacssGenerateOptions {
19
19
  /**
20
20
  * Optimize the output with lightningcss (minify + vendor prefixing).
21
21
  * `true`/`false` toggles it; `{ minify }` overrides just minification.
@@ -45,17 +45,17 @@ interface TeacssPluginOptions extends TeacssGenerateOptions {
45
45
  * Returns the raw layered CSS (preflight vars + utilities, no optimization),
46
46
  * the match count, and the absolute paths scanned (for watch registration).
47
47
  */
48
- declare function generate(options?: TeacssGenerateOptions): Promise<{
48
+ export declare function generate(options?: TeacssGenerateOptions): Promise<{
49
49
  css: string;
50
50
  utilities: number;
51
51
  files: string[];
52
52
  }>;
53
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<{
54
+ export declare function makeReadSources(base: string, ignore?: string[]): (includes: string[], excludes: string[]) => Promise<{
55
55
  files: string[];
56
56
  sources: string[];
57
57
  }>;
58
- interface GenerateEntryCssOptions {
58
+ export interface GenerateEntryCssOptions {
59
59
  /** Entry file directory — base for `@preset` relative specifiers and `@source` globs. */
60
60
  base: string;
61
61
  /** Entry filename, when known, so local `@import` cycles include the root identity. */
@@ -74,7 +74,7 @@ interface GenerateEntryCssOptions {
74
74
  * `@import`). Returns the final (unoptimized) CSS, the scanned files, and the
75
75
  * utility count. Optimization (lightningcss) is the caller's step.
76
76
  */
77
- declare function generateEntryCss(entryCss: string, options: GenerateEntryCssOptions): Promise<{
77
+ export declare function generateEntryCss(entryCss: string, options: GenerateEntryCssOptions): Promise<{
78
78
  css: string;
79
79
  files: string[];
80
80
  matched: number;
@@ -87,7 +87,7 @@ declare function generateEntryCss(entryCss: string, options: GenerateEntryCssOpt
87
87
  * `targets`, else the given `browserslist`, else a sensible default. `errorRecovery`
88
88
  * skips any single malformed rule instead of failing the build.
89
89
  */
90
- declare function optimize(css: string, { minify, targets, browserslist }?: {
90
+ export declare function optimize(css: string, { minify, targets, browserslist }?: {
91
91
  minify?: boolean;
92
92
  targets?: Targets;
93
93
  browserslist?: string[];
@@ -96,14 +96,14 @@ declare function optimize(css: string, { minify, targets, browserslist }?: {
96
96
  skipped: number;
97
97
  }>;
98
98
  /** Whether to minify, from Rsbuild's `output.minify` config + build mode. */
99
- declare function resolveMinify(minify: Minify | undefined, isProd: boolean): boolean;
99
+ export declare function resolveMinify(minify: Minify | undefined, isProd: boolean): boolean;
100
100
  /**
101
101
  * Inline `@apply` (+ `@screen` / `theme()` / `icon()`) in a CSS string, resolving
102
102
  * tokens against the config (inline `config`, or discovered from `cwd`/`configPath`).
103
103
  * The programmatic form of the plugin's per-`.css` pass; fast-bails to a
104
104
  * byte-identical string when the input has none of those directives.
105
105
  */
106
- declare function transformCss(code: string, options?: TeacssGenerateOptions, id?: string): Promise<string>;
106
+ export declare function transformCss(code: string, options?: TeacssGenerateOptions, id?: string): Promise<string>;
107
107
  /**
108
108
  * Rsbuild plugin: replace the `@teacss` directive in a CSS entry with generated
109
109
  * utilities, optimized with lightningcss, and inline `@apply` in any `.css`.
@@ -116,6 +116,5 @@ declare function transformCss(code: string, options?: TeacssGenerateOptions, id?
116
116
  * - `@apply` (+ `@screen`/`theme()`/`icon()`) is inlined in every `.css`
117
117
  * (fast-bailed), configurable via `apply`.
118
118
  */
119
- declare function pluginTeacss(options?: TeacssPluginOptions): RsbuildPlugin;
120
- //#endregion
121
- export { DEFAULT_TARGETS, GenerateEntryCssOptions, TeacssGenerateOptions, TeacssPluginOptions, generate, generateEntryCss, makeReadSources, optimize, pluginTeacss, resolveMinify, transformCss };
119
+ export declare function pluginTeacss(options?: TeacssPluginOptions): RsbuildPlugin;
120
+ //#endregion
package/dist/index.js CHANGED
@@ -1 +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`),k(e)]);return v(e,n.generator,t,n.sources)}async function v(e,t,r,i=[]){let{cwd:c=a.cwd(),contents:l}=e,u=r??(await import(`@teacss/runtime`)).defaultFilesystemGlobs,d=i[0]?n(i[0]):c,f=t.config.content?.filesystem,p=f??u,m=e.ignore??(f===void 0?o:[]),{files:h,sources:ee}=l?{files:[],sources:l}:await g(d,p,m),_=await s(t,h,ee);return{css:_.getLayers()||``,utilities:_.matched.size,files:h}}function y(e,t=[]){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,t.entryFile))}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,undeclared:n.undeclared,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,n=[]){let{cwd:r=a.cwd(),configPath:i,config:o}=e,{createGenerator:s}=await import(`@teacss/core`),c=t??(await import(`@teacss/config`)).createRecoveryConfigLoader(),l=o?{config:o,sources:[]}:await c(r,i);return{generator:await s(n.length?{...l.config,safelist:[...l.config.safelist??[],...n]}:l.config),sources:l.sources}}async function A(e,t,n){let[{resolveEntryConfig:r},{createGenerator:i}]=await Promise.all([import(`@teacss/config`),import(`@teacss/core`)]),{config:a,sources:o,unknown:s,undeclared:c}=await r(e,t,n);return{generator:await i(a),sources:o,unknown:s,undeclared:c,hasPreset:!!a.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:T,addMissingDependency:E,addContextDependency:O,resourcePath:M})=>{let N=M||``,ie=f(s,N),P=d&&p(c),F=P&&f(h,N);if(!ie&&!F)return c;let{parseEntry:ae}=await import(`@teacss/config`),I=ie?ae(c):void 0,L=I?.hasTeacss===!0;if(!L&&!F)return c;let R=!!(I&&(I.presets.length>0||I.sources.length>0||I.custom.length>0||I.shortcuts.length>0)),z=n(M||`${u.cwd??a.cwd()}/index.css`),B=M||i(z,`index.css`);for(let e of I?.sources??[])e.exclude||m(ee(z,e.glob),T,E,O);let V=te(I?.presets??[]),H,U,W;if(L)if(R)H=A(c,z,B).then(e=>(U={...e,sources:Array.from(new Set([B,...e.sources]))},U)).catch(async t=>{let{getConfigSourcesFromError:n}=await import(`@teacss/config`),r=n(t);for(let e of r)m(e,T,E,O);let i=x.get(l.name);if(!i||i.id!==B)throw t;let a=Array.from(new Set([...i.state.sources,...r]));return e.logger.warn(`@teacss/rsbuild: keeping the last valid config for ${B} while its preset graph is invalid`),a.length===i.state.sources.length?i.state:{...i.state,sources:a}}),b.set(l.name,H),d?_.set(l.name,H):_.delete(l.name);else if(I.safelist.length>0){let{expandClassGroups:e,splitClassTokens:t}=await import(`@teacss/core`),n=I.safelist.flatMap(n=>t(e(n))),r=g().then(e=>k(u,e,n));_.set(l.name,r),b.delete(l.name),x.delete(l.name)}else _.delete(l.name),b.delete(l.name),x.delete(l.name);let G=()=>{U&&W&&H&&b.get(l.name)===H&&x.set(l.name,{id:B,packagePresetDependencies:W,packagePresetSpecifiers:V,state:U})},K=c,q;if(P&&(L||F)){try{q=await S(l.name)}catch(e){if(!H){let{getConfigSourcesFromError:t}=await import(`@teacss/config`);for(let n of t(e))m(n,T,E,O)}throw e}for(let e of q.sources)m(e,T,E,O);K=await j(c,N,q.generator)}if(!L)return K===c?c:{code:K};let J,Y,X,Z=[],Q=[],oe=!0,$=[];if(R){let n=H?await H:await A(K,z,B);({css:J,files:X,matched:Y,unknown:Z,undeclared:Q,hasPreset:oe}=await C(K,{base:z,readSources:y(z,u.ignore)},n));try{W=ne(V,z)}catch(n){let r=x.get(l.name);if(!(r?.id===B&&re(r.packagePresetSpecifiers,V)&&r.packagePresetDependencies.some(e=>!t(e,{throwIfNoEntry:!1}))))throw n;W=r.packagePresetDependencies,e.logger.warn(`@teacss/rsbuild: keeping the last valid package preset dependencies for ${B} while package entries are unavailable`)}$=Array.from(new Set([...W,...n.sources]))}else{q??=await S(l.name);let e=await v(u,q.generator,void 0,q.sources),{spliceEntry:t}=await import(`@teacss/directives`);J=t(K,e.css),Y=e.utilities,X=e.files,$=q.sources}oe||e.logger.warn(`@teacss/rsbuild: ${M||`entry`} declares no @preset — no utilities generated. Add one, e.g. \`@preset "standard";\``),Z.length&&e.logger.warn(`@teacss/rsbuild: ${Z.length} @custom var(s) not registered (unknown namespace / illegal color step): ${Z.join(`, `)}`),Q.length&&e.logger.warn(`@teacss/rsbuild: ${Q.length} @custom theme var(s) not registered (no declared base value): ${Q.join(`, `)}`);for(let e of X)T(e);for(let e of $)m(e,T,E,O);let se=(l.config.mode??a.env.NODE_ENV)===`production`;if(!(r??se))return e.logger.info(`@teacss/rsbuild: ${Y} utilities (dev, unoptimized) → ${(J.length/1024).toFixed(1)}KB`),G(),{code:J};let ce=typeof r==`object`&&r.minify!==void 0?r.minify:D(l.config.output.minify,se),{css:le,skipped:ue}=await w(J,{minify:ce,targets:o,browserslist:l.browserslist});return e.logger.info(`@teacss/rsbuild: ${Y} utilities${ue?`, ${ue} skipped`:``} → ${(le.length/1024).toFixed(1)}KB`),G(),{code:le}})}}}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};
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 g(e,t){let r=t;for(;h.test(r);)r=n(r);return i(e,r)}async function _(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 v(e={}){let[{defaultFilesystemGlobs:t},n]=await Promise.all([import(`@teacss/runtime`),k(e)]);return y(e,n.generator,t,n.sources)}async function y(e,t,r,i=[]){let{cwd:c=a.cwd(),contents:l}=e,u=r??(await import(`@teacss/runtime`)).defaultFilesystemGlobs,d=i[0]?n(i[0]):c,f=t.config.content?.filesystem,p=f??u,m=e.ignore??(f===void 0?o:[]),{files:h,sources:g}=l?{files:[],sources:l}:await _(d,p,m),v=await s(t,h,g);return{css:v.getLayers()||``,utilities:v.matched.size,files:h}}function ee(e,t=[]){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={icons:`@teacss/preset-icons`,official:`@teacss/preset-official`,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 w(e,t,await A(e,t.base,t.entryFile))}async function C(e){let t=e.config.content?.filesystem,n=t??(await import(`@teacss/runtime`)).defaultFilesystemGlobs;return{includes:n.filter(e=>!e.startsWith(`!`)),excludes:[...n.filter(e=>e.startsWith(`!`)).map(e=>e.slice(1)),...t===void 0?o:[]]}}async function w(e,t,n){let{spliceEntry:r}=await import(`@teacss/directives`),{includes:i,excludes:a}=await C(n.generator),{files:o,sources:c}=t.contents?{files:[],sources:t.contents}:t.readSources?await t.readSources(i,a):{files:[],sources:[]},l=await s(n.generator,o,c);return{css:r(e,l.getLayers()||``),files:o,matched:l.matched.size,unknown:n.unknown,undeclared:n.undeclared,hasPreset:n.hasPreset}}async function T(e,{minify:t=!0,targets:n,browserslist:r}={}){let{transform:i,browserslistToTargets:a,Features:o}=await import(`lightningcss`),s=n??(r?.length?a(r):d),c=D(e),l=i({filename:`teacss.css`,code:Buffer.from(c.css),minify:t,errorRecovery:!0,targets:s,exclude:o.DirSelector});return{css:c.restore(l.code.toString()),skipped:l.warnings?.length??0}}const E=/(^|[;{])((?:\s|\/\*[\s\S]*?\*\/)*)all((?:\s|\/\*[\s\S]*?\*\/)*):((?:\s|\/\*[\s\S]*?\*\/)*)(?=(?:var|env)\()/gi;function D(e){let t=`--teacss-optimized-all`;for(;e.includes(t);)t+=`-x`;return{css:e.replace(E,(e,n,r,i,a)=>`${n}${r}${t}${i}:${a}`),restore:e=>e.replaceAll(t,`all`)}}function ie(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,n=[]){let{cwd:r=a.cwd(),configPath:i,config:o}=e,{createGenerator:s}=await import(`@teacss/core`),c=t??(await import(`@teacss/config`)).createRecoveryConfigLoader(),l=o?{config:o,sources:[]}:await c(r,i);return{generator:await s(n.length?{...l.config,safelist:[...l.config.safelist??[],...n]}:l.config),sources:l.sources}}async function A(e,t,n){let[{resolveEntryConfig:r},{createGenerator:i}]=await Promise.all([import(`@teacss/config`),import(`@teacss/core`)]),{config:a,sources:o,unknown:s,undeclared:c}=await r(e,t,n);return{generator:await i(a),sources:o,unknown:s,undeclared:c,hasPreset:!!a.presets?.length,hasEntryConfig:!!(a.presets?.length||a.content||a.shortcuts||Object.keys(a.theme??{}).length||s.length||c.length),safelist:(a.safelist??[]).filter(e=>typeof e==`string`)}}async function ae(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 j(e,t={},n){return p(e)?ae(e,n,await O(t)):e}function M(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){e.modifyRsbuildConfig((e,{mergeRsbuildConfig:t})=>t({tools:{lightningcssLoader:{exclude:{dirSelector:!0}}}},e));let c,_=()=>c??=import(`@teacss/config`).then(({createRecoveryConfigLoader:e})=>e()),v=new Map,b=new Map,x=new Map,S=e=>{let t=v.get(e);if(t)return t;let n=_().then(e=>k(u,e));return v.set(e,n),n};e.onBeforeEnvironmentCompile(({environment:e})=>{v.delete(e.name),b.delete(e.name)}),e.transform({test:d?[l,s]:s},async({code:c,environment:l,addDependency:E,addMissingDependency:D,addContextDependency:O,resourcePath:j})=>{let M=j||``,N=f(s,M),P=d&&p(c),F=P&&f(h,M);if(!N&&!F)return c;let{parseEntry:oe,scanTopLevelAtRules:se}=await import(`@teacss/config`),I=N?oe(c):void 0,L=I?.hasTeacss===!0;if(!L&&!F)return c;let R=!!(I&&(I.presets.length>0||I.sources.length>0||I.custom.length>0||I.shortcuts.length>0)),ce=L&&se(c).some(e=>e.name===`import`&&e.terminator===`;`),z=R||ce,B=n(j||`${u.cwd??a.cwd()}/index.css`),V=j||i(B,`index.css`);for(let e of I?.sources??[])e.exclude||m(g(B,e.glob),E,D,O);let H=te(I?.presets??[]),U,W,G;if(L){if(z)U=A(c,B,V).then(async e=>{if(!R&&!e.hasEntryConfig){let t=await k(u,await _(),e.safelist);e={...e,generator:t.generator,sources:[...e.sources,...t.sources],hasPreset:!!t.generator.config.presets.length,scanBase:t.sources[0]?n(t.sources[0]):u.cwd??a.cwd()}}return W={...e,sources:Array.from(new Set([V,...e.sources]))},W}).catch(async t=>{let{getConfigSourcesFromError:n}=await import(`@teacss/config`),r=n(t);for(let e of r)m(e,E,D,O);let i=x.get(l.name);if(!i||i.id!==V)throw t;let a=Array.from(new Set([...i.state.sources,...r]));return e.logger.warn(`@teacss/rsbuild: keeping the last valid config for ${V} while its preset graph is invalid`),a.length===i.state.sources.length?i.state:{...i.state,sources:a}}),b.set(l.name,U),d?v.set(l.name,U):v.delete(l.name);else if(I.safelist.length>0){let{expandClassGroups:e,splitClassTokens:t}=await import(`@teacss/core`),n=I.safelist.flatMap(n=>t(e(n))),r=_().then(e=>k(u,e,n));v.set(l.name,r),b.delete(l.name),x.delete(l.name)}else v.delete(l.name),b.delete(l.name),x.delete(l.name)}let le=()=>{W&&G&&U&&b.get(l.name)===U&&x.set(l.name,{id:V,packagePresetDependencies:G,packagePresetSpecifiers:H,state:W})},K=c,q;if(P&&(L||F)){try{q=await S(l.name)}catch(e){if(!U){let{getConfigSourcesFromError:t}=await import(`@teacss/config`);for(let n of t(e))m(n,E,D,O)}throw e}for(let e of q.sources)m(e,E,D,O);K=await ae(c,M,q.generator)}if(!L)return K===c?c:{code:K};let J,Y,X,Z=[],Q=[],ue=!0,$=[];if(z){let n=U?await U:await A(K,B,V),r=n.scanBase??B;for(let e of(await C(n.generator)).includes)m(g(r,e),E,D,O);({css:J,files:X,matched:Y,unknown:Z,undeclared:Q,hasPreset:ue}=await w(K,{base:B,contents:u.contents,readSources:ee(r,u.ignore)},n));try{G=ne(H,B)}catch(n){let r=x.get(l.name);if(!(r?.id===V&&re(r.packagePresetSpecifiers,H)&&r.packagePresetDependencies.some(e=>!t(e,{throwIfNoEntry:!1}))))throw n;G=r.packagePresetDependencies,e.logger.warn(`@teacss/rsbuild: keeping the last valid package preset dependencies for ${V} while package entries are unavailable`)}$=Array.from(new Set([...G,...n.sources]))}else{q??=await S(l.name);let e=await y(u,q.generator,void 0,q.sources),{spliceEntry:t}=await import(`@teacss/directives`);J=t(K,e.css),Y=e.utilities,X=e.files,$=q.sources}ue||e.logger.warn(`@teacss/rsbuild: ${j||`entry`} declares no @preset — no utilities generated. Add one, e.g. \`@preset "standard";\``),Z.length&&e.logger.warn(`@teacss/rsbuild: ${Z.length} @custom var(s) not registered (unknown namespace / illegal color step): ${Z.join(`, `)}`),Q.length&&e.logger.warn(`@teacss/rsbuild: ${Q.length} @custom theme var(s) not registered (no declared base value): ${Q.join(`, `)}`);for(let e of X)E(e);for(let e of $)m(e,E,D,O);let de=(l.config.mode??a.env.NODE_ENV)===`production`;if(!(r??de))return e.logger.info(`@teacss/rsbuild: ${Y} utilities (dev, unoptimized) → ${(J.length/1024).toFixed(1)}KB`),le(),{code:J};let fe=typeof r==`object`&&r.minify!==void 0?r.minify:ie(l.config.output.minify,de),{css:pe,skipped:me}=await T(J,{minify:fe,targets:o,browserslist:l.browserslist});return e.logger.info(`@teacss/rsbuild: ${Y} utilities${me?`, ${me} skipped`:``} → ${(pe.length/1024).toFixed(1)}KB`),le(),{code:pe}})}}}export{d as DEFAULT_TARGETS,v as generate,S as generateEntryCss,ee as makeReadSources,T as optimize,M as pluginTeacss,ie as resolveMinify,j as transformCss};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teacss/rsbuild",
3
- "version": "0.4.7",
3
+ "version": "0.5.1",
4
4
  "description": "Rsbuild integration for TeaCSS — generate utilities and optimize with lightningcss, no PostCSS.",
5
5
  "homepage": "https://css.teasim.com",
6
6
  "funding": "https://github.com/sponsors/billgo",
@@ -22,18 +22,18 @@
22
22
  "dev": "tsdown --watch"
23
23
  },
24
24
  "dependencies": {
25
- "@teacss/config": "0.4.7",
26
- "@teacss/core": "0.4.7",
27
- "@teacss/directives": "0.4.7",
28
- "@teacss/runtime": "0.4.7",
25
+ "@teacss/config": "0.5.1",
26
+ "@teacss/core": "0.5.1",
27
+ "@teacss/directives": "0.5.1",
28
+ "@teacss/runtime": "0.5.1",
29
29
  "lightningcss": "^1.33.0",
30
- "magic-string": "^1.1.0",
30
+ "magic-string": "^1.2.3",
31
31
  "tinyglobby": "^0.2.17"
32
32
  },
33
33
  "devDependencies": {
34
- "@rsbuild/core": "^2.1.8",
35
- "@teacss/preset-articles": "0.4.7",
36
- "@teacss/preset-standard": "0.4.7",
34
+ "@rsbuild/core": "^2.2.3",
35
+ "@teacss/preset-official": "0.5.1",
36
+ "@teacss/preset-standard": "0.5.1",
37
37
  "consola": "^3.4.2"
38
38
  },
39
39
  "peerDependencies": {