ts-astroturf-tools v0.16.0
ts-astroturf-tools beta! 🚧
This package improves DX for astroturf users.
Compatible with astroturf@>=1.0.0-beta, typescript@>=4 and webpack@>=5! For compatibility with astroturf@>=0.9 <= 1, use ts-astroturf-tools@<=0.14.3.
Installation
yarn add -D ts-astroturf-toolsnpm i --save-dev ts-astroturf-toolsOverview
Features are divided in three major categories:
- linaria-like functionality
- diagnostic messages
- autocomplete for identifiers
linaria-like functionality
Use variables declared in other modules inside your CSS:
// * before // impossible :( // * after // colors.tsx export const RED = 'red'; // index.tsx import { css } from 'astroturf'; import { RED } from './colors'; const btn = css` color: ${RED}; `; // works for 'stylesheet' and ... import { stylesheet } from 'astroturf'; const { a } = stylesheet` .a { color: ${RED}; } `; // .. styled components too! import styled from 'astroturf/react'; const Button = styled.button` color: ${RED}; `;
Diagnostic messages
These messages are available if you use plain stylesheet tag from astroturf.
There are two types of diagnostic messages:
warnings in case there is unused CSS
Available via:
- webpack loader
- babel plugin
- TS Language Service Plugin (VS Code)
import { stylesheet } from 'astroturf'; const { btn } = stylesheet` .btn { color: red; } .active { color: green; } `;The warning will look like this:
In VS Code the warning will become a suggestion:

errors in case there is missing CSS
Available via:
- webpack loader
- babel plugin
- TS Language Service Plugin (VS Code)
import { stylesheet } from 'astroturf'; const { btn, active } = stylesheet` .btn { color: red; } `;The error will look like this:
In VS Code:

Autocomplete for identifiers
Available via:
- TS Language Service Plugin (VS Code)

Quick summary of tools and their respective features
| Tool | Diagnostic messages | Autocomplete for identifiers | linaria-like functionality |
|---|---|---|---|
| TS Language Service Plugin | ✅ | ✅ | N/A |
| webpack loader | ✅ | N/A | ✅ optional |
| babel plugin | ✅ | N/A | ❌ |
| TS transformer | ❌ | N/A | ✅ |
N/A- not applicable
Configuration
TS Language Service Plugin
Add
ts-astroturf-toolsas a plugin to yourtsconfig.json:{ "compilerOptions": { "plugins": [ { "name": "ts-astroturf-tools" } ] }, "files": ["src/index.tsx"], "exclude": ["node_modules"] }Don't forget to switch to workspace typescript instance:

TS transformer:
raw TypeScript
You should use ttypescript as a compiler.
Add
ts-astroturf-tools/transformeras a transformer to yourtsconfig.json:{ "compilerOptions": { "plugins": [ { "transform": "ts-astroturf-tools/transformer" } ] }, "files": ["src/index.tsx"], "exclude": ["node_modules"] }webpack / ts-loader
const transformer = require('ts-astroturf-tools/transformer'); module.exports = { // ... module: { // ... rules: [ { test: /\.tsx$/, use: { loader: 'ts-loader', options: { // ... getCustomTransformers: () => ({ before: [transformer()], }), }, }, }, ], }, };
webpack loader
Add
ts-astroturf-tools/loaderas a first loader for ts-files:module.exports = { // ... module: { rules: [ // ... { test: /\.tsx?$/, use: [ // works with any typescript loader 'ts-loader', 'astroturf/loader', 'ts-astroturf-tools/loader', ], }, ], }, };Available options:
Option name Type Description linariabooleanEnables linaria-like functionality.Defaults:
module.exports = { // ... module: { rules: [ // ... { test: /\.tsx?$/, use: [ // works with any typescript loader 'awesome-typescript-loader', 'astroturf/loader', { loader: 'ts-astroturf-tools/loader', options: { linaria: false, }, }, ], }, ], }, };Babel plugin
Add
ts-astroturf-tools/babel-pluginto your babel plugins:module.exports = { presets: ['@babel/env', '@babel/preset-react'], plugins: ['ts-astroturf-tools/babel-plugin'], };
Known limitations
Regex-based parser is used to extract CSS class names.
Limited support for imports
Supported extensions:
.tsx,.ts,.js.Files must not contain side-effects, import other heavy modules and / or libraries and code that must be transpiled.
This is ok:
// a.js export const redColor = 'red'; // b.js export const greenColor = 'green'; export { redColor } from './a.js'; // index.js import { greenColor, redColor } from './a.js'; import styled from 'astroturf/react'; const Button = styled.button` color: ${redColor}; background: ${greenColor}; `;This is not ok and will most likely result in an error:
// a.js import * as React from 'react'; import image from './someImage.png'; export const redColor = 'red'; export const Something = () => ( <div style={{ background: `url(${image});` }}>Hello!</div> ); // b.js export const greenColor = 'green'; export { redColor } from './a.js'; // index.js import { greenColor, redColor } from './a.js'; import styled from 'astroturf/react'; const Button = styled.button` color: ${redColor}; background: ${greenColor}; `;Performance issues with imports (this issue is in progress of being fixed)
As of now, files are parsed and executed for each encountered import.
For example:
// a.js export const RED = 'red'; // b.js export { RED } from './a'; export const GREEN = 'green'; // ComponentA.js import styled from 'astroturf/react'; import { GREEN } from './b'; export const ComponentA = styled.div` color: ${GREEN}; `; // ComponentB.js import styled from 'astroturf/react'; import { RED } from './b'; export const ComponentB = styled.div` color: ${RED}; `;In this case both
a.jsandb.jswill be parsed and executed twice (first forComponentA.jsand then forComponentB.js). Keep this in mind and try to avoid creating large dependency trees.Limited support for interpolations
const WIDTH = '500px'; // ok const { a } = stylesheet` .a { width: ${WIDTH}; } `;const NAME = 'someClass'; // error // vvvvvvvvv const { someClass } = stylesheet` .${NAME} { color: red; } `;Only plain CSS is supported.
Basic features of SASS/LESS/etc. may work:
// simple nesting is ok const { someClass, anotherClass } = stylesheet` .someClass { color: red; &.anotherClass { border: 1px solid black; } } `;Advanced features will most probably not work:
// error! // vvvvvvvvvvvv const { someClass, anotherClass } = stylesheet` @name: anotherClass; .someClass { color: red; &.@{name} { color: black; } } `;It is not possible to show errors in case destructuring is not used:
const classes = stylesheet` .a { color: red; } `; console.log(a.b); // <- no errorThis is not hugely important because you should always use
cssin the first place.
3 years ago
4 years ago
4 years ago
4 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago