Skip to content

Commit

Permalink
New Transpiler (Limited AST) (#123)
Browse files Browse the repository at this point in the history
* core package draft

* add swc-plan

* rename swc-idea

* update swc idea

* fix code format

* remove swc-idea

* Initial new-transpiler

* update core index export

* fix swc plugin options

* move code core

* fix code format

* remove dead code

* remove dead code

* fix build package

* fix core export

* swc-plugin usize to u8

* add user options

* fix code format

* fix swc-plugin small fix

* fix rename BuildArgument to BuildArg and more

* NOT TreeShake Webpack Node ChildComplier

* update swc-plugin dependency & profile.release

* fix playground

* fix webpack-plugin

* fix code format

* fix playground

* fix webpack-plugin

* fix swc-plugin pre-transform

* fix swc-plugin pre-transform

* swc-plugin u8 to usize

* refactor rename

* add babel-plugin preTransform

* add babel-plugin transform

* refactor remove dead code

* add build package babel transpiler

* clean up collector

* refactor astNode & astNode array types

* swc-plugin wasm size optimize

* comeback createStyle & createGlobalStyle

* update playground

* (not completion) create library docs

* fix code format

* remove dead code for swc-plugin

* update docs

* update playground

* refactor rename
  • Loading branch information
taishinaritomi authored Mar 23, 2023
1 parent 2b72241 commit b7243aa
Show file tree
Hide file tree
Showing 65 changed files with 2,186 additions and 1,018 deletions.
95 changes: 95 additions & 0 deletions docs/HOW_TO_CREATE_LIBRARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# How to create Library

Library authors can use kaze-style to create pre-generated CSS in JS.

In kaze-style, there are two ways to create a Library.

## 1. Static assets

type reference [style](./1.STYLE.md) | [globalStyle](./2.GLOBAL_STYLE.md)

```ts
// Example
// @kaze-style/themes theme & globalTheme uses this method.

import { style, globalStyle } from '@kaze-style/core';
import { theme, globalTheme } from '@kaze-style/themes';

globalStyle(globalTheme.reset());

export const classes = style({
container: {
...theme.animation('spin'),
},
});
```

### how to create

```ts
// Example
export const animation = {
spin: {
animationDuration: '1s',
animationIterationCount: 'infinite',
animationTimingFunction: 'linear',
animationName: {
from: {
transform: 'rotate(0deg)',
},
to: {
transform: 'rotate(360deg)',
},
},
},
} as const;
```

## 2. Function API

This one can do more than static assets, but is a bit more complicated.

```ts
// Example
// @kaze-style/core style & globalStyle uses this method.

import { cssVar } from 'your-lib';

export const vars = cssVar({
darkColor: 'black',
lightColor: 'white',
});
```

### how to create

```ts
// Example
// @kaze-style/core style api
import { isBuildTime } from './isBuildTime';
import { resolveStyle } from './resolveStyle';
import { setCssRules } from './setCssRules';
import type { BuildArg, Classes } from './types/common';
import type { KazeStyle } from './types/style';
import { classesSerialize } from './utils/classesSerialize';

export function style<K extends string>(styles: KazeStyle<K>): Classes<K>;
export function style<K extends string>(
styles: KazeStyle<K>,
buildArg: BuildArg,
index: number,
): Classes<K>;
export function style<K extends string>(
styles: KazeStyle<K>,
buildArg?: BuildArg,
index?: number,
): Classes<K> {
const [cssRules, classes, staticClasses] = resolveStyle(styles);
if (isBuildTime(buildArg) && typeof index !== 'undefined') {
const classesNode = classesSerialize(staticClasses);
buildArg.injector.cssRules.push(...cssRules);
buildArg.injector.args.push({ value: [classesNode], index });
} else if (typeof document !== 'undefined') setCssRules(cssRules);
return classes;
}
```
47 changes: 47 additions & 0 deletions packages/babel-plugin/src/astNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import type { types as t } from '@babel/core';
import type { AstNode } from '@kaze-style/core';

export const nodeToExpr = (node: AstNode): t.Expression => {
if (node.type === 'String') {
return { type: 'StringLiteral', value: node.value };
} else if (node.type === 'Number') {
return { type: 'NumericLiteral', value: node.value };
} else if (node.type === 'Boolean') {
return { type: 'BooleanLiteral', value: node.value };
} else if (node.type === 'Null') {
return { type: 'NullLiteral' };
} else if (node.type === 'Identifier') {
return {
type: 'Identifier',
name: node.name,
};
} else if (node.type === 'Call') {
return {
type: 'CallExpression',
callee: {
type: 'Identifier',
name: node.name,
},
arguments: node.arguments.map((value) => nodeToExpr(value)),
};
} else if (node.type === 'Array') {
return {
type: 'ArrayExpression',
elements: node.elements.map((value) => nodeToExpr(value)),
};
} else {
return {
type: 'ObjectExpression',
properties: node.properties.map(({ key, value }) => ({
type: 'ObjectProperty',
key: {
type: 'StringLiteral',
value: key,
},
value: nodeToExpr(value),
computed: false,
shorthand: false,
})),
};
}
};
5 changes: 5 additions & 0 deletions packages/babel-plugin/src/commonConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export type InputTransform = {
source: string;
from: string;
to: string;
};
2 changes: 0 additions & 2 deletions packages/babel-plugin/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,4 @@ export * from './preTransform';
export * from './transform';
export * from './preTransformPlugin';
export * from './transformPlugin';
export type { PreTransformOptions } from './preTransformPlugin';
export type { TransformOptions } from './transformPlugin';
export type { TransformOptions as BabelOptions } from '@babel/core';
13 changes: 7 additions & 6 deletions packages/babel-plugin/src/preTransform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,32 @@ import { transformAsync as babelTransform } from '@babel/core';
import type { TransformOptions as BabelOptions } from '@babel/core';
// @ts-expect-error type
import typescriptSyntax from '@babel/plugin-syntax-typescript';
import type { PreTransformOptions } from './preTransformPlugin';
import { preTransformPlugin } from './preTransformPlugin';

type Options = {
filename: string;
preTransformOptions: PreTransformOptions;
babelOptions?: BabelOptions;
transform: Record<string, unknown>;
babel?: BabelOptions;
};

type Metadata = { isTransformed: boolean };
type Result = [string, Metadata];

export const preTransform = async (
code: string,
{ filename, preTransformOptions, babelOptions = {} }: Options,
options: Options,
): Promise<Result> => {
const babelOptions = options.babel || {};
const transformOptions = options.transform || {};
const result = await babelTransform(code, {
filename,
filename: options.filename,
caller: { name: 'kaze' },
babelrc: false,
configFile: false,
compact: false,
...babelOptions,
plugins: [
[preTransformPlugin, preTransformOptions],
[preTransformPlugin, transformOptions],
[typescriptSyntax, { isTSX: true }],
...(babelOptions.plugins || []),
],
Expand Down
Loading

0 comments on commit b7243aa

Please sign in to comment.