Giter Club home page Giter Club logo

postcss-jsx's Introduction

PostCSS JSX Syntax

NPM version Travis Travis Codecov David

PostCSS syntax for parsing CSS in JS literals:

Getting Started

First thing's first, install the module:

npm install postcss-syntax postcss-jsx --save-dev

Use Cases

const postcss = require('postcss');
const stylelint = require('stylelint');
const syntax = require('postcss-syntax');
postcss([stylelint({ fix: true })]).process(source, { syntax: syntax }).then(function (result) {
	// An alias for the result.css property. Use it with syntaxes that generate non-CSS output.
	result.content
});

input:

import glm from 'glamorous';
const Component1 = glm.a({
	flexDirectionn: 'row',
	display: 'inline-block',
	color: '#fff',
});

output:

import glm from 'glamorous';
const Component1 = glm.a({
	color: '#fff',
	display: 'inline-block',
	flexDirectionn: 'row',
});

Advanced Use Cases

Add support for more css-in-js package:

const syntax = require('postcss-syntax')({
	"i-css": (index, namespace) => namespace[index + 1] === "addStyles",
	"styled-components": true,
});

See: postcss-syntax

Style Transformations

The main use case of this plugin is to apply PostCSS transformations to CSS code in template literals & styles as object literals.

postcss-jsx's People

Contributors

abalmos avatar ai avatar bpscott avatar gucong3000 avatar hudochenkov avatar mccleanp avatar ota-meshi avatar vankop avatar web-padawan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

postcss-jsx's Issues

Support emotion 10?

Should this support the emotion 10 css prop out of the box? It appears that it does not, but it is also difficult to confirm that my setup is correct. I have been trying to verify and/or add support, but with limited success. If it is not yet supported, could you point me in the right direction to add it?

Postcss-jsx doesn't seem to work with emotion & emotion-theming

Consider the following code snippet:

import React from 'react';

const style = theme => ({
  width: 100,
  padding: 40,
  margin: 60,
  color: theme.color.primary,
});

const style2 = {
  width: 100,
  padding: 40,
  margin: 60,
};

const Component = () => (
    <div css={style}>
      some other text
     <span css={style2}>Hello</span>
    </div>);

When passed into postcss-jsx through styelint, the styles in style function are ignored. However the object styles are processed.

Will this issue be resolved anytime soon?

Add astroturf support

css-literal-loader is an amazing CSS-in-JS solution since it has zero runtime and compiles by Babel during deploy.

As result, it is blazing fast and 100% compatible with PostCSS ecosystem. This is why it is “official” CSS-in-JS for PostCSS 😄.

@gucong3000 I can send PR, but I am not sure how to write tests.

"Unknown word" syntax error for multiline arrow function

When using a multiline arrow function "Unknown word" error is thrown.

I'm using the latest [email protected] which uses [email protected]:

> stylelint "**/*.styled.js"

Button.styled.js
 8:3  ✖  Unknown word   CssSyntaxError
import { css } from 'styled-components';

export const buttonStyles = css`
  border-radius: 4px;

  cursor: pointer;

  ${(props) => {
    return props.small && 'padding: 30px;';
  }}
`;

This issue is similar to gucong3000/postcss-styled#37.

Incorrect parsing/stringifying for nested tagged template literals

Syntax incorrectly parse, and then stringify complicated CSS-in-JS, where tagged template literal has css`` template literal inside.

Input:

import styled, { css } from 'styled-components';
const Message = styled.p`
	padding: 10px;
	${(props) => css`
		color: #b02d00;
	`}
	${(props2) => css`
		border-color: red;
	`}
`;

Output:

import styled, { css } from 'styled-components';
const Message = styled.p`
	padding: 10px;
	${(props) => css`
		color: #b02d00;
	`}
	${(props2) => css`
		border-color: red;
	`}

		color: #b02d00;
	`}
	${(props2) => css`
		border-color: red;
	`}
