postcss-bem-linter icon indicating copy to clipboard operation
postcss-bem-linter copied to clipboard

Does not work with Sass interpolation

Open ruedap opened this issue 6 years ago • 5 comments

This plugin does not seem to support Sass interpolation.

input.scss:

/** @define ComponentName */
.ComponentName {
  $ComponentName: &;

  &--modifierName {
    color: blue;

    #{$ComponentName} {  // <- Sass interpolation
      &-decendantName {
        color: red;
      }
    }
  }
}

postcss-bem-linter result:

input.scss
 9:7  ✖  Invalid component selector                   plugin/selector-bem-pattern
         ".ComponentName--modifierName
         #{$ComponentName}-decendantName"

output.css

/** @define ComponentName */
.ComponentName--modifierName {
  color: blue;
}
.ComponentName--modifierName .ComponentName-decendantName {
  color: red;
}

postcss-bem-linter result:

No errors

ruedap avatar Apr 15 '18 08:04 ruedap

Might be related to #97, #100 🤔

ruedap avatar Apr 15 '18 14:04 ruedap

I've come across this issue as well.

For now I'm simply ignoring (the few and far between) instances of selectors that contain Sass string interpolation. Not ideal, nor sustainable, but it's tiding things over until a solution is reached (hopefully in this issue).

Rather than ignoring on a selector-by-selector basis, I put the ignoreSelectors option to use like so:-

bemLinter({
  ignoreSelectors: /\#\{\$[a-z]+(?:-[a-z]+)*\}/,
});

The intended logic of this regex (see example) is to match any string that contains: #{$sass-variable-name}.

Back to the issue at hand:

Is it this plugin's responsibility to process Sass string interpolation and ensure that the resulting selector is in the correct format? (And is that even possible?) Or, is it instead the responsibility of the user to configure the regex to take into account the presence of Sass string interpolation within a selector?

/cc @simonsmith

saulhardman avatar Apr 16 '18 10:04 saulhardman

Is it this plugin's responsibility to process Sass string interpolation and ensure that the resulting selector is in the correct format? (And is that even possible?)

A good question and I think it would be outside of the scope of this plugin to compile the Sass and understand how to apply the linting rules to the source file.

The solution I'd be tempted to go with would be to apply the postcss-bem-linter after the Sass transformation has happened. You will get less accurate line numbers in the error console (and no editor support on the source files) but that feels like an acceptable tradeoff for these complex Sass examples.

We support nesting but mainly because that isn't unique to Sass and also exists as an official proposal

simonsmith avatar Apr 16 '18 12:04 simonsmith

If anyone comes after this, I'm using the following for now:


const namePattern = /([a-z0-9]+|#\{\$.*\})((-[a-z0-9]+|#\{\$.*\})+)?/;

componentSelectors: (componentName) => new RegExp(`^\\.(${componentName})(((--|__)(${namePattern.source}))+)?$`)

It's been working so far. If anyone try this in another project and find any error, warn me please.

guilhermetod avatar Oct 16 '20 14:10 guilhermetod

@guilhermetod if i use json format, how can i do it? or you can show your js file?

almogk012 avatar Nov 12 '20 11:11 almogk012