Skip to content

Commit

Permalink
Build: lint MD and JSON, adopt semistandard and eslint-plugin-config
Browse files Browse the repository at this point in the history
Major overhaul:

* Lint and enforce style in code examples in Markdown docs.

* Lint and style JSON files.

* Consolidate all ESLint configs into a central file.

* Statically check and enforce ES5 environment and browser compat.

  We already have this confidence through our CI tests, but
  having it via eslin-plugin-config makes this accessible during
  development for 99% of cases, which makes development quicker
  and more helpful during pull requests as well.

* Explicitly don't allow use of global setTimeout/clearTimeout, or
  any other runtime-specific APIs except when explicitly declared
  as safe to do so. This is to ensure portability for the main code
  and test suite.

* Move from jquery preset to semistandard preset.
  I don't have a strong preference for the style, but the
  semistandard preset is more actively maintained and contains a
  broader set of rules that also help with code quality rather than
  just coding style.

  Having said that, I do use semistandard in other repos I maintain,
  which helps reduce context switching a bit for me.
  • Loading branch information
Krinkle committed Mar 28, 2022
1 parent aa7314b commit 0f6ec7c
Show file tree
Hide file tree
Showing 257 changed files with 27,390 additions and 18,212 deletions.
7 changes: 2 additions & 5 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
root = true

[*]
indent_style = tab
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
Expand All @@ -13,7 +14,3 @@ insert_final_newline = true
trim_trailing_whitespace = false
[test/integration/nyc.js]
trim_trailing_whitespace = false

[*.{yml,yaml,md}]
indent_style = space
indent_size = 2
25 changes: 25 additions & 0 deletions .eslintrc.base.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* eslint-env node */

// This JS file exists to reset 'env' and 'globals',
// which ESLint doesn't have a built-in way to do otherwise.
// Because of this, we have to bypass semistandard.
const standard = require('eslint-config-standard');

const config = Object.assign(standard, {
env: {},
globals: {},
rules: Object.assign(standard.rules, {
// semistandard
semi: ['error', 'always'],
'no-extra-semi': 'error',
// disablements
'no-lone-blocks': 'off',
'node/no-callback-literal': 'off',
'prefer-const': 'off',
'prefer-promise-reject-errors': 'off',
// extra
'no-unused-vars': ['error', { args: 'all', argsIgnorePattern: '^_' }]
})
});