`;

The problem is in multiple places: in this package and in postcss-syntax .

Code parsed acceptable for running linter over the resulting AST, but not to stringify it back. After parsing there are three Root nodes:

First root is styled.p template literal:

Second root is the first css template literal:

Third root is the second css template literal:

This part is correct, but the problem in details.

Stringifying is initiated in postcss-syntax. All roots are “concatenated” together.

  1. Nodes with type “literal” in the first node are preserved and then other two roots, which are parsed literals from the first root, are glued. That's why duplication happens. When PostCSS plugin is runned over input like above, type: "literal" nodes are not being processed by plugins and copied as is. While the following roots are processed.
  2. For some reasons second root has empty raws.beforeStart, when the third root has correct raws.beforeStart. Second root should have not-empty raws.beforeStart.

Screenshots above made in debugger in VS Code, I put breakpoint on this line and printed document.nodes. It's right before stringifying.

I've added failing test cases #54.

Consider to include abilities of stylelint-processor-styled-components

Hi, I am one of maintainers of stylelint-processor-styled-components. Before stylelint supports syntax: css-in-js, users lint styles with the processor.

As discussed in stylelint-processor-styled-components#278, postcss-jsx analyzes the whole AST more completely and can give more accurate replacements for tagged template interpolations, so hope it can include as much as possible abilities of stylelint-processor-styled-components and make the processor deprecated.

Now main differences between them are, which are listed with test files names of stylelint-processor-styled-components,

  1. not require keeping closing backtick on base indentation level: ignore-rule-comments, see styled-compoents' document
  2. not throw errors for invalid css: hard, nofiles
  3. not support ignore comments: ignore-rule-comments
  4. not support interpolation-tagging: interpolation-tagging
  5. not support options: options, real-world
  6. will throw unexpected errors if the interpolation is a declaration: interpolations

Not all of them are appropriate to implement in postcss-jsx, but if we really decided to deprecate the processor with postcss-jsx, we should write F.A.Q or some documents for users to migrate smoothly.

Throws an errror “Cannot read property 'file' of undefined”

'use strict';
const postcssJsx = require('postcss-jsx'); // v0.32.0

postcssJsx.parse("let a;let a;", {
  from: 'source.ts'
});
$ node run.js
TypeError: Cannot read property 'file' of undefined
    at Scope.checkBlockScopedCollisions (/Users/shinnn/example/node_modules/@babel/traverse/lib/scope/index.js:347:22)
    at Scope.registerBinding (/Users/shinnn/example/node_modules/@babel/traverse/lib/scope/index.js:506:16)
    at Scope.registerDeclaration (/Users/shinnn/example/node_modules/@babel/traverse/lib/scope/index.js:454:14)
    at Object.Declaration (/Users/shinnn/example/node_modules/@babel/traverse/lib/scope/index.js:125:12)
    at NodePath._call (/Users/shinnn/example/node_modules/@babel/traverse/lib/path/context.js:53:20)
    at NodePath.call (/Users/shinnn/example/node_modules/@babel/traverse/lib/path/context.js:40:17)
    at NodePath.visit (/Users/shinnn/example/node_modules/@babel/traverse/lib/path/context.js:88:12)
    at TraversalContext.visitQueue (/Users/shinnn/example/node_modules/@babel/traverse/lib/context.js:118:16)
    at TraversalContext.visitMultiple (/Users/shinnn/example/node_modules/@babel/traverse/lib/context.js:85:17)
    at TraversalContext.visit (/Users/shinnn/example/node_modules/@babel/traverse/lib/context.js:144:19)

Styled with types not recognized

Emotion and styled-components supports typing of props by specified generic type:
const Component = styled.div<{ someProp: string }>
or
const Component = styled.div<ComponentProps>

But the text in template literal it's not recognized as css by postcss-jsx.

Why put @babel/core in dependencies?

My project is depend on babel v6 and stylelint. The stylelint dependence on postcss-jsx.

If I install styleint (which will also install postcss-jsx), it will install @babel/core.... And my project build failed. The error is below:

> cross-env NODE_ENV=production webpack --config scripts/webpack.config.prod.babel.js --display-modules

/cloud/source_code/node_modules/[email protected]@webpack-cli/bin/cli.js:244
				throw err;
				^

Error: Plugin/Preset files are not allowed to export objects, only functions. In /cloud/source_code/node_modules/babel-preset-stage-2/lib/index.js
    at createDescriptor (/cloud/source_code/node_modules/_@[email protected]@@babel/core/lib/config/config-descriptors.js:178:11)
    at items.map (/cloud/source_code/node_modules/_@[email protected]@@babel/core/lib/config/config-descriptors.js:109:50)
    at Array.map (<anonymous>)
    at createDescriptors (/cloud/source_code/node_modules/_@[email protected]@@babel/core/lib/config/config-descriptors.js:109:29)
    at createPresetDescriptors (/cloud/source_code/node_modules/_@[email protected]@@babel/core/lib/config/config-descriptors.js:101:10)
    at presets (/cloud/source_code/node_modules/_@[email protected]@@babel/core/lib/config/config-descriptors.js:47:19)
    at mergeChainOpts (/cloud/source_code/node_modules/_@[email protected]@@babel/core/lib/config/config-chain.js:315:26)
    at /cloud/source_code/node_modules/_@[email protected]@@babel/core/lib/config/config-chain.js:278:7
    at buildRootChain (/cloud/source_code/node_modules/_@[email protected]@@babel/core/lib/config/config-chain.js:118:22)
    at loadPrivatePartialConfig (/cloud/source_code/node_modules/_@[email protected]@@babel/core/lib/config/partial.js:57:55)
    at loadFullConfig (/cloud/source_code/node_modules/_@[email protected]@@babel/core/lib/config/full.js:43:39)
    at loadOptions (/cloud/source_code/node_modules/_@[email protected]@@babel/core/lib/config/index.js:27:36)
    at OptionManager.init (/cloud/source_code/node_modules/_@[email protected]@@babel/core/lib/index.js:215:36)
    at compile (/cloud/source_code/node_modules/_@[email protected]@@babel/register/lib/node.js:61:42)
    at compileHook (/cloud/source_code/node_modules/_@[email protected]@@babel/register/lib/node.js:102:12)
    at Module._compile (/cloud/source_code/node_modules/[email protected]@pirates/lib/index.js:77:29)
    at Module._extensions..js (module.js:646:10)
    at Object.newLoader [as .js] (/cloud/source_code/node_modules/[email protected]@pirates/lib/index.js:88:7)
    at Module.load (module.js:554:32)
    at tryModuleLoad (module.js:497:12)
    at Function.Module._load (module.js:489:3)
    at Module.require (module.js:579:17)
    at require (/cloud/source_code/node_modules/[email protected]@v8-compile-cache/v8-compile-cache.js:159:20)
    at WEBPACK_OPTIONS (/cloud/source_code/node_modules/[email protected]@webpack-cli/bin/convert-argv.js:133:13)
    at requireConfig (/cloud/source_code/node_modules/[email protected]@webpack-cli/bin/convert-argv.js:135:6)
    at /cloud/source_code/node_modules/[email protected]@webpack-cli/bin/convert-argv.js:142:17
    at Array.forEach (<anonymous>)
    at module.exports (/cloud/source_code/node_modules/[email protected]@webpack-cli/bin/convert-argv.js:140:15)
    at yargs.parse (/cloud/source_code/node_modules/[email protected]@webpack-cli/bin/cli.js:241:39)
    at Object.parse (/cloud/source_code/node_modules/[email protected]@yargs/yargs.js:563:18)

I don't know why cause this problem, but I think @babel/core should in devDependencies, right?

styled() with options

let Button = styled(Clickable, { allowAs: true })`
  position: relative;
  display: flex;
})

