This commit is contained in:
Alex 2024-04-07 21:18:45 -04:00
parent 4114914eea
commit bec8b92669
5 changed files with 31 additions and 15 deletions

View File

@ -1 +1,9 @@
# babel-tailwind
Compile-run Tailwind compiler.
```tsx
export function App() {
return <div css="flex m-0"></div>;
}
```

View File

@ -1,6 +1,6 @@
{
"name": "@aet/babel-tailwind",
"version": "0.0.1-beta.5",
"version": "0.0.1-beta.7",
"main": "dist/index.js",
"license": "MIT",
"private": true,
@ -46,4 +46,4 @@
"singleQuote": false,
"trailingComma": "es5"
}
}
}

View File

@ -4,12 +4,6 @@ import { type NodePath, type types as t } from "@babel/core";
import type { SourceLocation, StyleMap, StyleMapEntry } from "./shared";
import { type TailwindPluginOptions, getClassName } from "./index";
interface BabelPluginState {
getCx: () => t.Identifier;
sliceText: (node: t.Node) => SourceLocation;
tailwindMap: Map<string, StyleMapEntry>;
}
const definePlugin =
<T>(fn: (runtime: typeof babel) => babel.Visitor<babel.PluginPass & T>) =>
(runtime: typeof babel) => {
@ -31,6 +25,13 @@ function matchPath(
fn?.(nodePath);
}
interface BabelPluginState {
getCx: () => t.Identifier;
sliceText: (node: t.Node) => SourceLocation;
recordIfAbsent: (node: StyleMapEntry) => void;
tailwindMap: Map<string, StyleMapEntry>;
}
export function babelTailwind(
styleMap: StyleMap,
{
@ -67,7 +68,7 @@ export function babelTailwind(
Program: {
enter(path, state) {
let cx: t.Identifier;
state.tailwindMap = new Map();
const map = (state.tailwindMap = new Map());
state.sliceText = node => ({
filename: state.filename!,
start: node.loc!.start,
@ -77,6 +78,11 @@ export function babelTailwind(
.slice(node.loc!.start.line - 1, node.loc!.end.line)
.join("\n"),
});
state.recordIfAbsent = entry => {
if (!map.has(entry.key)) {
map.set(entry.key, entry);
}
};
state.getCx = () => {
if (cx == null) {
cx = path.scope.generateUidIdentifier("cx");
@ -101,7 +107,7 @@ export function babelTailwind(
},
},
TaggedTemplateExpression(path, { tailwindMap, sliceText }) {
TaggedTemplateExpression(path, { sliceText, recordIfAbsent }) {
if (taggedTemplateName == null) return;
const { node } = path;
@ -119,7 +125,7 @@ export function babelTailwind(
if (value) {
const trimmed = value.replace(/\s+/g, " ").trim();
const className = getClass(trimmed);
tailwindMap.set(className, {
recordIfAbsent({
key: className,
className: trimmed,
location: sliceText(node),
@ -128,7 +134,7 @@ export function babelTailwind(
}
},
JSXAttribute(path, { tailwindMap, sliceText, getCx }) {
JSXAttribute(path, { sliceText, recordIfAbsent, getCx }) {
const { name } = path.node;
if (name.name !== jsxAttributeName) return;
@ -152,7 +158,7 @@ export function babelTailwind(
if (value) {
const trimmed = value.replace(/\s+/g, " ").trim();
const className = getClass(trimmed);
tailwindMap.set(className, {
recordIfAbsent({
key: className,
className: trimmed,
location: sliceText(node),

View File

@ -1,6 +1,7 @@
import hash from "@emotion/hash";
import type { Config } from "tailwindcss";
import type postcss from "postcss";
import { memoize } from "lodash";
import { babelTailwind } from "./babel-tailwind";
import { esbuildPlugin } from "./esbuild-postcss";
import { vitePlugin } from "./vite-plugin";
@ -90,7 +91,7 @@ export const getClassName: GetClassName = cls => "tw-" + hash(cls);
*/
export function getTailwindPlugins(options: TailwindPluginOptions) {
const styleMap: StyleMap = new Map();
const compile = createPostCSS(options);
const compile = memoize(createPostCSS(options));
return {
compile,

View File

@ -1,5 +1,6 @@
import { dirname, join } from "node:path";
import type * as vite from "vite";
import { memoize } from "lodash";
import { type Compile, type StyleMap, pkgName, toCSSText } from "./shared";
const ROLLUP_PREFIX = "\0tailwind:";
@ -28,7 +29,7 @@ export const vitePlugin = (styleMap: StyleMap, compile: Compile): vite.Plugin =>
if (id.startsWith(ROLLUP_PREFIX)) {
const resolved = id.slice(ROLLUP_PREFIX.length);
if (resolved === "directive:base") {
return (await compile("@tailwind base;")).css;
return (await compile("@tailwind base")).css;
}
if (styleMap.has(resolved)) {