Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/lttb/postjss
Use the power of PostCSS in compiling with JSS
https://github.com/lttb/postjss
babel babel-plugin css-in-js jss postcss styled-components
Last synced: 4 days ago
JSON representation
Use the power of PostCSS in compiling with JSS
- Host: GitHub
- URL: https://github.com/lttb/postjss
- Owner: lttb
- License: mit
- Created: 2017-02-18T20:23:42.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2017-06-18T17:38:39.000Z (over 7 years ago)
- Last Synced: 2024-10-31T17:06:30.176Z (12 days ago)
- Topics: babel, babel-plugin, css-in-js, jss, postcss, styled-components
- Language: JavaScript
- Homepage:
- Size: 159 KB
- Stars: 40
- Watchers: 3
- Forks: 4
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# PostJSS
This project allows to use PostCSS features (plugins, syntaxes etc.) for compiling to JSS object via babel, so you can take benefits from both.
+ [Advantages](#advantages)
+ [Installation](#installation)
+ [Babel Plugin Options](#babel-plugin-options)
+ [How it works?](#how-it-works)
- [As tagged template literal](#as-tagged-template-literal)
- [As separate styles file](#as-a-separate-styles-file)
+ [Custom PostJSS Syntax](#custom-postjss-syntax)
+ [Hot Module Replacement](#hot-module-replacement)
+ [Linting](#linting)
+ [Rebuild optimization](#rebuild-optimization)
+ [Runtime Usage (sync and async)](#runtime)## Advantages
- With PostJSS very easy to start using JSS from SASS/SCSS/PostCSS etc. All you need - update your components and use PostJSS Babel Plugin
- You can continue use your favorite syntax and the power of PostCSS plugins (stylelint, sort-order etc.), but take advantages of CSS in JS - awesome!
- You can write styles in styled-components way, css-modules way or in both - the choice is yours
- You can build your project just with babel
- Static compilation, no runtime overhead!
- You can use any library that is compatible with the JSS-object, not only JSS## Installation
```sh
npm i postjss -S
```## Babel Plugin Options
This plugin uses [postcss-load-config](https://github.com/michael-ciniawsky/postcss-load-config), so you **need** to set **PostCSS options** in *package.json/.postcssrc/postcss.config.js/.postcssrc.js*
Plugin Options:
- `extensionsRe`: `String` - RegExp for extensions. By default `(c|(s[ac]?))ss` - for css, sass, scss, sss
- `namespace`: `String` - Set your custom namespace for tagged literals. By default its `postjss`
- `throwError`: `Boolean` - Plugin will throw an error and stop transpiling, if error caused by PostCSS (eg `styling` errors). By default `false`*.babelrc* example:
```js
plugins: [
[
'postjss/babel', {
extensionsRe: 's[ac]?ss',
namespace: 'customPostJSSNamespace',
throwError: false
}
]
]
```## How it works?
Please check the [counter example](https://github.com/lttb/postjss/tree/master/examples/counter)
- [Separate styles example](https://github.com/lttb/postjss/blob/master/examples/counter/src/client/containers/App/index.jsx)
- [Tagged template literal example](https://github.com/lttb/postjss/blob/master/examples/counter/src/client/components/Counter/index.jsx)![postjss example](https://cloud.githubusercontent.com/assets/11135392/23830255/903ece9c-0717-11e7-8d48-a0b7bf023da9.jpg)
### As tagged template literal
Babel PostJSS plugin transforms tagged literal into the JSS-object by PostCSS, like:
```jsx
const styles = postjss`
.${selector}
left: ${() => 0}margin-${marginType}: 10px
transition: ${'opacity'} 1s
color: ${color}
&::before
content: '😱'
`
```After transpile it would look like:
```jsx
const styles = {
[selector]: {
left: () => 0,
[`margin-${marginType}`]: '10px',
transition: 'opacity 1s',
color: color,
'&::before': {
content: "'😱'"
}
}
}
```You are free to use all PostCSS feature and custom `postjss syntax` (see bellow)
> Notice that if you are using `stylelint` and `property-no-unknown` rule, you need to set an option like this (it's required for current postjss parser implementation):
> `property-no-unknown: [true, { ignoreProperties: ['/\$\^var__/'] }]`### As a separate styles file
After transpiling imported styles inlined into variable (import name) as a function expression, that accepts an object with arguments and returns a JSS object with styles with arguments usage. Notice that arguments name has uniq scope, so you need not worry about names conflict.
Say you have this *styles.sss* (with SugarSS i.e.):
```stylus
.lang-list
display: flexmargin: 0
padding: 0list-style: none
.lang
margin-right: 10px
padding: 5px&.current
border-bottom: 1px solid red
```And a component using it:
```jsx
import style from './style.sss'
```After babel transpiling your component become as:
```jsx
const styles = function (izexozk) {
izexozk = Object.assign({}, izexozk);
return {
"langList": {
"display": "flex",
"margin": "0",
"padding": "0",
"listStyle": "none"
},
"lang": {
"marginRight": "10px",
"padding": "5px",
"&.current": {
"borderBottom": "1px solid red"
}
}
};
}
```And you can use this with JSS like:
```jsx
injectSheet(style())
```## Custom PostJSS Syntax
You can use specific syntax for some JSS-features in your CSS:
- `/JS Code/` - you can place JS-block wrapped by `/` in every property value
```stylus
.app
display: /({ visible }) => visible ? 'block' : 'none'/
```
- `$^variableName` - allows you to use variables passed as arguments to the style function
```stylus
.app
background-color: /^color || $color/
```
- `defaults` block for default values - it would be default for accepting args
```stylus
defaults:
prop: /^prop || 'test'/
selector: ''
```
- `$^propertyName` - for custom property/selector names
```stylus
.app
$^prop: 100vw$^selector:
display: none
```## Hot Module Replacement
For tagged literals HMR supported out of the box. But for separate styles you need to use `postjss hot-loader` with webpack:
Notice, that you need to set this loader **after** `babel-loader`.```js
use: [
'babel-loader',
'postjss/webpack/hot-loader',
]
```## Linting
You can use [stylelint](https://github.com/stylelint/stylelint) for linting and [postcss-reporter](https://github.com/postcss/postcss-reporter) for warnings and errors.
So with PostJSS it works like a charm:### For CSS files:
![sss](https://cloud.githubusercontent.com/assets/11135392/23332790/9ee8325e-fb90-11e6-848d-ce4734814b39.gif)
### For tagged literals:
![postjss](https://cloud.githubusercontent.com/assets/11135392/23332827/1d705f20-fb91-11e6-8b13-146a65cf3ed5.gif)
## Rebuild optimization
Let's say you use some tool for linting. But if you set `throwError: true` for `postjss`, it will cause a babel transpilling error, so babel will have to build other files next time, not only fixed.
You can set `throwError: false` for dev building to avoid this, and use `postjss report-loader` for webpack (set this loader **before** `babel-loader`:
```js
use: [
'postjss/webpack/report-loader',
'babel-loader',
]
```This will break webpack compiling if there are some errors in PostJSS, but not babel transpiling. And then babel needs to rebuild only fixed file.
## Runtime
You can use this module in runtime without babel-plugin.
- it works just on node.js
- you can use async and sync versions, so async is more preferable, because sync is blocking your process
- and it may cause some performance issuesSo I recommend this usage only for tests and first steps :)
Sync version:
```jsx
import postjss from 'postjss'console.log(postjss`
.app
color: red
`)// output: { app: { color: 'red' } }
```Async version:
```jsx
import postjssAsync from 'postjss/runtime/async';(async () => {
const postjss = await postjssAsyncconsole.log(await postjss`
.app
color: red
`)// output: { app: { color: 'red' } }
})()```
You may also be interested in this project for runtime usage: [jss-from-postcss](https://github.com/axept/jss-from-postcss)
## Full Example
*style.sss*
```stylus
@import 'vars.sss'
@import 'mixins.sss'$color: 'green'
:root
--color: $colordefaults:
prop: /$^prop || 'test'/
selector: ''.app
position: absolute
top: 0
left: 0display: /({ name }) => name + 1 + $color-from-import/
overflow-y: auto
flex-direction: columnwidth: 100vw
height: 100vhcolor: var(--color)
background-color: /$^value || $color/$^prop: 100vw
$^selector:
display: none.content
@mixin containerpadding: 20px
.header
border-bottom: 1px solid #eee
```*component.jsx*
```jsx
const style = function (izezix) {
izezix = Object.assign({
"prop": izezix.prop || 'test',
"selector": "''"
}, izezix);
return {
"app": {
"position": "absolute",
"top": "0",
"left": "0",
"display": function ({
name
}) {
return name + 1 + 'black';
},
"overflowY": "auto",
"flexDirection": "column",
"width": "100vw",
"height": "100vh",
"color": "green",
"backgroundColor": izezix.value || 'green',
[izezix.prop]: "100vw"
},
[izezix.selector]: {
"display": "none"
},
"content": {
"position": "absolute",
"margin": "0 auto",
"&::before": {
"content": "''"
},
"padding": "20px"
},
"header": {
"borderBottom": "1px solid #eee"
}
};
}
```## Links
* [JSS](https://github.com/cssinjs/jss) - Great lib for CSS in JS
* [PostCSS](https://github.com/postcss/postcss) - Awesome tool for customizable style transform## License
MIT