module.exports = config;
266 changes: 193 additions & 73 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,79 +1,199 @@
{
"root": true,
"env": {
"es6": true
},
"extends": ["eslint:recommended", "jquery"],
"parserOptions": {
"root": true,
"extends": ".eslintrc.base.js",
"plugins": [
"compat",
"html",
"json-es",
"markdown",
"qunit"
],
"reportUnusedDisableDirectives": true,
"ignorePatterns": [
"__codeorigin/**",
"coverage/**",
"docs/.jekyll-cache/**",
"docs/_site/**",
"lib/**",
"qunit/**",
"test/cli/fixtures/sourcemap/*.min.js",
"test/integration/*/**",
"temp/**"
],
"overrides": [
// Universal source code
// Written for compat with ES5 runtimes,
// ES6+ syntax is transpiled via Rollup. ES6+ APIs may not be used.
{
"files": ["src/**"],
"extends": ".eslintrc.base.js",
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module"
},
"globals": {
"clearTimeout": "off",
"setTimeout": "off"
},
"rules": {
"no-console": "error",
"compat/compat": [
"error",
"android >= 4.3, firefox >= 45, ie >= 9, safari >= 9.1, chrome >= 58"
]
}
},
// Universal test suites
// Strictly ES5 syntax for ES5 runtimes.
{
"files": ["test/**"],
"extends": [".eslintrc.base.js", "plugin:qunit/recommended"],
"parserOptions": {
"ecmaVersion": 5,
"sourceType": "script"
},
"globals": {
"QUnit": "readonly"
},
"rules": {
"compat/compat": [
"error",
"android >= 4.3, firefox >= 45, ie >= 9, safari >= 9.1, chrome >= 58"
],
"max-len": "off",
"no-throw-literal": "off",
"no-var": "off",
"prefer-regex-literals": "off",
"qunit/literal-compare-order": "off",
"qunit/no-arrow-tests": "off",
"qunit/no-assert-equal-boolean": "off",
"qunit/no-assert-logical-expression": "off",
"qunit/no-only": "off",
"qunit/require-expect": "off",
"qunit/resolve-async": "off"
}
},
"rules": {
"arrow-spacing": ["error", { "before": true, "after": true }],
"brace-style": ["error", "1tbs", { "allowSingleLine": true }],
"constructor-super": "error",
"indent": ["error", "tab", {
"CallExpression": {
"arguments": 1
},
"MemberExpression": 1,
"SwitchCase": 0,
"outerIIFEBody": 1
}],
// Node.js-specific source code
{
"files": [
"bin/**",
"build/**",
"src/cli/**",
"Gruntfile.js",
"rollup.config.js"
],
"excludedFiles": [
"build/coverage-bridge.js"
],
"extends": [".eslintrc.base.js", "plugin:node/recommended"],
"parserOptions": {
"ecmaVersion": 2020,
"sourceType": "script"
},
"env": {
"node": true
},
"rules": {
"compat/compat": "off",
"no-console": "off",
"no-const-assign": "error",
"no-constant-condition": ["error", { "checkLoops": false }],
"no-dupe-class-members": "error",
"no-duplicate-imports": "error",
"no-multi-spaces": ["error", { "ignoreEOLComments": true }],
"no-this-before-super": "error",
"no-useless-constructor": "error",
"no-useless-rename": "error",
"prefer-const": "error",
"rest-spread-spacing": ["error", "never"],
"wrap-iife": ["error", "any"]
"no-process-exit": "off",
"node/no-missing-require": "off",
"node/no-unpublished-require": "off"
}
},
// Misc overrides
{
"files": ["test/cli/**"],
"env": {
"es2017": true,
"node": true
},
"parserOptions": {
"ecmaVersion": 2018
},
"rules": {
"compat/compat": "off"
}
},
{
"files": ["test/mozjs.js"],
"parserOptions": {
"ecmaVersion": 6
},
"rules": {
"compat/compat": "off"
}
},
{
"files": ["test/es2018/**"],
"env": {
"es2017": true
},
"parserOptions": {
"ecmaVersion": 2018
},
"rules": {
"compat/compat": "off"
}
},
{
"files": ["test/node/**"],
"env": {
"es2017": true,
"node": true
},
"parserOptions": {
"ecmaVersion": 2018
},
"rules": {
"compat/compat": "off"
}
},
{
"files": ["test/**/*.html"],
"env": {
"browser": true
}
},
{
"files": ["**/*.mjs"],
"parserOptions": {
"sourceType": "module"
}
},
{
"files": ["**/*.md"],
"processor": "markdown/markdown"
},
{
"files": ["**/*.md/**"],
"parserOptions": {
"ecmaFeatures": {
"impliedStrict": true
}
},
"rules": {
// https://github.com/eslint/eslint/issues/15732
"array-bracket-spacing": "off",
"no-labels": "off",
"no-undef": "off",
"no-unused-expressions": "off",
"no-unused-vars": "off",
"no-var": "off",
"strict": "off"
}
},
"ignorePatterns": [
"__codeorigin/**",
"coverage/**",
"docs/_site/**",
"lib/**",
"qunit/**",
"test/integration/*/**",
"temp/**"
],
"overrides": [
{
"files": [
"bin/*.js",
"build/**/*.js",
"src/cli/*.js",
"Gruntfile.js",
"rollup.config.js"
],
"excludedFiles": [
"build/coverage-bridge.js"
],
"parserOptions": {
"sourceType": "script",
"ecmaVersion": 2020
},
"env": {
"node": true
},
"extends": ["plugin:node/recommended"],
"rules": {
"no-process-exit": "off"
}
},
{
"files": [
"test/**/*.html"
],
"extends": ["eslint:recommended", "jquery"],
"rules": {
"wrap-iife": ["error", "any"],
"indent": "off"
}
}
]
{
"files": ["**/*.json"],
"extends": [
"plugin:json-es/recommended"
],
"parser": "eslint-plugin-json-es",
"rules": {
// https://github.com/zeitport/eslint-plugin-json-es/issues/35
// "indent": ["error", 2]
"indent": "off"
}
}
]
}
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/.nyc_output/
/__codeorigin/
/coverage/
/docs/_site/
/docs/.jekyll-cache/
/docs/_site/
/docs/Gemfile.lock
/test/integration/*/package-lock.json
/test/integration/*/node_modules/
Expand Down
Loading

0 comments on commit 0f6ec7c

Please sign in to comment.