@ppldo/vanillin
v0.2.0
Published
Converting tool for migrate css modules code base to vanilla-extract.
Downloads
11
Readme
vanillin - migrate to vanilla-extract in hour (eventually)
CLI-tool for transpiling css modules to vanilla-extract.
When it doesn't possible to transpile automatically, vanillin will add a TODO comment.
input:
.wrap {
display: flex;
flex-direction: column;
width: 100%;
padding-top: 14px;
white-space: pre-wrap;
overflow-wrap: break-word
}
.wrap.active {
cursor: pointer;
}
.wrap a {
color: var(--color-0);
}
.wrap a:hover {
color: var(--color-1, pink);
}
output:
import {style, globalStyle} from "@vanilla-extract/css";
import {vars} from "../vars";
export const wrap = style({
display: "flex",
flexDirection: "column",
width: "100%",
paddingTop: "14px",
whiteSpace: "pre-wrap",
overflowWrap: "break-word"
});
export const active = style({
selectors: {[`${wrap}&`]: {cursor: "pointer"}}
});
globalStyle(`${wrap} a`, {color: vars.color0});
globalStyle(`${wrap} a:hover`, {color: fallbackVar(vars.color1, "pink")});
Install:
yarn add -D @ppldo/vanillin
npm install -D @ppldo/vanillin
Usage
Internally vanillin uses PostCSS parser, which expects spec-compliant CSS. If you use preprocessor, you need to preprocess your file before use vanillin.
Next examples assume your project uses PostCSS. For another preprocessor consults with their CLI documentation.
Note: don't forget to install postcss-cli with proper version
yarn add -D postcss-cli@YOUR_POSTCSS_VERSION
npm install -D postcss-cli@YOUR_POSTCSS_VERSION
Try to convert one file. Pass css content to stdin of vanillin, result will be printed stdout which you can redirect to new file.
postcss styles.module.css | vanillin > styles.css.ts
Change style imports:
// before
import styles from './styles.module.css'
// after
import * as styles from './styles.css'
Prettify generated file with your code formatter.
Fix all TODO comments and possible compilation errors in generated file styles.css.ts
Make sure code semantic doesn't change. Make bug reports if so.
Now you can delete original file:
rm styles.module.css
Congrats! You just started migration to vanilla-extract.
Repeat it until you (and we) will be sure about codegen quality, and then go to bulk converting.
Bug reports
Make sure you use the latest version of vanillin.
If generated code changed semantic of original code and don't contain TODO comments about it, please let us know by sending bug report with preprocessed file (NOT ORIGINAL ONE) and generated file.
Please, paste output of this command to bug report:
PREPR=$(postcss styles.module.css) &&
printf "IN:\n\n$PREPR\n\nOUT:\n\n" &&
printf "$PREPR" | vanillin
Also add vanillin version and desired output.
Variables
Note: If you want to convert variables.css to vanilla-extract variables, don't forget to disable the CSS processor plugin for translating custom properties.
Given such CSS variables:
:root {
--color-black: #000;
--color-0: #F44336;
--color-0-1: #FF8575;
--color-gradient-0: linear-gradient(0deg, var(--color-0) 0%, var(--color-0-1) 100%);
--color-red: red;
--color-1: #C2185B;
--color-1-1: #E33594;
--color-gradient-1: linear-gradient(0deg, var(--color-1) 0%, var(--color-1-1) 100%);
}
You should create file vars.ts
with vars
export and all variables translated to camelCase:
vars.ts
import {createGlobalTheme} from '@vanilla-extract/css'
const colorBlack = '#000'
const color0 = '#F44336'
const color01 = '#FF8575'
const colorGradient0 = `linear-gradient(0deg, ${color0} 0%, ${color01} 100%)`
const colorRed = 'red'
const color1 = '#C2185B'
const color11 = '#E33594'
const colorGradient1 = `linear-gradient(0deg, ${color1} 0%, ${color11} 100%)`
export const vars = createGlobalTheme(':root', {
colorBlack,
color0,
color01,
colorGradient0,
colorRed,
color1,
color11,
colorGradient1
})
You can remember it path to shell variable:
VARS=$(realpath vars.ts)
Then when you run vanillin on your regular css pass this path under vars
flag.
ATTENTION: You should run this command from directory, where styles.css.ts
will be placed!
postcss styles.module.css | vanillin --vars $VARS > styles.css.ts
Vanillin will replace variables from theme to refs. All unknown variables will be left as is.
input:
.root {
--color-0: purple;
--color-some: green;
color: var(--color-0, red);
background: var(--color-gradient-0);
border: solid 1px var(--color-brand);
}
output:
import {style} from "@vanilla-extract/css";
import {vars} from '../vars.ts'
export const root = style({
vars: {
[vars.color0]: 'purple',
'--color-some': 'green',
},
color: fallbackVar(vars.color0, "red"),
background: vars.colorGradient0,
border: 'solid 1px var(--color-brand)',
})
Bulk converting
Call vanillin with two arguments: directory with preprocessed css files and your output directory.
Vanillin does recursive search css files in directory and writes it to output directory with the same structure. For example styles.css from ./build/some-component/styles.css will be generated in ./src/some-component/styles.css.ts (full project).
We assume your original files named styles.module.css
,then names of generated files will be styles.modules.css.ts
Select project part which you are going convert:
FOLDER=src
Generate styles.css.ts with vanillin:
postcss "$FOLDER/**/styles.module.css" --base $FOLDER --dir build
vanillin --bulk build $FOLDER
rm -rf build
You can use vanillin --bulk with vars
flag.
vanillin --bulk cssDir targetDir --vars vars.ts
You can bulk replace style imports with IDE or use some regexp:
find $FOLDER -name '*.tsx' -type f -print0 |
xargs -0 sed -E -i "s#import\s+(\w+)\s+from\s+.\./styles\.module\.css.#import * as \1 from './styles.module.css'#"
Fix all TODO comments and possible compilation errors in generated files.
Now you can delete original files:
find $FOLDER -name "styles.module.css" -exec rm {} \;
Caveats
All kebab-case class names will be transformed to camelCase, with TODO comment, because of js syntax
In case of circular dependencies (or forward refs) in selectors, some marker classes will be added.
:local() pseudo from css modules spec not supported.
/*localB and localC will not be local*/
.localA :global global-b :local(localC) :local .localB {
}
For all not implemented yet features from CSS and CSS Modules look here: https://github.com/ppldo/vanillin/issues?q=is%3Aissue+is%3Aopen+label%3Atodo