Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Leading _ in classnames #1023

Closed
Diokuz opened this issue May 24, 2017 · 20 comments
Closed

Leading _ in classnames #1023

Diokuz opened this issue May 24, 2017 · 20 comments

Comments

@Diokuz
Copy link

Diokuz commented May 24, 2017

Im struggling with postcss because it removes leading underscore character in my classnames. For example (pseudocode):

._x {
  color: red;
}
import s from './css.css';

<div className={s._x}> // undefined, {s.x} works

So, looks like it is works like that for the last three years:

postcss/lib/parser.es6

Lines 209 to 212 in d06be72

if ( node.prop[0] === '_' || node.prop[0] === '*' ) {
node.raws.before += node.prop[0];
node.prop = node.prop.slice(1);
}

But somehow it breaks only when css-loader works. When postcss-loader works – it doesnt happen)

Why you forbid leading underscores in classNames?
Or maybe all the magic happens in node.raws.before and css-loader doesnt handle it properly?

I use React webpack@2, postcss@5.2.17 css-loader@0.28.2

css-loader issue webpack-contrib/css-loader#541

@ai
Copy link
Member

ai commented May 24, 2017

That code in parser is only for declaration.

Are you sure, that it is PostCSS, because you show this problem on CSS Modules example, where CSS Modules can do some magic with classnames.

Can you try to check AST by postcss.parse(css)?

@michael-ciniawsky
Copy link

michael-ciniawsky commented May 24, 2017

css-loader compiles the [style] exports (e.g to camelCase) it's not a PostCSS issue, reopen in webpack-contrib/css-loader please

@Diokuz
Copy link
Author

Diokuz commented May 24, 2017

postcss.parse('.src⁄x___x {\n  color: red;\n}\n:export {\n  _x: src⁄x___x;\n}\n').nodes[1]

↓↓↓

Rule {
  raws: { before: '\n', between: ' ', semicolon: true, after: '\n' },
  type: 'rule',
  nodes: 
   [ Declaration {
       raws: [Object],
       type: 'decl',
       parent: [Circular],
       source: [Object],
       prop: 'x',
       value: 'src⁄x___x' } ],
  parent: 
   Root {
     raws: { semicolon: false, after: '\n' },
     type: 'root',
     nodes: [ [Object], [Circular] ],
     source: { input: [Object], start: [Object] } },
  source: 
   { start: { line: 4, column: 1 },
     input: 
      Input {
        css: '.src⁄x___x {\n  color: red;\n}\n:export {\n  _x: src⁄x___x;\n}\n',
        id: '<input css 2>' },
     end: { line: 6, column: 1 } },
  selector: ':export' }

So, props is x

@Diokuz
Copy link
Author

Diokuz commented May 24, 2017

After that css-loader just do that:

exports[decl.prop] = decl.value;

https://github.com/webpack-contrib/css-loader/blob/master/lib/processCss.js#L71

and I lose _

I just trying to understant what happens in postcss) Why _ lost in prop.
I understant that it is rather css-loader problem, but I cannot figure out (inside css-loader source) what is wrong.

@Diokuz
Copy link
Author

Diokuz commented May 24, 2017

If I print decl:

decl Declaration {
  raws: { before: '\n  _', between: ': ' },
  type: 'decl',
...

So, should it be like

exports[decl.raws.before.trim() + decl.prop] = decl.value;

?

How to get proper classname there?

@michael-ciniawsky
Copy link

This is already ICSS (:export), does ._className { color: red; } without any plugins etc also produce this issue ?

@Diokuz
Copy link
Author

Diokuz commented May 24, 2017

Without :export there is no prop key.

The question is: why you remove _ from prop, and what to advise css-loader maintainers? Theirs code looks logical, and decl.raws.before.trim() + decl.prop looks wired.

@ai
Copy link
Member

ai commented May 24, 2017

@Diokuz you ask about declaration property _x: black; it about class name ._x { }. Because in first comment you show class example, but in AST show example work property.

@TrySound
Copy link
Member

TrySound commented May 24, 2017

@ai css-modules plugins first converts all to icss which is looks like this

.localClass {}

turns into

:export {
  localClass: 'globalClass--hash'
}

And then loader extracts all info from this.

@TrySound
Copy link
Member

We can concat prefixes on extracting only in one place. Nothing wrong with it.

@Diokuz
Copy link
Author

Diokuz commented May 24, 2017

Well, I use postcss-loader first, and it creates :export stuff. Then I use css-loader only to create js objects, but it uses postcss for that. Here is config webpack-contrib/css-loader#541

Should postcss be able to parse ICSS, or maybe that is a problem?

@TrySound
Copy link
Member

@Diokuz I do ICSS utilities which will be used in all loaders and behave in the same way.
https://github.com/css-modules/icss-utils
So this will be fixed.

@ai
Copy link
Member

ai commented May 24, 2017

I will close it because it is not related to PostCSS.

PostCSS keeps _ in class. PostCSS removes leading _ from declaration properties, because it is illegal symbol there.

@ai ai closed this as completed May 24, 2017
@michael-ciniawsky
Copy link

I do ICSS utilities which will be used in all loaders and behave in the same way.

What (ノಠ益ಠ)ノ彡┻━┻ ? 🙃 😛 :D

@TrySound
Copy link
Member

I mean css-loader, css-modules-parser, core loader

@michael-ciniawsky
Copy link

Well, I use postcss-loader first, and it creates :export stuff.

@Diokuz That's likely the issue, you can't really use css-modules with postcss-loader yet #227

@TrySound Yup, I'm already 'stalking' all the cssm repos :D

@Diokuz
Copy link
Author

Diokuz commented May 24, 2017

you can't really use css-modules with postcss-loader yet #227

Haha, thats funny) Thanks anyway)

PostCSS keeps _ in class. PostCSS removes leading _ from declaration properties, because it is illegal symbol there.

@ai does postcss supports ICSS syntax?

@ai
Copy link
Member

ai commented May 24, 2017

@Diokuz of course, CSS Modules uses PostCSS to parse CSS, so PostCSS by default support it.

@Diokuz
Copy link
Author

Diokuz commented Jun 6, 2017

@ai then I still didn't get it, why it is considered as a normal behaviour to drop leading _ in classnames inside :export?

@ai
Copy link
Member

ai commented Jun 6, 2017

Nope. Normal behavior is to drop _ only in property names. If you have different wrong behavior with selectors, show it with PostCSS API example (you shown selector problem only with CSS Modules, with PostCSS you shown properties behavior which is correct).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants