предисловие
Несмотря на то, что существует множество полезных подключаемых модулей ESLint, по мере того, как проект продолжает итеративно развиваться, вы можете столкнуться с ситуациями, когда существующие подключаемые модули ESLint не могут соответствовать текущей групповой разработке. На этом этапе вам нужно самостоятельно создать плагин ESLint.
В этой статье я расскажу вам об общей истории различных инструментов Lint, а затем шаг за шагом создам свой собственный плагин ESLint и научу вас его использовать.AST
Абстрактное синтаксическое дерево для формулировки правил этого плагина.
Это поможет вам понять принцип реализации ESLint.
Цели и очки знаний
эта статьяESLint
Цель плагина — отключить в разработке проекта:console.time()
.
- Абстрактное синтаксическое дерево AST
- ESLint
- публиковать нпм
- модульный тест
Сборка строительных лесов плагинов
Здесь мы используемyeomanа такжеgenerator-eslintСкаффолдинг-код для сборки плагина. Установить:
npm install -g yo generator-eslint
Создайте новую локальную папку eslint-plugin-demofortutorial:
mkdir eslint-plugin-demofortutorial
cd eslint-plugin-demofortutorial
Инициализируйте структуру проекта плагина ESLint:
yo eslint:plugin // 搭建一个初始化的目录结构
Структура каталогов файла на данный момент такова:
.
├── README.md
├── lib
│ ├── index.js
│ └── rules
├── package.json
└── tests
└── lib
└── rules
Установите зависимости:
npm install
На этом этапе среда настроена.
Создать правило
Терминальное исполнение:
yo eslint:rule // 生成默认 eslint rule 模版文件
.
├── README.md
├── docs // 使用文档
│ └── rules
│ └── no-console-time.md
├── lib // eslint 规则开发
│ ├── index.js
│ └── rules // 此目录下可以构建多个规则,本文只拿一个规则来讲解
│ └── no-console-time.js
├── package.json
└── tests // 单元测试
└── lib
└── rules
└── no-console-time.js
В приведенной выше структуре нам нужно разрабатывать плагины Eslint в каталоге ./lib/, вот расположение определяющих его правил.
АСТ в ESLint
в официальной письменной формеESLint
Перед подключением необходимо понятьESLint
Принцип работы. вESLint
Метод использования должен быть знаком всем, я не буду его здесь объяснять, если вы не понимаете, вы можете нажать на официальную документацию.Как настроить ESLint в своем проекте.
При разработке командных проектов компании исходный код, написанный разными разработчиками, отличается, то вESLint
Как анализировать исходный код, написанный каждым человеком?
Как разработчики, перед лицом таких проблем мы должны знать, как использоватьабстрактные средства! ТакJavascript
Как воплощается абстракция?
Вот такAST
(Абстрактное синтаксическое дерево (AST)), а затем идет стократно просмотренная диаграмма предложения.
существуетESLint
, esprima используется по умолчанию для разбора того, что мы пишемJavascript
оператор, пусть он сгенерирует абстрактное синтаксическое дерево, а затем перейдите кперехватыватьПроверьте, соответствует ли он нашему предписанному методу записи, и, наконец, позвольте ему отобразить ошибку, предупреждение или нормальный проход.ESLint
Суть в правиле(rules
), а ядро определения правил является использованиеAST
проверить. Каждое правило не зависит друг от друга и может быть отключено установкойoff
,предупреждатьwarn
⚠️ и ошибкаerror
❌, разумеется, никаких подсказок для нормального прохождения давать не нужно.
создание правила
вышеизложенное закончилосьESLint
а такжеAST
После отношений мы можем официально ввести разработку конкретных правил. Сначала посмотрите на ранее сгенерированныйlib/rules/no-console-time.js
:
/**
* @fileoverview no console.time()
* @author Allan91
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = {
meta: {
docs: {
description: "no console.time()",
category: "Fill me in",
recommended: false
},
fixable: null, // or "code" or "whitespace"
schema: [
// fill in your schema
]
},
create: function(context) {
// variables should be defined here
//----------------------------------------------------------------------
// Helpers
//----------------------------------------------------------------------
// any helper functions should go here or else delete this section
//----------------------------------------------------------------------
// Public
//----------------------------------------------------------------------
return {
// give me methods
};
}
};
Этот файл дает шаблон для написания правил, одно правило соответствует экспортируемомуnode
модуль, который состоит изmeta
а такжеcreate
Состоит из двух частей.
- meta представляет собой метаданные этого правила, такие как его категория, документ, схема допустимых параметров и т. д.
- create: если meta выражает то, что мы хотим сделать, то create выражает то, как это правило будет анализировать код;
Create возвращает объект, наиболее распространенный из которыхимя ключадаAST
в абстрактном синтаксическом деревеСелектор, в этом селекторе мы можем получить соответствующий выбранный контент, а затем мы можем сделать определенные суждения для выбранного контента, чтобы увидеть, удовлетворяет ли он нашим правилам. Если не устраивает, доступенcontext.report
кидать вопросы,ESLint
Будет использовать нашу конфигурацию для отображения брошенного контента по-другому.
Для получения подробной информации о конфигурации конкретных параметров см.официальная документация
Создано этой статьейESLint
Плагины предназначены для предотвращения использования их разработчиками в проектах.console.time()
, сначала посмотрите, как этот код выглядит в абстрактном синтаксическом дереве:
Среди них мы будем использовать следующий контент, чтобы определить, содержит ли кодconsole.time
:
Тогда мы на основе вышеизложенногоAST
(Абстрактный китайский метод)lib/rules/no-console-time.js
Напишите правила так:
/**
* @fileoverview no console.time()
* @author Allan91
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = {
meta: {
docs: {
description: "no console.time()",
category: "Fill me in",
recommended: false
},
fixable: null, // or "code" or "whitespace"
schema: [
// fill in your schema
],
// 报错信息描述
messages: {
avoidMethod: "console method '{{name}}' is forbidden.",
},
},
create: function(context) {
return {
// 键名为ast中选择器名
'CallExpression MemberExpression': (node) => {
// 如果在ast中满足以下条件,就用 context.report() 进行对外警告⚠️
if (node.property.name === 'time' && node.object.name === 'console') {
context.report({
node,
messageId: 'avoidMethod',
data: {
name: 'time',
},
});
}
},
};
}
};
Изменить сноваlib/index.js
:
"use strict";
module.exports = {
rules: {
'no-console-time': require('./rules/no-console-time'),
},
configs: {
recommended: {
rules: {
'demofortutorial/no-console-time': 2, // 可以省略 eslint-plugin 前缀
},
},
},
};
Слишком далеко,Eslint
Плагин создан. Все, что вам нужно сделать дальше, это опубликовать этот проект вплатформа нпм.
Выполнение корневого каталога:
npm publish
Открытьnpmплатформу, вы можете выполнить поиск по опубликованным вышеeslint-plugin-demofortutorial
Пакет узлов.
как использовать
После публикации установите этот пакет в нужные вам проекты:
npm install eslint-plugin-demofortutorial -D
затем в.eslintrc.js
Средняя конфигурация:
"extends": [
"eslint:recommended",
"plugin:eslint-plugin-demofortutorial/recommended",
],
"plugins": [
'demofortutorial'
],
если не раньше.eslintrc.js
файл, вы можете выполнить следующую команду для создания:
npm install -g eslint
eslint --init
На этом этапе, если текущий проектJS
запись в документеconsole.time
, появятся следующие эффекты:
Модульное тестирование (идеальное)
для полногоnpm
С точки зрения пакетов вышеописанное является лишь «полуфабрикатом», и нам необходимо написать юнит-тесты, чтобы обеспечить его целостность и безопасность.
Далее, чтобы завершить модульный тест, в./tests/lib/rules/no-console-time.js
Напишите следующий код в:
'use strict';
// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------
let rule = require('../../../lib/rules/no-console-time');
let RuleTester = require('eslint').RuleTester;
// ------------------------------------------------------------------------------
// Tests
// ------------------------------------------------------------------------------
let ruleTester = new RuleTester({
parserOptions: {
ecmaVersion: 10,
},
});
ruleTester.run('no-console-time', rule, {
valid: [ // 合法示例
'_.time({a:1});',
"_.time('abc');",
"_.time(['a', 'b', 'c']);",
"lodash.time('abc');",
'lodash.time({a:1});',
'abc.time',
"lodash.time(['a', 'b', 'c']);",
],
invalid: [ // 不合法示例
{
code: 'console.time()',
errors: [
{
messageId: 'avoidMethod',
},
],
},
{
code: "console.time.call({}, 'hello')",
errors: [
{
messageId: 'avoidMethod',
},
],
},
{
code: "console.time.apply({}, ['hello'])",
errors: [
{
messageId: 'avoidMethod',
},
],
},
{
code: 'console.time.call(new Int32Array([1, 2, 3, 4, 5]));',
errors: 1,
},
],
});
Подробнее о приведенном выше тестовом коде см.официальная документация.
Выполнение корневого каталога:
npm run test
На этом разработка этого пакета завершена. Разработка других правил аналогична, например, вы можете продолжить разработку других спецификаций, таких как ️console.log()
,debugger
Предупреждение и тд.
разное
из-за автогенерацииESLint
проект зависит отeslint
Версия все еще находится на стадии 3.x, что приведет к следующим ошибкам при разборе синтаксиса модульного теста:
'Parsing error: Invalid ecmaVersion.'
Рекомендуется обновить пакет до"eslint": "^5.16.0"
.
над.
ПроверитьРепозиторий проекта на Github
ПроверитьПакеты, опубликованные на Npm
Использованная литература:
zhuanlan.zhihu.com/p/32297243 En. Wikipedia.org/wiki/lint_(… octoverse.github.com/ jslint.com medium.com/@Anton/why-… Woohoo.Фермер online.net/blog/2013/0… eslint.org jscs.info GitHub.com/Вавилон/Вавилон… GitHub.com/Yanni Passenger Access/О… Woohoo.Фермер online.net/blog/2016/0… medium.com/@mark E log/ просто…
Внеклассные знания: краткая история Lint
Lint 是为了解决代码不严谨而导致各种问题的一种工具。 Например==
а также===
Сочетание может вызвать некоторые странные проблемы.
JSLint и JSHint
В 2002 году Дуглас Крокфорд разработал, возможно, первый инструмент проверки синтаксиса для JavaScript — JSLint, исходный код которого был открыт в 2010 году.
JSLint действительно помог многим разработчикам JavaScript сэкономить много времени на устранении неполадок в своем коде с момента его появления. Но проблема с JSLint тоже очевидна —трудно настраиваемый, все стили кода и правила встроены; кроме того, Дуглас Крокфорд соблюдает прекрасную традицию «использовать и использовать» в даосизме и не будет нарушать открытую конфигурацию или изменять правила, которые он считает правильными. Так что Антон Ковалев пожаловался: «JSLint нужен только для того, чтобы сделать стиль вашего кода более похожим на Дугласа Крокфорда», и в 2011 году форкнул оригинальный проект для разработки JSHint.«Почему я разветвил JSLint на JSHint»
Характеристики JSHint:Настраиваемый, а документация относительно полная и удобная для разработчиков. Вскоре люди перешли с JSLint на JSHint.
Рождение ESLint
В ближайшие несколько лет все будут использовать JSHint в первую очередь для инструментов обнаружения кода, но поворотный момент наступил в 2013 году, когда Закас обнаружил, что JSHint не может удовлетворить потребности его собственного нормотворчества, и сотрудничал с Антоном.
После обсуждения выяснилось, что на JShint этого добиться невозможно, и Закас также предполагает изобрестиAST
корп. Итак, в июне 2013 года Zakas выпустила новый инструмент для анализа — ESLint.«Знакомство с ESLint»
var ast = esprima.parse(text, { loc: true, range: true }),
walk = astw(ast);
walk(function(node) {
api.emit(node.type, node);
});
return messages;
Контратака ESLint
Появление ESLint не поколебало доминирования JSHint.Поскольку первый использует правила обработки AST и использует Esprima для разбора кода, скорость выполнения намного ниже, чем у JSHint, для которого требуется всего один шаг.; Во-вторых, уже было много редакторов, которые имели идеальную поддержку JSHint, и экология была достаточно сильна. Что действительно делает ESLint контратакой, так этоECMAScript 6
внешность.
В июне 2015 года была официально выпущена спецификация ES2015. Однако после релиза представленные на рынке браузеры имеют крайне ограниченную поддержку последних стандартов. Если вы хотите заранее испытать новейший стандартный синтаксис, вы должны полагаться наBabel
Подобные инструменты компилируют код до ES5 или ниже, а некоторые экспериментальные функции можно транспилировать с помощью Babel.
Но в настоящее время JSHint не может обеспечить поддержку в краткосрочной перспективе, а ESLint нужен только подходящий синтаксический анализатор для продолжения проверки lint. Команда Babel разработала инструмент для ESLint, чтобы заменить парсер по умолчанию, что мы и видим сейчас.babel-eslint
, что делает ESLint первым инструментом lint, поддерживающим синтаксис ES6.
Также в 2015 году все более широкое распространение становился React, а появившийся вскоре JSX становился все более популярным. Сам ESLint также не поддерживает синтаксис JSX. Но из-за масштабируемости,eslint-plugin-react
Появление ESLint позволяет ESLint в то же время поддерживать правила, специфичные для React.
В 2016 году команда разработчиков JSCS посчитала, что принципы реализации ESLint и JSCS слишком похожи, а проблемы, которые нужно было решить, были одинаковыми, и в конце концов решила объединиться с ESLint и прекратить обслуживание JSCS.
Текущие основные инструменты lint и графики трендов на рынке:
С тех пор ESLint доминировал в реках и озерах и стал основным интерфейсным инструментом для замены JSHint.