Skip to content

Commit 7be0416

Browse files
authored
ESLint plugin for Scoped CSS in Vue.js (#2)
1 parent 2c53581 commit 7be0416

File tree

374 files changed

+52044
-1
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

374 files changed

+52044
-1
lines changed

.eslintignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/.nyc_output
2+
/coverage
3+
/node_modules
4+
/assets
5+
/dist
6+
/docs/.vuepress/dist

.eslintrc.js

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
"use strict"
2+
3+
const version = require("./package.json").version
4+
5+
module.exports = {
6+
parserOptions: {
7+
sourceType: "script",
8+
ecmaVersion: 2018,
9+
},
10+
extends: [
11+
"plugin:@mysticatea/es2015",
12+
"plugin:@mysticatea/+node",
13+
"plugin:@mysticatea/+eslint-plugin",
14+
],
15+
rules: {
16+
'require-jsdoc': 'error',
17+
"no-warning-comments": "warn",
18+
'no-lonely-if': 'off'
19+
},
20+
overrides: [
21+
{
22+
files: ["*.ts"],
23+
rules: {
24+
"@mysticatea/ts/no-require-imports": "off",
25+
"@mysticatea/ts/no-var-requires": "off",
26+
"no-implicit-globals": "off",
27+
},
28+
parserOptions: {
29+
sourceType: "module",
30+
project: "./tsconfig.json",
31+
},
32+
},
33+
{
34+
files: ["lib/rules/**"],
35+
rules: {
36+
"@mysticatea/eslint-plugin/report-message-format": ["error", "[^a-z].*\\.$"],
37+
"@mysticatea/eslint-plugin/require-meta-docs-url": [
38+
"error",
39+
{
40+
pattern: `https://github.com/ota-meshi/eslint-plugin-vue-scoped-css/blob/v${version}/docs/rules/{{name}}.md`,
41+
},
42+
],
43+
}
44+
},
45+
{
46+
files: ["scripts/*.js", "tests/**/*.js", "scripts/*.ts", "tests/**/*.ts"],
47+
rules: {
48+
"require-jsdoc": "off",
49+
"no-console": "off"
50+
},
51+
},
52+
{
53+
files: ["*.vue"],
54+
parserOptions: {
55+
sourceType: "module",
56+
},
57+
extends: [
58+
// "plugin:vue-scoped-css/recommended"
59+
],
60+
globals:{
61+
require: true
62+
},
63+
},
64+
{
65+
files: ["docs/.vuepress/**"],
66+
parserOptions: {
67+
sourceType: "module",
68+
ecmaVersion: 2019,
69+
parser: 'babel-eslint'
70+
},
71+
globals: {
72+
window: true
73+
},
74+
rules: {
75+
"require-jsdoc": "off",
76+
"@mysticatea/vue/html-closing-bracket-newline": "off",
77+
"@mysticatea/vue/max-attributes-per-line": "off",
78+
"@mysticatea/vue/comma-dangle": "off",
79+
"@mysticatea/vue/html-indent": "off",
80+
"@mysticatea/vue/html-self-closing": "off",
81+
"@mysticatea/node/no-unsupported-features/es-syntax": "off"
82+
},
83+
},
84+
],
85+
}

.gitignore

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,12 @@
1-
node_modules
1+
/node_modules
2+
/docs/.vuepress/dist
3+
/dist
4+
/.nyc_output
5+
/coverage
6+
7+
# gh-pages
8+
/assets
9+
/rules
10+
/playground
11+
/404.html
12+
/index.html

.travis.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
language: node_js
2+
cache:
3+
npm: false
4+
matrix:
5+
include:
6+
- node_js: "node"
7+
env: CI=coverage
8+
- node_js: "8"
9+
- node_js: "8"
10+
env: DEPS=low
11+
- node_js: "10"
12+
- node_js: "12"
13+
before_install:
14+
- if [ "$DEPS" = "low" ]; then npm i -S eslint@5.0.0 eslint-plugin-vue@5.0.0 vue-eslint-parser@5.0.0; fi
15+
before_deploy:
16+
- npm run build
17+
deploy:
18+
skip_cleanup: true
19+
provider: npm
20+
email: $EMAIL
21+
api_key: $NPM_TOKEN
22+
on:
23+
tags: true
24+
notifications:
25+
email: false
26+
after_success:
27+
- if [ "$CI" = "coverage" ]; then npm install coveralls --no-save && cat ./coverage/lcov.info | ./node_modules/.bin/coveralls

.vscode/settings.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"eslint.validate": [
3+
"javascript",
4+
"javascriptreact",
5+
{ "language": "vue", "autoFix": true },
6+
{ "autoFix": true, "language": "typescript" },
7+
],
8+
"typescript.validate.enable": true,
9+
"javascript.validate.enable": false,
10+
"eslint.autoFixOnSave": true,
11+
"eslint.workingDirectories": [
12+
{"directory": "./", "changeProcessCWD": true },
13+
{"directory": "./docs/.vuepress", "changeProcessCWD": true }
14+
],
15+
"vetur.validation.script": false,
16+
"vetur.validation.style": false,
17+
"css.validate": false,
18+
"typescript.tsdk": "node_modules/typescript/lib"
19+
}