postcss-jsx parses is as allow-as: true CSS, but it is allowed syntax in astroturf to enable <Button as={Link}>

jsx属性拓展

JSXAttribute: (path) => {
if (/^(?:css|style)$/.test(path.node.name.name)) {
addObjectJob(path.get("value.expression"));
}
},

目前看只支持css合style属性,能否增加一个配置项去解析自定义的props,一些组件传样式过去还挺常见的,比如bodyStyle

`zIndex` property is converted to `-z-index`

JS:

<div
  style={{
    zIndex: "1"
  }}
>

stylelint config:

{
  "rules": {
    "property-whitelist": ["z-index"]
  }
}

stylelint warning (note the extra leading hyphen in the property name):

Unexpected property "-z-index" (property-whitelist)"

Expected no violation.

Do not add fake rules around CSS-in-JS blocks

JS:

let rotating = keyframes`
  100% {
    transform: rotate(360deg);
  }
`

let resizing = keyframes`
  100% {
    stroke-dasharray: 89, 200;
    stroke-dashoffset: -124px;
  }
`

Stylelint output:

components/loader.js
 27:3  ✖  Unexpected duplicate selector "100%", first    no-duplicate-selectors
          used at line 13

Suggestion fix:

  1. Wrap let A = styled.div() to A { }
  2. Wrap let anim = keyframes() to @keyframes anime { }

ParseError - interpolations with "$"

This syntax cannot parse selectors with the "$" character:

import { styled } from '@brandonkal/linaria/react'

interface CardProps {
  grid$?: boolean
}

export const Card = (p => styled.div<CardProps>`
  &${[p.grid$]} {
    padding: 24px;
  }
`)({} as CardProps)

Provide webpack example

Hello,

First of all, thank you for maintaining this library, it seems like a very interesting concept.

I started looking into solutions like this after I discovered stylis, which is used by many CSS-in-JS libraries like styled-components and emotion, does not support CSS Grid. I discovered postcss-jsx and thought it may have a nice synergy with Autoprefixer's grid support, along with the plethora of other plugins like postcss-preset-env and stylelint.

