@teacss/vite 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 +50 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.js +2 -0
- package/package.json +43 -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,50 @@
|
|
|
1
|
+
# @teacss/vite
|
|
2
|
+
|
|
3
|
+
**Vite plugin for TeaCSS.**
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
The plugin scans Vite modules, generates utilities, transforms TeaCSS CSS
|
|
8
|
+
directives, and serves the generated stylesheet as `virtual:teacss.css`.
|
|
9
|
+
|
|
10
|
+
Use this package when Vite owns the application's module graph and development
|
|
11
|
+
or production build. It owns TeaCSS extraction, stylesheet HMR, and final CSS
|
|
12
|
+
asset generation inside Vite; Astro applications should use `@teacss/astro` for
|
|
13
|
+
Astro lifecycle and automatic page injection, while the optional
|
|
14
|
+
`@teacss/inspector` only observes this plugin's development context.
|
|
15
|
+
|
|
16
|
+
Production builds collect every transformed module before finalizing the
|
|
17
|
+
stylesheet, run generated rules through the configured Vite CSS transform and
|
|
18
|
+
minifier, and derive hashed asset names from the final CSS. Dependent JavaScript
|
|
19
|
+
chunks include the final CSS digest, so late stylesheet-reference changes also
|
|
20
|
+
invalidate their hashes. Fixed asset names remain fixed. Generated utility CSS
|
|
21
|
+
currently has no build sourcemap.
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import { defineConfig } from "vite";
|
|
27
|
+
import { pluginTeacss } from "teacss/vite";
|
|
28
|
+
|
|
29
|
+
export default defineConfig({
|
|
30
|
+
plugins: [pluginTeacss()],
|
|
31
|
+
});
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import "virtual:teacss.css";
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Configure TeaCSS in `index.css` or `src/index.css`:
|
|
39
|
+
|
|
40
|
+
```css
|
|
41
|
+
@preset "standard";
|
|
42
|
+
@source "./src/**/*.{ts,tsx}";
|
|
43
|
+
@teacss;
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Status
|
|
47
|
+
|
|
48
|
+
Pre-1.0. Install `@teacss/vite` beside `teacss`, then use the stable
|
|
49
|
+
`teacss/vite` facade subpath in applications. Integration authors may import
|
|
50
|
+
`@teacss/vite` directly when they intentionally do not use the facade.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { TeacssPluginContext, UserConfig, UserConfigDefaults } from "@teacss/core";
|
|
2
|
+
import { LightningCSSOptions, Plugin } from "vite";
|
|
3
|
+
//#region src/types.d.ts
|
|
4
|
+
interface TeacssVitePluginConfig<Theme extends object = object> extends UserConfig<Theme> {
|
|
5
|
+
/**
|
|
6
|
+
* Generation mode. Only `global` is supported (a single virtual stylesheet
|
|
7
|
+
* collecting every utility found across the project).
|
|
8
|
+
*
|
|
9
|
+
* @default "global"
|
|
10
|
+
*/
|
|
11
|
+
mode?: "global";
|
|
12
|
+
/**
|
|
13
|
+
* Drive Vite's CSS pipeline with **lightningcss** instead of PostCSS + esbuild:
|
|
14
|
+
* sets `css.transformer: "lightningcss"` (replaces PostCSS) and
|
|
15
|
+
* `build.cssMinify: "lightningcss"` (replaces esbuild's CSS minifier). On by
|
|
16
|
+
* default — pass `false` to keep Vite's PostCSS + esbuild pipeline, or an
|
|
17
|
+
* object to forward lightningcss options (e.g. `targets`, `drafts`). Only
|
|
18
|
+
* fields you haven't set yourself are touched, so an explicit
|
|
19
|
+
* `css.transformer` / `build.cssMinify` always wins.
|
|
20
|
+
*
|
|
21
|
+
* @default true
|
|
22
|
+
*/
|
|
23
|
+
lightningcss?: boolean | LightningCSSOptions;
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region src/index.d.ts
|
|
27
|
+
declare function defineConfig<Theme extends object>(config: TeacssVitePluginConfig<Theme>): TeacssVitePluginConfig<Theme>;
|
|
28
|
+
interface TeacssVitePluginAPI {
|
|
29
|
+
getContext: () => TeacssPluginContext<TeacssVitePluginConfig>;
|
|
30
|
+
getMode: () => "global";
|
|
31
|
+
}
|
|
32
|
+
declare function pluginTeacss<Theme extends object>(configOrPath?: TeacssVitePluginConfig<Theme> | string, defaults?: UserConfigDefaults): Plugin[];
|
|
33
|
+
//#endregion
|
|
34
|
+
export { TeacssVitePluginAPI, TeacssVitePluginConfig, defineConfig, pluginTeacss };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{createHash as e}from"node:crypto";import{basename as t,join as n,resolve as r}from"node:path";import i from"node:process";import{entryDiscoveryFiles as a}from"@teacss/config";import{CSS_PLACEHOLDER as o,isCssId as s}from"@teacss/core";import{applyTransformerPipeline as c,createContext as l,getModuleOutput as u}from"@teacss/runtime";import{normalizePath as d,preprocessCSS as f,transformWithEsbuild as p}from"vite";function m(e){return e.includes(`@apply`)||e.includes(`--at-apply`)||e.includes(`@screen`)||e.includes(`theme(`)||e.includes(`icon(`)}const h=async()=>{let{default:e}=await import(`@teacss/directives`);return e()};function ee(e=h){let t;return{name:`@teacss/directives`,idFilter:s,async transform(n,r,i){if(m(n.original))return await(await(t??=e())).transform?.(n,r,i)}}}function g(e){return e}const _=new Set([`virtual:teacss.css`,`teacss.css`]),v=`/*! ${o} */`,y=`teacss:css-ready`;function b(e,t,n){let r=e.lastIndexOf(t);return r<0||r+t.length!==e.length||r>0&&e[r-1]!==`/`?e:`${e.slice(0,r)}${n}`}function te(e,t,n){let r;try{r=JSON.parse(e)}catch{return e}let i=!1,a=e=>{if(typeof e==`string`){let r=b(e,t,n);return i||=r!==e,r}if(Array.isArray(e))return e.map(a);if(e&&typeof e==`object`)for(let[t,n]of Object.entries(e))e[t]=a(n);return e};return a(r),i?JSON.stringify(r,void 0,2):e}function x(e,t){let n=0,r=``;for(let i=t;i<e.length;i++){let t=e[i];if(r){t===`\\`?i++:t===r&&(r=``);continue}if(t===`"`||t===`'`||t==="`")r=t;else if(t===`[`)n++;else if(t===`]`&&--n===0)return i}return-1}function S(e,t,n=0){for(let r=n;r<e.length;r++){let n=e[r];if(n===`'`||n===`"`||n==="`"){let t=n;for(r++;r<e.length;r++)if(e[r]===`\\`)r++;else if(e[r]===t)break;continue}if(n===`/`&&e[r+1]===`/`){let t=e.indexOf(`
|
|
2
|
+
`,r+2);if(t<0)return-1;r=t;continue}if(n===`/`&&e[r+1]===`*`){let t=e.indexOf(`*/`,r+2);if(t<0)return-1;r=t+1;continue}if(e.startsWith(t,r))return r}return-1}function ne(e,t,n){let r=S(e,`const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=`);if(r<0)return e;let i=r+56;if(e[i]!==`[`)return e;let a=x(e,i);if(a<0||!e.startsWith(`)))=>i.map(i=>d[i]);`,a+1)||S(e,`__vite__mapDeps([`,a+20+1)<0)return e;let o=JSON.stringify(t),s=e.slice(i,a+1),c=s.replaceAll(o,JSON.stringify(n));return c===s?e:`${e.slice(0,i)}${c}${e.slice(a+1)}`}const C={chrome:`chrome`,edge:`edge`,firefox:`firefox`,hermes:!1,ie:`ie`,ios:`ios_saf`,node:!1,opera:`opera`,rhino:!1,safari:`safari`},w={2015:[`chrome49`,`edge13`,`safari10`,`ios10`,`firefox44`,`opera36`],2016:[`chrome50`,`edge13`,`safari10`,`ios10`,`firefox43`,`opera37`],2017:[`chrome58`,`edge15`,`safari11`,`ios11`,`firefox52`,`opera45`],2018:[`chrome63`,`edge79`,`safari12`,`ios12`,`firefox58`,`opera50`],2019:[`chrome73`,`edge79`,`safari12.1`,`ios12.1`,`firefox64`,`opera60`],2020:[`chrome80`,`edge80`,`safari14.1`,`ios14.5`,`firefox80`,`opera67`],2021:[`chrome85`,`edge85`,`safari14.1`,`ios14.5`,`firefox80`,`opera71`],2022:[`chrome94`,`edge94`,`safari16.4`,`ios16.4`,`firefox93`,`opera80`],2023:[`chrome110`,`edge110`,`safari16.4`,`ios16.4`,`firefox146`,`opera96`],2024:[`chrome119`,`edge119`,`safari17.4`,`ios17.4`,`firefox145`,`opera105`],2025:[`chrome136`,`edge136`,`safari26.0`,`ios26.0`,`firefox138`,`opera121`]};function re(e){let t={},n=(Array.isArray(e)?e:e?[e]:[]).flatMap(e=>{let t=/^es(6|\d{4})$/.exec(e);if(!t)return e;let n=t[1]===`6`?2015:Number(t[1]),r=w[n];if(!r)throw Error(`Unsupported target "${e}"`);return r});for(let e of n){if(e===`esnext`)continue;let n=/^([a-z_]+)(\d+)(?:\.(\d+))?$/i.exec(e),r=n&&C[n[1].toLowerCase()];if(r===!1)continue;if(!n||!r)throw Error(`Unsupported target "${e}"`);let i=Number(n[2])<<16|Number(n[3]??0)<<8;(!t[r]||i<t[r])&&(t[r]=i)}return t}function T(o,s={}){let m,h=o;if(o&&typeof o==`object`){m=o.lightningcss;let e={...o};delete e.lightningcss,delete e.mode,h=Object.keys(e).length?e:void 0}let g=l(h,{envMode:i.env.NODE_ENV===`development`?`dev`:`build`,...s,transformers:[...s.transformers??[],ee()]}),b=`/__tea.css`,x,S=!1,C,w,T=!1,E,D,O=new Set,k=new Map,A=new Map,j=new Map,M=new Set,N,P,F=0,I=!1,L,R,z=0,B=0,V,H;function U(){H=void 0}function W(e=g.root){let t=g.getConfigFileList().map(d),i=new Set(t);if(typeof h==`object`){O=i;return}let o=d(typeof h==`string`?r(e,h):e);if(!t.includes(o))for(let e of a)i.add(d(n(o,e)));O=i}async function G(){let{prefix:e}=await g.getVMPRegexes();return b=`/${e}.css`,b}async function K(){await g.flushTasks();let e=H;if(e&&e.config===g.generator.config&&e.tokens.length===g.tokens.size){let t=0,n=!0;for(let r of g.tokens)if(e.tokens[t++]!==r){n=!1;break}if(n)return await e.promise}let t=[...g.tokens],n={config:g.generator.config,promise:g.generator.generate(t,{minify:!1}).then(({css:e})=>e),tokens:t};H=n;try{return await n.promise}catch(e){throw H===n&&(H=void 0),e}}async function q(){let e=await K(),t=x;if(!t||!(`environments`in t))return e;let n=r(t.root,b.slice(1)),i=(await f(e,n,t.css.transformer===`lightningcss`&&t.build.cssMinify?{...t,build:{...t.build,cssMinify:!1}}:t)).code;if(!t.build.cssMinify)return i;if(t.build.cssMinify===`esbuild`){let e=t.esbuild||{},r={charset:e.charset,legalComments:e.legalComments,logLevel:e.logLevel,logLimit:e.logLimit,logOverride:e.logOverride},a=e.minifyIdentifiers!=null||e.minifySyntax!=null||e.minifyWhitespace!=null?{minifyIdentifiers:e.minifyIdentifiers??!0,minifySyntax:e.minifySyntax??!0,minifyWhitespace:e.minifyWhitespace??!0}:{minify:!0},o=await p(i,n,{...r,...a,loader:`css`,sourcemap:!1,target:t.build.cssTarget||void 0},void 0,t,void 0,!0);for(let e of o.warnings)t.logger.warn(`[esbuild css minify] ${e.text}`);return o.code}let{transform:a}=await import(`lightningcss`),o=a({...t.css.lightningcss,code:Buffer.from(i),cssModules:void 0,filename:n,minify:!0,targets:re(t.build.cssTarget)});for(let e of o.warnings)t.logger.warn(`[lightningcss minify] ${e.message}`);return new TextDecoder().decode(o.code)}function J(){if(!C)return;let e=C;N&&clearTimeout(N),N=setTimeout(()=>{N=void 0;let t=P,n=(async()=>{if(t&&await t.catch(()=>{}),C!==e||(T?B:z)>=F||(await Q(),await e.waitForRequestsIdle?.(),C!==e||(T?B:z)>=F))return;let n=F,r=e.moduleGraph.getModuleById(b);if(!r){z=n,T&&(B=n);return}T?(await e.reloadModule(r),B=n,z=n):(e.moduleGraph.invalidateModule(r),z=n)})();P=n,n.then(()=>{P===n&&(P=void 0,C===e&&(T?B:z)<F&&J())},t=>{P===n&&(P=void 0),e.config.logger.error(`TeaCSS failed to invalidate its virtual stylesheet`,{error:t})})},20)}function ie(){U(),C&&(F++,J())}function ae(e){if(!C)return;let t=!1;for(let n of e){let e=C.moduleGraph.getModuleById(n);e&&(C.moduleGraph.invalidateModule(e),t=!0)}t&&C.ws.send({type:`full-reload`})}function Y(){N&&clearTimeout(N),N=void 0,T=!1,E?.(),E=void 0,D?.(),D=void 0,C=void 0,P=void 0}function X(){w??=g.onInvalidate(ie)}function Z(){U(),Y(),w?.(),w=void 0}async function oe(e,t){let n={};k.set(t,n),A.set(t,e);try{let r=await c(g,e,t);return k.get(t)===n?(r?j.set(t,r.code):j.delete(t),g.filter(e,t)?await g.extract(r?.code??e,t):g.modules.has(t)&&await g.extract(``,t),r??null):r??null}finally{k.get(t)===n&&k.delete(t)}}async function se(e,t){V&&await V;let n=oe(e,t),r=n.then(()=>{},()=>{});M.add(r);try{return await n}finally{M.delete(r)}}async function ce(e){let t=new Set(e),n=new Set([...A.keys(),...j.keys()]),r=[];for(let e of n)t.has(e)||(k.delete(e),A.delete(e),j.delete(e),r.push(g.extract(``,e)));await Promise.all(r)}async function Q(){for(;M.size;)await Promise.all(M)}async function le(){let e=Array.from(A),t=new Map(e.map(([e,t])=>[e,j.get(e)??t]));try{await g.reloadConfig()}finally{W(g.root)}await G();let n=[];for(let[r,i]of e){let e=u(g,r)??i;e===i?j.delete(r):j.set(r,e),e!==t.get(r)&&n.push(r)}ae(n)}async function ue(){let e=V,t=(async()=>{e&&await e.catch(()=>{}),await Q(),await le()})();V=t;try{await t}finally{V===t&&(V=void 0)}}let $={name:`teacss`,enforce:`pre`,config(e){if(m===!1)return;let t=typeof m==`object`?m:void 0,n={};return e.css?.transformer===void 0&&(n.css={transformer:`lightningcss`,...t?{lightningcss:t}:{}}),e.build?.cssMinify===void 0&&(n.build={cssMinify:`lightningcss`}),n},async configResolved(e){x=e,S=e.command===`serve`,await g.updateRoot(e.root),W(e.root),await G(),X()},buildStart(){I=!1,L=void 0,R=void 0,X(),W();for(let e of O)this.addWatchFile(e)},async buildEnd(t){if(!(S||t)){if(typeof this.getModuleIds==`function`&&await ce(this.getModuleIds()),!(I||typeof this.getModuleInfo==`function`&&this.getModuleInfo(b)!=null)){R=void 0;return}L=await q(),R=e(`sha256`).update(L).digest(`hex`)}},configureServer(e){Y(),C=e,X();let t=()=>{C===e&&(T=!0,B<F&&J())};if(e.hot?.on(y,t),E=()=>e.hot?.off(y,t),e.httpServer){let t=()=>{C===e&&Z()};e.httpServer.once(`close`,t),D=()=>e.httpServer?.off(`close`,t)}},closeBundle(){Z()},transformIndexHtml:{order:`pre`,async handler(e,{filename:t}){g.filter(e,t)?await g.extract(e,t):g.modules.has(t)&&await g.extract(``,t)}},async resolveId(e){return _.has(e)||_.has(e.replace(/^\//,``))||e.startsWith(`${b}?`)?b:null},async load(e){return e===b?S?await K():(I=!0,v):null},async transform(e,t){return t===b?null:await se(e,t)},async watchChange(e,t){if(O.has(d(e)))try{await ue()}finally{for(let e of O)this.addWatchFile(e)}else V&&await V;if(t.event===`delete`){let t=new Set([e]);for(let n of[...g.modules.keys(),...k.keys(),...A.keys()])(n===e||n.startsWith(`${e}?`))&&t.add(n);for(let e of t)k.delete(e),A.delete(e),j.delete(e);await Promise.all(Array.from(t,e=>g.extract(``,e)))}},async generateBundle(e,n){if(S)return;let r;for(let[i,a]of Object.entries(n)){if(a.type!==`asset`||!a.fileName.endsWith(`.css`))continue;let o=typeof a.source==`string`?a.source:new TextDecoder().decode(a.source);if(!o.includes(v))continue;r??=L??await q();let s=o.replaceAll(v,r),c=typeof e.assetFileNames!=`string`||e.assetFileNames.includes(`[hash`);if(typeof e.assetFileNames==`function`){let t={name:a.name,names:a.names,originalFileName:a.originalFileName??void 0,originalFileNames:a.originalFileNames,type:`asset`},n=e.assetFileNames({...t,source:a.source}),r=e.assetFileNames({...t,source:s});c=r.includes(`[hash`)||r!==n}if(!x||!(`environments`in x)||!c){a.source=s;continue}let l=this.emitFile({type:`asset`,name:a.name||t(a.fileName),...a.originalFileName?{originalFileName:a.originalFileName}:{},source:s}),u=this.getFileName(l),d=new Set,f=x.build.manifest,p=x.build.ssrManifest;f&&d.add(typeof f==`string`?f:`.vite/manifest.json`),p&&d.add(typeof p==`string`?p:`.vite/ssr-manifest.json`);for(let e of Object.values(n))e.viteMetadata?.importedCss.delete(a.fileName)&&e.viteMetadata.importedCss.add(u),e.type===`chunk`?e.code=ne(e.code,a.fileName,u):e!==a&&typeof e.source==`string`&&d.has(e.fileName)&&(e.source=te(e.source,a.fileName,u));delete n[i]}}};return[$,{name:`teacss:api`,enforce:`post`,api:{getContext:()=>g,getMode:()=>`global`},transform(e,t){return!S||t!==b||!e.includes(`import.meta.hot`)?null:`${e}\nimport.meta.hot.send(${JSON.stringify(y)});`},augmentChunkHash(){return R},generateBundle:{order:`post`,async handler(e,t){let n=$.generateBundle;typeof n==`function`&&await n.call(this,e,t,!1)}}}]}export{g as defineConfig,T as pluginTeacss};
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@teacss/vite",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Vite plugin for TeaCSS.",
|
|
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
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"vite": "^8.1.5"
|
|
33
|
+
},
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"vite": ">=8.0.0"
|
|
36
|
+
},
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=22.12.0"
|
|
39
|
+
},
|
|
40
|
+
"publishConfig": {
|
|
41
|
+
"access": "public"
|
|
42
|
+
}
|
|
43
|
+
}
|