UNPKG

19.1 kBMarkdownView Raw
1## stylint - the stylus linter.
2
3[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/rossPatton/stylint?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Code Climate](https://codeclimate.com/github/rossPatton/stylint/badges/gpa.svg)](https://codeclimate.com/github/rossPatton/stylint) [![Test Coverage](https://codeclimate.com/github/rossPatton/stylint/badges/coverage.svg)](https://codeclimate.com/github/rossPatton/stylint/coverage) [![Build Status](https://travis-ci.org/rossPatton/stylint.svg?branch=master)](https://travis-ci.org/rossPatton/stylint)
4
5[![NPM](https://nodei.co/npm/stylint.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/stylint/)
6
7[changelog](changelog.md)
8
9[known issues](https://github.com/rossPatton/stylint/issues)
10
11If you have any problems with the linter just create a ticket there and I will respond.
12
13Same thing if you have any feature requests.
14
15I will gladly accept pull requests if you want to do the work yourself.
16
17you can also ping me [here](https://gitter.im/rossPatton/stylint)
18
19
20## CLI
21`-h` or `--help` Display list of commands
22
23`-w` or `--watch` Watch file or directory and run lint on change
24
25`-c` or `--config` Pass in location of custom config file
26
27`-v` or `--version` Display current version
28
29
30## Example cli Usage:
31`stylint` Run stylint on cwd
32
33`stylint path/to/filename.styl` Run stylint on a file
34
35`stylint path/to/dir --watch` Watch dir, run stylint on file change
36
37`stylint --help` Get list of commands
38
39`stylint --version` Get version number
40
41`stylint --config path/to/config/.configrc` Run stylint with custom config settings
42
43`stylint styl/ --watch -c path/to/config/.configrc` Watch dir, use custom config
44
45
46## Non ClI Usage
47I'll be the first to admit that the syntax is a bit weird, but it works just fine.
48```javascript
49const stylint = require('stylint')('path/to/stylus/', {
50 brackets: 'always',
51 namingConvention: 'BEM',
52 semicolons: 'always'
53}, callbackFn).create();
54```
55
56API docs are in the docs/ folder
57
58
59## Gulp
60You can use the CLI with [gulp-shell](https://github.com/sun-zheng-an/gulp-shell) like below:
61```javascript
62gulp.task('stylint', shell.task([
63 'stylint path/to/styl/ -c .stylintrc'
64]));
65```
66
67Or just use [gulp-stylint](https://github.com/danielhusar/gulp-stylint)
68```javascript
69var gulp = require('gulp');
70var stylint = require('gulp-stylint');
71
72gulp.task('default', function () {
73 return gulp.src('src/*.styl')
74 .pipe(stylint())
75});
76```
77
78## Grunt
79You can use [grunt-stylint](https://github.com/xdissent/grunt-stylint)
80
81```javascript
82grunt.initConfig({
83 stylint: {
84 options: {
85 config: {
86 colons: 'never'
87 }
88 },
89 src: ['src/**/*.styl']
90 }
91});
92```
93
94## Webpack
95You can use [stylint-loader](https://github.com/guerrero/stylint-loader)
96
97```javascript
98module.exports = {
99 // ...
100 module: {
101 preLoaders: [
102 {
103 test: /\.styl$/,
104 loader: 'stylint'
105 }
106 ],
107 loaders: [
108 {
109 test: /\.styl$/,
110 loader: 'style!css!stylus'
111 }
112 ]
113 }
114 // ...
115}
116```
117
118
119## As Part of Your Workflow
120Stylint integrations with both Sublime Text 3 and Atom.io are available.
121
122[Atom linter-stylint](https://atom.io/packages/linter-stylint)
123
124[SublimeLinter-contrib-stylint](https://packagecontrol.io/packages/SublimeLinter-contrib-stylint)
125
126
127## Why Write This Tool?
128Stylus is my CSS pre-processor of choice and the lack of a decent linter (or really, any linter) was an annoying pain point. So I thought I'd try my hand at writing what I thought my ideal linter would look like.
129
130
131## Why Use This Tool?
132To catch little mistakes (duplication of rules for instance) and to enforce a code style guide. This is particularly important with Stylus, which is unopinionated when it comes to syntax. Like Stylus itself, this linter opts for flexibility over rigidity.
133
134
135## Options
136The following is a list of all options available to stylint.
137```json
138{
139 "blocks": false,
140 "brackets": "never",
141 "colons": "always",
142 "colors": "always",
143 "commaSpace": "always",
144 "commentSpace": "always",
145 "cssLiteral": "never",
146 "depthLimit": false,
147 "duplicates": true,
148 "efficient": "always",
149 "extendPref": false,
150 "globalDupe": false,
151 "indentPref": false,
152 "leadingZero": "never",
153 "maxErrors": false,
154 "maxWarnings": false,
155 "mixed": false,
156 "namingConvention": false,
157 "namingConventionStrict": false,
158 "none": "never",
159 "noImportant": true,
160 "parenSpace": false,
161 "placeholders": "always",
162 "prefixVarsWithDollar": "always",
163 "quotePref": false,
164 "semicolons": "never",
165 "sortOrder": "alphabetical",
166 "stackedProperties": "never",
167 "trailingWhitespace": "never",
168 "universal": false,
169 "valid": true,
170 "zeroUnits": "never",
171 "zIndexNormalize": false
172}
173```
174
175#### Custom Configuration
176By default, Stylint attempts to use the .stylintrc file in your working directory. If not, the above is what it falls back to.
177
178You can also use the `-c` or `--config` flags to pass in the location of your custom `.stylintrc` config file if it resides somewhere else.
179
180If requiring Stylint ( as opposed to using it via the cli ), the 2nd param is the config object.
181
182
183#### Severity
184Stylint has 2 levels of output, Warnings and Errors. All Stylint rules optionally take an object, allowing you to set it to be an Error. Combined with the maxWarnings and maxErrors properties, you can be very flexible about say, code style but strict on things like code duplication.
185
186Example:
187```json
188{
189 "brackets": {
190 "expect": "never",
191 "error": true
192 },
193 "colons": {
194 "expect": "always",
195 "error": true
196 }
197}
198```
199
200
201## Custom Reporters
202Stylint console output can be modified with the use of a reporter. Feel free to write your own (no matter how outlandish) and I'll add it here.
203
204[Stylint-stylish](https://github.com/SimenB/stylint-stylish)
205
206
207
208### warning toggle ( inline comment: @stylint off || @stylint on )
209Disable linting for a particular block of code by placing `@stylint off` in a line comment. Re-enable by placing `@stylint on` in a line comment further down. Stylint will not test any lines until turned back on. Use this to suppress warnings on a case-by-case basis. By default the linter will check every line except for @css blocks or places where certain rules have exceptions.
210
211For example, let's say you want to enforce `namingConvention: "lowercase_underscore"`, but you're also styling elements from the Bootstrap framework. You can use the `@stylint off` toggle to prevent warnings in places where you're referencing Bootstrap classes.
212
213Example:
214```stylus
215.button_block {
216 background: silver;
217 padding: 4px;
218}
219// @stylint off
220.button_block .btn-default {
221 background-color: green;
222 color: white;
223}
224// @stylint on
225```
226
227
228### ignore toggle ( inline comment: @stylint ignore )
229A toggle that works like the block comment, but just for one line. Useful for cases where you want to include fallback css for browser support.
230
231Example:
232```stylus
233.button-zoom
234 cursor pointer // @stylint ignore
235 cursor zoom-in
236```
237
238
239### transparent mixin use ( Array<string> )
240In Stylus you have the option of using mixins transparently, like css properties.
241
242Example: prefer `mySpecialTransition: 5px`
243
244Where `mySpecialTransition` is a previously defined mixin that takes a px val as it's parameter.
245
246If you use nib, `size`, `absolute`, and `fixed` are often used in this way.
247
248Because of nib's widespread use, the above 3 are supported by default. But any custom transparent mixin will cause the valid property check to fail. If you want to use the valid check with transparent mixins, you can do so by passing in the name of your transparent mixin to the `mixins` property of your config object.
249
250Example: `mixins: ['mySpecialTransition']` will tell Stylint that mySpecialTransition exists and is not an error.
251
252
253### blocks ( default: false, 'always' || 'never' || false )
254When 'always' expect the `@block` keyword when defining block variables.
255When 'never', expect no `@block` keyword when defining block variables.
256When false, do not check either way.
257
258Example if 'always': prefer `my-block = @block ` over `my-block = `
259
260Example if 'never': prefer `my-block = ` over `my-block = @block `
261
262
263### brackets ( default: 'never', 'always' || 'never' || false )
264When 'always', expect {} when declaring a selector.
265When 'never', expect no brackets when declaring a selector.
266
267Example if 'always': prefer `.some-class-name {` over `.some-class-name`
268
269Example if 'never': prefer `.some-class-name ` over `.some-class-name {`
270
271
272### colons ( default: 'always', 'always' || 'never' || false )
273When 'always', expect : when declaring a property.
274When 'never', expect no : when declaring a property.
275
276Example if 'always': prefer `margin: 0` over `margin 0`
277
278Example if 'never: prefer `margin 0` over `margin: 0`
279
280
281### colors ( default: 'always' || false )
282When 'always', enforce variables when defining hex values
283
284Example if true: prefer `color $red` over `color #f00`
285
286
287### commaSpace ( default: 'always', 'always' || 'never' || false )
288Enforce or disallow spaces after commas.
289
290Example if always: prefer `rgba(0, 0, 0, .18)` over `rgba(0,0,0,.18)`
291
292Example if never: prefer `rgba(0,0,0,.18)` over `rgba(0, 0, 0, .18)`
293
294
295### commentSpace ( default: 'always', 'always' || 'never' || false )
296Enforce or disallow spaces after line comments
297
298Example if always: prefer `// comment` over `//comment`
299
300Example if never: prefer `//comment` over `// comment`
301
302
303### cssLiteral ( default: 'never', 'never' || false )
304By default Stylint ignores `@css` blocks. If set to true however, it will throw a warning if `@css` is used.
305
306Example if 'never': `@css` will throw a warning
307
308
309### depthLimit ( default: false, number or false )
310Set the max selector depth. If set to 4, max selector depth will be 4 indents. Pseudo selectors like `&:first-child` or `&:hover` won't count towards the limit.
311
312Set to false if you don't want to check for this.
313
314
315### duplicates ( default: true, true || false )
316Checks if selector or property duplicated unnecessarily. By default, only checks on a file-by-file basis, but if `globalDupes: true` is set, then it will also check for duplicates globally (for root values only).
317
318Example if true: the following will throw a warning:
319```stylus
320.test
321 margin 0
322 margin 5px
323```
324
325
326### efficient ( default: 'always', 'always' || 'never' || false )
327Check for places where properties can be written more efficiently.
328
329Example if always: prefer `margin 0` over `margin 0 0`
330
331Example if never: prefer `margin 0 0` over `margin 0`
332
333
334### extendPref ( default: false, '@extend' || '@extends' || false )
335Pass in either `@extend` or `@extends` and then enforce that. Both are valid in Stylus. It doesn't really matter which one you use. I prefer `@extends` myself.
336
337Example if set to `@extends`: prefer `@extends $some-var` over `@extend $some-var`
338
339Example if set to `@extend`: prefer `@extend $some-var` over `@extend $some-var`
340
341
342### globalDupe ( default: false, true || false )
343Works in conjunction with duplicates. Does nothing on its own. If false, duplicates will check for dupes within individual files only. If true, duplicates will check for dupes across all files.
344
345Example if true: the following will throw a warning
346```stylus
347>>> file1.styl
348.test
349 margin 0
350
351>>> file2.styl
352.test
353 margin 5px
354```
355
356
357### indentPref ( default: false, number or false )
358This works in conjunction with depthLimit. If you indent with spaces this is the number of spaces you indent with. If you use hard tabs, set this value to false.
359
360If you set this to a number, it will output warnings/errors if you the # of spaces used for indenting differs from the number set.
361
362By default this value is false, so if you indent with spaces you'll need to manually set this value in a custom `.stylintrc` file.
363
364Example if 2: prefer `/s/smargin: 0` over `/s/s/smargin: 0`
365
366
367### leadingZero ( default: 'never', 'always' || 'never' || false )
368Enforce or disallow unnecessary leading zeroes on decimal points.
369
370Example if always: prefer `rgba( 0, 0, 0, 0.5 )` over `rgba( 0, 0, 0, .5 )`
371
372Example if never: prefer `rgba( 0, 0, 0, .5 )` over `rgba( 0, 0, 0, 0.5 )`
373
374
375### maxErrors ( default: false, number || false )
376Set 'max' number of Errors.
377
378
379### maxWarnings ( default: false, number || false )
380Set 'max' number of Warnings.
381
382
383### mixed ( default: false, boolean, relies on indentPref )
384Returns true if mixed spaces and tabs are found. If a number is passed to indentPref, it assumes soft tabs (ie, spaces), and if false is passed to indentPref it assumes hard tabs.
385
386If soft tabs, outputs warning/error if hard tabs used. If hard tabs, outputs warning/error if unnecessary extra spaces found.
387
388Example if indentPref: 4 and mixed: true: prefer `\s\s\s\smargin\s0` over `\tmargin\s0`
389
390Example if indentPref: 2 and mixed: true: prefer `\s\smargin\s0` over `\tmargin\s0`
391
392Example if indentPref: false and mixed: true: prefer `\tmargin\s0` over `\s\s\s\smargin\s0`
393
394
395### namingConvention ( default: false, false | 'lowercase-dash' | 'lowercase_underscore' | 'camelCase' | 'BEM' )
396Enforce a particular naming convention when declaring classes, ids, and variables. Throws a warning if you don't follow the convention.
397
398Example if set to `'lowercase-dash'`: prefer `$var-name` over `$var_name` or `$varName`
399
400Example if set to `'lowercase_underscore'`: prefer `$var_name` over `$var-name` or `$varName`
401
402Example if set to `'camelCase'`: prefer `$varName` over `$var_name` or `$var-name`
403
404Example if set to `'BEM'`: prefer `$var__like--this` over `$var_name` or `$varName`
405
406
407### namingConventionStrict ( default: false, true || false )
408By default, namingConvention only looks at variable names. If namingConventionStrict is set to true, namingConvention will also look at class and id names.
409
410If you have a lot of 3rd party css you can't change you might want to leave this off.
411
412
413### none ( default: 'never'. options: 'always' || never' || false )
414If 'always' check for places where `none` used instead of `0`.
415If 'never' check for places where `0` could be used instead of `none`.
416
417Example if 'always': prefer `border none` over `border 0`
418
419Example if 'never': prefer `outline 0` over `outline none`
420
421
422### noImportant ( default: true, true || false )
423If true, show warning when `!important` is found.
424
425Example if true: the following will throw a warning
426
427```stylus
428div
429 color red !important
430```
431
432
433### parenSpace ( default: false, 'always' || 'never' || false )
434Enforce or disallow use of extra spaces inside parens.
435
436Example if always: prefer `my-mixin( $myParam )` over `my-mixin($myParam)`
437
438Example if never: prefer `my-mixin($myParam)` over `my-mixin( $myParam )`
439
440
441### placeholder ( default: 'always', 'always' || 'never' || false )
442Enforce extending placeholder vars when using `@extend(s)`
443
444Example if always: prefer `@extends $placeholder` over `$extends .some-class`
445
446Example if never: prefer `@extends .some-class` over `$extends $placeholder`
447
448
449### prefixVarsWithDollar ( default: 'always', 'always' || 'never' || false )
450Enforce use of `$` when defining a variable. In Stylus using a `$` when defining a variable is optional, but is a good idea if you want to prevent ambiguity. Not including the `$` sets up situations where you wonder: "Is this a variable or a value?" For instance: `padding $default` is easier to understand than `padding default`.
451
452Yes, `default` isn't an acceptable value for `padding`, but at first glance you might not catch that since it just looks like a value. And now if you try to set `cursor default`, it's not going to behave the way you expect. All this pain and heartache could've been avoided if you just used a `$`.
453
454Example if always: prefer `$my-var = 0` over `my-var = 0`
455
456Example if never: prefer `my-var = 0` over `$my-var = 0`
457
458
459### quotePref ( default: false, 'single' || 'double' || false )
460Enforce consistent quotation style.
461
462Example if `'single'`: prefer `$var = 'some string'` over `$var = "some string"`
463
464Example if `'double'`: prefer `$var = "some string"` over `$var = 'some string'`
465
466
467### semicolons ( default: 'never', 'always' || 'never' || false )
468Enforce or disallow semicolons
469
470Example if always: prefer `margin 0;` over `margin 0`
471
472Example if never: prefer `margin 0` over `margin 0;`
473
474
475### sortOrder ( default: 'alphabetical', 'alphabetical' || 'grouped' || [Array] || false )
476Enforce a particular sort order when declaring properties. Throws a warning if you don't follow the order. If set to false, allow any order.
477
478Example if `'alphabetical'`:
479
480prefer this:
481```stylus
482.some-class
483 display block
484 float left
485 position absolute
486 right 10px
487 top 0
488```
489
490over this:
491```stylus
492.some-class
493 position absolute
494 top 0
495 right 10px
496 display block
497 float left
498```
499
500Example if `'grouped'` ([based on predefined grouped ordering](src/data/ordering.json#L2)):
501
502prefer this:
503```stylus
504.some-class
505 position absolute
506 top 0
507 right 10px
508 display block
509 float left
510```
511
512over this:
513```stylus
514.some-class
515 display block
516 float left
517 position absolute
518 right 10px
519 top 0
520```
521
522Example if `[ 'margin', 'padding', 'float', 'position' ]`:
523
524prefer this:
525```stylus
526.some-class
527 margin 0
528 padding 0
529 float left
530 position absolute
531 right 10px
532 top 0
533 display block
534```
535
536over this:
537```stylus
538.some-class
539 display block
540 float left
541 position absolute
542 right 10px
543 top 0
544 margin 0
545 padding 0
546```
547
548When set to `'grouped'` or `{Array}` throws a warning if properties that are not defined in the ordering array are not after those that should be ordered.
549
550
551### stackedProperties ( default: 'never', 'never' || false )
552No one-liners. Enforce putting properties on new lines.
553
554Example if `never`: prefer
555
556```stylus
557.className
558 padding 0
559```
560
561over
562
563`.className { padding 0 }`
564
565
566### trailingWhitespace ( default: 'never', 'never' || false )
567If false, ignores trailing white space. If 'never', trailing white space will throw a warning.
568
569
570### universal ( default: false, 'never' || false )
571Looks for instances of the inefficient * selector. Lots of resets use this, for good reason (resetting box model), but past that you really don't need this selector, and you should avoid it if possible.
572
573Example if never, disallow the following:
574```stylus
575div *
576 margin 0
577```
578
579
580### valid ( default: true, true || false )
581Check that a property is valid CSS or HTML.
582
583Example if true: `marg 0` will throw a warning, prefer `margin 0`
584
585Example if true: `divv` will throw a warning, prefer `div`
586
587
588### zeroUnits ( default: 'never', 'always' || 'never' || false )
589Looks for instances of `0px`. You don't need the px. Checks all units, not just px.
590
591Example if always: prefer `margin-right 0px` over `margin-right 0`
592
593Example if never: prefer `margin-right 0` over `margin-right 0em`
594
595
596### zIndexNormalize ( default: false, number or false )
597Enforce some (very) basic z-index sanity. Any number passed in will be used as the base for your z-index values. Throws an error if your value is not normalized.
598
599Example if set to 5: prefer `z-index 10` over `z-index 9`
600Example if set to 10: prefer `z-index 20` over `z-index 15`
601Example if set to 50: prefer `z-index 100` over `z-index 75`