README.md

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# eslint-plugin-vue-scoped-css
2+
3+
[eslint-plugin-vue-scoped-css](https://www.npmjs.com/package/eslint-plugin-vue-scoped-css) is ESLint plugin for [Scoped CSS in Vue.js].
4+
5+
[![NPM license](https://img.shields.io/npm/l/eslint-plugin-vue-scoped-css.svg)](https://www.npmjs.com/package/eslint-plugin-vue-scoped-css)
6+
[![NPM version](https://img.shields.io/npm/v/eslint-plugin-vue-scoped-css.svg)](https://www.npmjs.com/package/eslint-plugin-vue-scoped-css)
7+
[![NPM downloads](https://img.shields.io/badge/dynamic/json.svg?label=downloads&colorB=green&suffix=/day&query=$.downloads&uri=https://api.npmjs.org//downloads/point/last-day/eslint-plugin-vue-scoped-css&maxAge=3600)](http://www.npmtrends.com/eslint-plugin-vue-scoped-css)
8+
[![NPM downloads](https://img.shields.io/npm/dw/eslint-plugin-vue-scoped-css.svg)](http://www.npmtrends.com/eslint-plugin-vue-scoped-css)
9+
[![NPM downloads](https://img.shields.io/npm/dm/eslint-plugin-vue-scoped-css.svg)](http://www.npmtrends.com/eslint-plugin-vue-scoped-css)
10+
[![NPM downloads](https://img.shields.io/npm/dy/eslint-plugin-vue-scoped-css.svg)](http://www.npmtrends.com/eslint-plugin-vue-scoped-css)
11+
[![NPM downloads](https://img.shields.io/npm/dt/eslint-plugin-vue-scoped-css.svg)](http://www.npmtrends.com/eslint-plugin-vue-scoped-css)
12+
<!--
13+
[![Build Status](https://travis-ci.org/ota-meshi/eslint-plugin-vue-scoped-css.svg?branch=master)](https://travis-ci.org/ota-meshi/eslint-plugin-vue-scoped-css)
14+
[![Coverage Status](https://coveralls.io/repos/github/ota-meshi/eslint-plugin-vue-scoped-css/badge.svg?branch=master)](https://coveralls.io/github/ota-meshi/eslint-plugin-vue-scoped-css?branch=master)
15+
[![Greenkeeper badge](https://badges.greenkeeper.io/ota-meshi/eslint-plugin-vue-scoped-css.svg)](https://greenkeeper.io/)
16+
-->
17+
18+
## Features
19+
20+
This ESLint plugin provides linting rules specific to [Scoped CSS in Vue.js].
21+
22+
You can check on the [Online DEMO](https://ota-meshi.github.io/eslint-plugin-vue-scoped-css/playground/).
23+
24+
<!--DOCS_IGNORE_START-->
25+
26+
## Documentation
27+
28+
See [documents](https://ota-meshi.github.io/eslint-plugin-vue-scoped-css/).
29+
30+
<!--DOCS_IGNORE_END-->
31+
32+
## Installation
33+
34+
```bash
35+
npm install --save-dev eslint-plugin-vue-scoped-css
36+
```
37+
38+
## Usage
39+
40+
Create `.eslintrc.*` file to configure rules. See also: [http://eslint.org/docs/user-guide/configuring](http://eslint.org/docs/user-guide/configuring).
41+
42+
Example **.eslintrc.js**:
43+
44+
```js
45+
module.exports = {
46+
extends: [
47+
// add more generic rulesets here, such as:
48+
// 'eslint:recommended',
49+
'plugin:vue-scoped-css/recommended'
50+
],
51+
rules: {
52+
// override/add rules settings here, such as:
53+
// 'vue-scoped-css/no-warning-html-comments': 'error'
54+
}
55+
}
56+
```
57+
58+
## Configs
59+
60+
This plugin provides 3 predefined configs:
61+
62+
- `plugin:vue-scoped-css/base` - Settings and rules to enable correct ESLint parsing
63+
- `plugin:vue-scoped-css/recommended` - Above, plus rules to improve code experience
64+
- `plugin:vue-scoped-css/all` - All rules of this plugin are included
65+
66+
## Rules
67+
68+
<!--RULES_SECTION_START-->
69+
70+
The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) automatically fixes problems reported by rules which have a wrench :wrench: below.
71+
72+
<!--RULES_TABLE_START-->
73+
74+
### Base Rules (Enabling Correct ESLint Parsing)
75+
76+
Enable this plugin using with:
77+
78+
```json
79+
{
80+
"extends": "plugin:vue-scoped-css/base"
81+
}
82+
```
83+
84+
### Recommended (Improve Development Experience)
85+
86+
Enforce all the rules in this category with:
87+
88+
```json
89+
{
90+
"extends": "plugin:vue-scoped-css/recommended"
91+
}
92+
```
93+
94+
| | Rule ID | Description |
95+
|:---|:--------|:------------|
96+
| | [vue-scoped-css/no-unused-selector](./docs/rules/no-unused-selector.md) | Reports selectors defined in Scoped CSS not used in `<template>`. |
97+
| | [vue-scoped-css/require-scoped](./docs/rules/require-scoped.md) | Enforce the `<style>` tags to has the `scoped` attribute. |
98+
99+
### Uncategorized
100+
101+
| | Rule ID | Description |
102+
|:---|:--------|:------------|
103+
| | [vue-scoped-css/require-selector-used-inside](./docs/rules/require-selector-used-inside.md) | Reports the defined selectors is not used inside `<template>`. |
104+
105+
<!--RULES_TABLE_END-->
106+
<!--RULES_SECTION_END-->
107+
108+
## Contributing
109+
110+
Welcome contributing!
111+
112+
Please use GitHub's Issues/PRs.
113+
114+
### Development Tools
115+
116+
- `npm test` runs tests and measures coverage.
117+
- `npm run update` runs in order to update readme and recommended configuration.
118+
119+
## License
120+
121+
See the [LICENSE](LICENSE) file for license rights and limitations (MIT).
122+
123+
[Scoped CSS in Vue.js]: https://vue-loader.vuejs.org/guide/scoped-css.html

docs/.vuepress/categories.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
const { rules } = require("../../dist/utils/rules")
2+
3+
const categoryTitles = {
4+
base: "Base Rules (Enabling Correct ESLint Parsing)",
5+
recommended: "Recommended (Improve Development Experience)",
6+
}
7+
8+
const categoryConfigDescriptions = {
9+
base: "Enable this plugin using with:",
10+
recommended: "Enforce all the rules in this category with:",
11+
}
12+
13+
const categoryIds = Object.keys(categoryTitles)
14+
const categoryRules = rules.reduce((obj, rule) => {
15+
const cat = rule.meta.docs.category || "uncategorized"
16+
const categories = obj[cat] || (obj[cat] = [])
17+
categories.push(rule)
18+
return obj
19+
}, {})
20+
21+
// Throw if no title is defined for a category
22+
for (const categoryId of Object.keys(categoryRules)) {
23+
if (categoryId !== "uncategorized" && !categoryTitles[categoryId]) {
24+
throw new Error(
25+
`Category "${categoryId}" does not have a title defined.`
26+
)
27+
}
28+
}
29+
30+
module.exports = categoryIds.map(categoryId => ({
31+
categoryId,
32+
title: categoryTitles[categoryId],
33+
configDescription: categoryConfigDescriptions[categoryId],
34+
rules: (categoryRules[categoryId] || []).filter(
35+
rule => !rule.meta.deprecated
36+
),
37+
}))
38+
// .filter(category => category.rules.length >= 1)

0 commit comments

Comments
 (0)