@teacss/rsbuild 0.8.0 → 0.8.2
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 +14 -2
- package/dist/index.d.ts +7 -39
- package/dist/index.js +1 -1
- package/package.json +8 -9
package/README.md
CHANGED
|
@@ -34,8 +34,20 @@ programmatic configuration, and imported safelists augment it.
|
|
|
34
34
|
A custom entry `test` is combined with the directive transform matcher, so
|
|
35
35
|
entries such as `.pcss` still reach TeaCSS.
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
`
|
|
37
|
+
Tooling that compiles an entry outside a build, such as a Storybook setup or a
|
|
38
|
+
test, uses `generateEntryCss` with `makeReadSources`:
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
import { generateEntryCss, makeReadSources } from "@teacss/rsbuild";
|
|
42
|
+
|
|
43
|
+
const { css } = await generateEntryCss(entryCss, {
|
|
44
|
+
base: root,
|
|
45
|
+
entryFile,
|
|
46
|
+
readSources: makeReadSources(root),
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The returned CSS is not optimized.
|
|
39
51
|
|
|
40
52
|
The optimizer preserves native `:dir()` selectors. The plugin also excludes
|
|
41
53
|
their language-based rewrite in Rsbuild's CSS loader and inherited minimizer
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RsbuildPlugin } from "@rsbuild/core";
|
|
2
2
|
import { UserConfig } from "@teacss/core";
|
|
3
3
|
import { Targets } from "lightningcss";
|
|
4
|
-
//#region src/
|
|
5
|
-
|
|
6
|
-
export interface TeacssGenerateOptions {
|
|
4
|
+
//#region src/plugin.d.ts
|
|
5
|
+
interface TeacssGenerateOptions {
|
|
7
6
|
/** Project root to scan + resolve config from. @default process.cwd() */
|
|
8
7
|
cwd?: string;
|
|
9
8
|
/** Path to the CSS entry, or a directory to discover it from. Ignored when `config` is given. */
|
|
@@ -15,7 +14,7 @@ export interface TeacssGenerateOptions {
|
|
|
15
14
|
/** Globs ignored during the filesystem scan. */
|
|
16
15
|
ignore?: string[];
|
|
17
16
|
}
|
|
18
|
-
|
|
17
|
+
interface TeacssPluginOptions extends TeacssGenerateOptions {
|
|
19
18
|
/**
|
|
20
19
|
* Optimize the output with lightningcss (minify + vendor prefixing).
|
|
21
20
|
* `true`/`false` toggles it; `{ minify }` overrides just minification.
|
|
@@ -40,22 +39,12 @@ export interface TeacssPluginOptions extends TeacssGenerateOptions {
|
|
|
40
39
|
test?: RegExp;
|
|
41
40
|
};
|
|
42
41
|
}
|
|
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
|
-
export declare function generate(options?: TeacssGenerateOptions): Promise<{
|
|
49
|
-
css: string;
|
|
50
|
-
utilities: number;
|
|
51
|
-
files: string[];
|
|
52
|
-
}>;
|
|
53
42
|
/** Build a `readSources` that scans `@source` include/exclude globs relative to the entry dir. */
|
|
54
43
|
export declare function makeReadSources(base: string, ignore?: string[]): (includes: string[], excludes: string[]) => Promise<{
|
|
55
44
|
files: string[];
|
|
56
45
|
sources: string[];
|
|
57
46
|
}>;
|
|
58
|
-
|
|
47
|
+
interface GenerateEntryCssOptions {
|
|
59
48
|
/** Entry file directory — base for `@presets` relative specifiers and `@source` globs. */
|
|
60
49
|
base: string;
|
|
61
50
|
/** Entry filename, when known, so local `@import` cycles include the root identity. */
|
|
@@ -81,28 +70,6 @@ export declare function generateEntryCss(entryCss: string, options: GenerateEntr
|
|
|
81
70
|
unknown: string[];
|
|
82
71
|
hasPreset: boolean;
|
|
83
72
|
}>;
|
|
84
|
-
/**
|
|
85
|
-
* Optimize CSS with lightningcss: minify + vendor prefixing. Targets come from
|
|
86
|
-
* `targets`, else the given `browserslist`, else a sensible default. `errorRecovery`
|
|
87
|
-
* skips any single malformed rule instead of failing the build.
|
|
88
|
-
*/
|
|
89
|
-
export declare function optimize(css: string, { minify, targets, browserslist }?: {
|
|
90
|
-
minify?: boolean;
|
|
91
|
-
targets?: Targets;
|
|
92
|
-
browserslist?: string[];
|
|
93
|
-
}): Promise<{
|
|
94
|
-
css: string;
|
|
95
|
-
skipped: number;
|
|
96
|
-
}>;
|
|
97
|
-
/** Whether to minify, from Rsbuild's `output.minify` config + build mode. */
|
|
98
|
-
export declare function resolveMinify(minify: Minify | undefined, isProd: boolean): boolean;
|
|
99
|
-
/**
|
|
100
|
-
* Inline `@apply` (+ `@screen` / `theme()` / `icon()`) in a CSS string, resolving
|
|
101
|
-
* tokens against the config (inline `config`, or discovered from `cwd`/`configPath`).
|
|
102
|
-
* The programmatic form of the plugin's per-`.css` pass; fast-bails to a
|
|
103
|
-
* byte-identical string when the input has none of those directives.
|
|
104
|
-
*/
|
|
105
|
-
export declare function transformCss(code: string, options?: TeacssGenerateOptions, id?: string): Promise<string>;
|
|
106
73
|
/**
|
|
107
74
|
* Rsbuild plugin: replace the `@teacss` directive in a CSS entry with generated
|
|
108
75
|
* utilities, optimized with lightningcss, and inline `@apply` in any `.css`.
|
|
@@ -116,4 +83,5 @@ export declare function transformCss(code: string, options?: TeacssGenerateOptio
|
|
|
116
83
|
* (fast-bailed), configurable via `apply`.
|
|
117
84
|
*/
|
|
118
85
|
export declare function pluginTeacss(options?: TeacssPluginOptions): RsbuildPlugin;
|
|
119
|
-
//#endregion
|
|
86
|
+
//#endregion
|
|
87
|
+
export type { GenerateEntryCssOptions, TeacssGenerateOptions, TeacssPluginOptions };
|
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/@(presets?|primary|neutral|success|warning|failure|general|focused|custom|source|shortcut|safelist)\b/.test(e)||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{
|
|
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/@(presets?|primary|neutral|success|warning|failure|general|focused|custom|source|shortcut|safelist)\b/.test(e)||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{scanSourceFiles:r}=await import(`@teacss/config/internal/source-scan`),i=await r(t,{cwd:e,expandDirectories:!0,ignore:n});return{files:i,sources:i.map(c)}}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: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 y(e,t=[]){return async(n,r)=>{let{scanSourceFiles:i}=await import(`@teacss/config/internal/source-scan`),a=await i(n,{cwd:e,expandDirectories:!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 ee(e){return e.filter(e=>!e.startsWith(`.`)&&!r(e))}function te(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 ne(e,t){return e.length===t.length&&e.every((e,n)=>e===t[n])}async function S(e,t){return w(e,t,await O(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,hasPreset:n.hasPreset}}async function re(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=E(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 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 ie(e,t){return typeof e==`boolean`||e==null?(e??!0)&&t:e.css!==!1&&(e.css===`always`||t)}async function D(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 O(e,t,n){let[{resolveEntryConfig:r},{createGenerator:i}]=await Promise.all([import(`@teacss/config`),import(`@teacss/core`)]),{config:a,sources:o,unknown:s}=await r(e,t,n);return{generator:await i(a),sources:o,unknown:s,hasPreset:!!a.presets?.length,hasEntryConfig:!!(a.presets?.length||a.content||a.shortcuts||Object.keys(a.theme??{}).length||s.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()}function k(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()),b=new Map,x=new Map,S=new Map,T=e=>{let t=b.get(e);if(t)return t;let n=_().then(e=>D(u,e));return b.set(e,n),n};e.onBeforeEnvironmentCompile(({environment:e})=>{b.delete(e.name),x.delete(e.name)}),e.transform({test:d?[l,s]:s},async({code:c,environment:l,addDependency:E,addMissingDependency:k,addContextDependency:A,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,diagnoseEntry:ce}=await import(`@teacss/config`),I=N?oe(c):void 0,L=I?.hasTeacss===!0;if(!L&&!F)return c;let R=!!(I&&(ce(c).length||I.rolePalettes||I.presets.length>0||I.sources.length>0||I.custom.length>0||I.shortcuts.length>0)),le=L&&se(c).some(e=>e.name===`import`&&e.terminator===`;`),z=R||le,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,k,A);let H=ee(I?.presets??[]),U,W,G;if(L){if(z)U=O(c,B,V).then(async e=>{if(!R&&!e.hasEntryConfig){let t=await D(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,k,A);let i=S.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}}),x.set(l.name,U),d?b.set(l.name,U):b.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=>D(u,e,n));b.set(l.name,r),x.delete(l.name),S.delete(l.name)}else b.delete(l.name),x.delete(l.name),S.delete(l.name)}let K=()=>{W&&G&&U&&x.get(l.name)===U&&S.set(l.name,{id:V,packagePresetDependencies:G,packagePresetSpecifiers:H,state:W})},q=c,J;if(P&&(L||F)){try{J=await T(l.name)}catch(e){if(!U){let{getConfigSourcesFromError:t}=await import(`@teacss/config`);for(let n of t(e))m(n,E,k,A)}throw e}for(let e of J.sources)m(e,E,k,A);q=await ae(c,M,J.generator)}if(!L)return q===c?c:{code:q};let Y,X,Z,Q=[],ue=!0,$=[];if(z){let n=U?await U:await O(q,B,V),r=n.scanBase??B;for(let e of(await C(n.generator)).includes)m(g(r,e),E,k,A);({css:Y,files:Z,matched:X,unknown:Q,hasPreset:ue}=await w(q,{base:B,contents:u.contents,readSources:y(r,u.ignore)},n));try{G=te(H,B)}catch(n){let r=S.get(l.name);if(!(r?.id===V&&ne(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{J??=await T(l.name);let e=await v(u,J.generator,void 0,J.sources),{spliceEntry:t}=await import(`@teacss/directives`);Y=t(q,e.css),X=e.utilities,Z=e.files,$=J.sources}ue||e.logger.warn(`@teacss/rsbuild: ${j||`entry`} declares no @presets — no utilities generated. Add one, e.g. \`@presets "standard";\``),Q.length&&e.logger.warn(`@teacss/rsbuild: ${Q.length} @custom var(s) not registered (unknown namespace / illegal color step): ${Q.join(`, `)}`);for(let e of Z)E(e);for(let e of $)m(e,E,k,A);let de=(l.config.mode??a.env.NODE_ENV)===`production`;if(!(r??de))return e.logger.info(`@teacss/rsbuild: ${X} utilities (dev, unoptimized) → ${(Y.length/1024).toFixed(1)}KB`),K(),{code:Y};let fe=typeof r==`object`&&r.minify!==void 0?r.minify:ie(l.config.output.minify,de),{css:pe,skipped:me}=await re(Y,{minify:fe,targets:o,browserslist:l.browserslist});return e.logger.info(`@teacss/rsbuild: ${X} utilities${me?`, ${me} skipped`:``} → ${(pe.length/1024).toFixed(1)}KB`),K(),{code:pe}})}}}export{S as generateEntryCss,y as makeReadSources,k as pluginTeacss};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teacss/rsbuild",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.2",
|
|
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,17 @@
|
|
|
22
22
|
"dev": "tsdown --watch"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@teacss/config": "0.8.
|
|
26
|
-
"@teacss/core": "0.8.
|
|
27
|
-
"@teacss/directives": "0.8.
|
|
28
|
-
"@teacss/runtime": "0.8.
|
|
25
|
+
"@teacss/config": "0.8.2",
|
|
26
|
+
"@teacss/core": "0.8.2",
|
|
27
|
+
"@teacss/directives": "0.8.2",
|
|
28
|
+
"@teacss/runtime": "0.8.2",
|
|
29
29
|
"lightningcss": "^1.33.0",
|
|
30
|
-
"magic-string": "^1.2.3"
|
|
31
|
-
"tinyglobby": "^0.2.17"
|
|
30
|
+
"magic-string": "^1.2.3"
|
|
32
31
|
},
|
|
33
32
|
"devDependencies": {
|
|
34
33
|
"@rsbuild/core": "^2.2.3",
|
|
35
|
-
"@teacss/preset-official": "0.8.
|
|
36
|
-
"@teacss/preset-standard": "0.8.
|
|
34
|
+
"@teacss/preset-official": "0.8.2",
|
|
35
|
+
"@teacss/preset-standard": "0.8.2",
|
|
37
36
|
"consola": "^3.4.2"
|
|
38
37
|
},
|
|
39
38
|
"peerDependencies": {
|