Having spent two days trying to get it to work with Webpack and postcss-loader I am at the end of my ropes, unfortunately. There is very little documentation on the matter, so my first question is does postcss-jsx work with Webpack (postcss-loader) and babel?

Is there any chance for a more thorough description of how to get this project working with webpack and for example autoprefixer? Maybe an example project? Or at least a hint on where I may be in the wrong?

If I manage to get this working I will write a long blog post detailing how to set it up with webpack and parcel (not sure if parcel will work though). That post may make it easier for the next person coming along to use this project.

If you're interested in my progress, it is over at the postcss-and-styled-components repo. Currently no transformations are applied at all.

Thanks for your time, you rock

Still maintained?

If not, maybe one of the bigger communities (stylelint, styled-components, emotion, other css-in-js projects, a coalition of multiple communities) can take over?

Cannot read property 'objectExpression' of undefined

'use strict';

const postcss = require('postcss'); // v6.0.22
const postcssJsx = require('postcss-jsx'); // v0.10.0

(async () => {
  try {
    await postcss().process('x().y(z => {});', {
      syntax: postcssJsx,
      from: 'source.jsx'
    });
  } catch (err) {
    console.error(err);
  }
})();
$ node example.js
TypeError: Cannot read property 'objectExpression' of undefined
    at path.get.forEach (/Users/example/node_modules/postcss-jsx/extract.js:123:12)
    at Array.forEach (<anonymous>)
    at enter (/Users/example/node_modules/postcss-jsx/extract.js:114:28)
    at NodePath._call (/Users/example/node_modules/@babel/traverse/lib/path/context.js:65:20)
    at NodePath.call (/Users/example/node_modules/@babel/traverse/lib/path/context.js:36:14)
    at NodePath.visit (/Users/example/node_modules/@babel/traverse/lib/path/context.js:100:12)
    at TraversalContext.visitQueue (/Users/example/node_modules/@babel/traverse/lib/context.js:142:16)
    at TraversalContext.visitSingle (/Users/example/node_modules/@babel/traverse/lib/context.js:102:19)
    at TraversalContext.visit (/Users/example/node_modules/@babel/traverse/lib/context.js:182:19)
    at Function.traverse.node (/Users/example/node_modules/@babel/traverse/lib/index.js:106:17)

babelrc + JSX breaks reporting

I noticed stylelint was silently not reporting errors in css-in-js files. From experimentation, this only occurs when JSX is used in the file.

The issue is that postcss-jsx is not working properly when babel is configured (e.g. with a .babelrc file in scope).

Here is a minimal repo of the issue: https://github.com/brandonkal/postcss-jsx-bug

Doesn't throw CssSyntaxError when using @babel/[email protected]

'use strict';

const {parse} = require('postcss-jsx');

parse('styled.a`"`;', {from: 'file.js'});

When you have installed @babel/[email protected], the script above throws the following error:

$ node run.js

/Users/shinnn/example/node_modules/postcss-syntax/parse-style.js:66
				throw this.error(error);
				^
CssSyntaxError: /Users/shinnn/example/file.js:1:10: Unclosed string
    at Input.error (/Users/shinnn/example/node_modules/postcss/lib/input.js:124:16)
    at unclosed (/Users/shinnn/example/node_modules/postcss/lib/tokenize.js:59:17)
    at Object.nextToken (/Users/shinnn/example/node_modules/postcss/lib/tokenize.js:176:15)
    at Parser.parse (/Users/shinnn/example/node_modules/postcss/lib/parser.js:55:30)
    at Object.parse (/Users/shinnn/example/node_modules/postcss/lib/parse.js:19:12)
    at LocalFixer.parse (/Users/shinnn/example/node_modules/postcss-syntax/parse-style.js:57:18)
    at parseStyle (/Users/shinnn/example/node_modules/postcss-syntax/parse-style.js:89:39)
    at styles.sort.forEach.style (/Users/shinnn/example/node_modules/postcss-syntax/parse-style.js:104:17)
    at Array.forEach (<anonymous>)
    at parseStyle (/Users/shinnn/example/node_modules/postcss-syntax/parse-style.js:103:6)

This is an expected behavior because " is an invalid CSS.

However, if you have installed @babel/[email protected], the same script doesn't throw any errors.

The currently effective workaround is to change package.json#L44

"@babel/core": "^7.0.0-rc.1"
like the following:

- "@babel/core": "^7.0.0-rc.1"
+ "@babel/core": "7.0.0-rc.1"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.