ESLint простым языком

внешний интерфейс ESLint

1. Предпосылки

javascript — это динамический язык со слабой типизацией, который компилируется во время выполнения, что приводит к множеству ошибок, которые могут быть обнаружены только во время выполнения, и их трудно найти в процессе кодирования;
eslint — подключаемый инструмент для обнаружения кода JS, разработчики могут писать свои собственные правила и находить несоответствующие позиции в исходном коде, чтобы помочь разработчикам найти проблемы в процессе программирования;

2 ворсовых инструмента

  1. JSLint: Обнаружение отправителя, прямое обнаружение строки исходного файла;меньше конфигурации,Строгие спецификации,Плохая масштабируемость,Не удалось найти соответствующее правило на основе ошибки;
  2. JSHint: Разработано на основе JSHint;Параметры правил можно настроить, предоставляя полный подключаемый модуль редактора, поддерживающий некоторые общие классы библиотек и es6, но не поддерживающий пользовательские правила и не могу найти соответствующие правила в соответствии с ошибками.;
  3. ESLint: На основе правил обнаружения дерева AST;Расширяемый синтаксический анализатор, расширяемые правила и конфигурация;

JSHint и ESlintФункции:

  1. JSHint напрямую определяет строку исходного файла, а ESLint преобразует исходный код в AST, а затем оценивает все правила, поэтому скорость выполнения JSHint будет выше, чем у ESlint;
  2. ESLint обладает хорошей масштабируемостью, ядром ESLint является определение того, соответствует ли AST правилам;
    1. Шаг 1: синтаксический анализатор преобразует исходный код в AST; синтаксический анализатор ESLint можно настраивать, исходный код использует любую расширенную грамматику или заменяется на TS, вы можете напрямую изменить синтаксический анализатор, чтобы получить окончательный AST, а eslint может выполнять сопоставление правил;
    2. Шаг 2: Правила выполнения, правила обнаружения ESLint могут быть настроены;

3 Основное использование

  1. Проект устанавливает eslint:yarn add eslint -D;
  2. Инициализировать конфигурацию eslint: eslint --init;
  3. Обнаружить eslint: запустить eslint;

3.1 Основные параметры

Настроить параметры в eslint можно двумя способами, один через конфигурационный файл, а другой через командную строку, параметры конфигурационного файла не обязательно включают командную строку.Для удобства просмотра и использования,Рекомендуется сначала настроить его в конфигурации;

3.1.1 Параметры .eslintrc

Для получения подробной информации, пожалуйста, проверьтеESL int.org/docs/user —…;

module.exports = {
	// 若项目中有多个子项目,且每个项目都会有.eslintrc,子项目会一直向上查找所有的.eslintrc,直到找到root:true的eslintrc,再将所有的.eslintrc合并
	'root': true,
	// 对环境定义的一组全局变量的预设 详细看:https://eslint.org/docs/user-guide/configuring/language-options#specifying-environments
	'env': {
		// 浏览器全局变量
		browser: true,
		// Node.js 全局变量和作用域
		node: true,
		// CommonJS全局变量和CommonJS作用域
		commonjs: true,
		// 启用除模块之外的所有ECMAScript 6功能
		es6: true
	},
	// 将数据提供给每一个将被执行的规则
	"settings": {
		"sharedData": "Hello"
	},
	// 继承另一个配置文件的所有特性
	'extends': [
		'eslint:recommended',
		'plugin:@typescript-eslint/recommended'
	],
	// 插件,向ESLint添加各种扩展,可以定义规则,环境或配置的第三方模块
	'plugins': [
		'@typescript-eslint'
	],
	// 全局变量
	'globals': {
		// false、readable、readonly 这 3 个是等价的,表示变量只可读不可写;
		// true、writeable、writable 这 3 个是等价的,表示变量可读可写;
		'$': true,
		'console': false
	},
	// 解释器
	'parser': '@typescript-eslint/parser',
	// 解释器的配置
	'parserOptions': {
		// 代码模块类型,可选script(默认),module
		'sourceType': 'module',
		// 指定ECMAScript版本,默认为5
		'ecamVersion': 6,
		// 额外的语言特性,所有选项默认都是 false
		'ecmaFeatures': {
			// 是否允许 return 语句出现在 global 环境下
			'globalReturn': true,
			// 是否开启全局 script 模式
			'impliedStrict': true,
			// 是否启用 JSX
			'jsx': true,
			// 是否启用对实验性的objectRest/spreadProperties的支持
			'experimentalObjectRestSpread': false
		}
	},
	// 规则
	'rules': {
		// 禁止使用 alert
		'no-alert': 'off',
		// 逗号前面没有空格 后面有空格
		'comma-spacing': [2, {
			'before': false, 'after': true
		}],
	}
};

3.1.2 Параметры командной строки

Для получения подробной информации, пожалуйста, проверьтеESL от /docs/user-a…;

eslint [options] file.js [file.js] [dir]

Basic configuration:
  --no-eslintrc                  禁止使用配置文件.eslintrc.*
  -c, --config path::String      指定使用.eslintrc.*配置文件的路径(可以不是这个名字)
  --env [String]                 指定环境
  --ext [String]                 指定JavaScript文件扩展名,默认值:.js
  --global [String]              定义全局变量
  --parser String                指定解析器
  --parser-options Object        指定解析器配置
  --resolve-plugins-relative-to path::String  应该从中解析插件的文件夹,默认为CWD

Specifying rules and plugins:
  --rulesdir [path::String]      使用其他规则的目录
  --plugin [String]              指定插件
  --rule Object                  指定规则

Fixing problems:
  --fix                          自定修复eslint问题
  --fix-dry-run                  自动修复问题但不保存对文件的更改
  --fix-type Array               指定要应用的修复类型(问题、建议、布局)

Ignoring files:
  --ignore-path path::String     指定忽略的路径 即指定一个文件作为.eslintignore
  --no-ignore                    禁用忽略文件和模式的使用
  --ignore-pattern [String]      要忽略的文件模式(除了.eslintignore中的文件)

Using stdin:
  --stdin                        <STDIN>上提供的Lint代码-默认值:false
  --stdin-filename String        指定STDIN的文件名

Handling warnings:
  --quiet                        仅报告错误-默认值:false
  --max-warnings Int             触发退出代码的警告次数-默认值:-1

Output:
  -o, --output-file path::String  指定要将报告写入的文件
  -f, --format String            使用特定的输出格式-默认值:stylish
  --color, --no-color            强制启用/禁用颜色

Inline configuration comments:
  --no-inline-config             防止注释更改配置或规则
  --report-unused-disable-directives  添加错误信息给未被使用的eslint-disable指令

Caching:
  --cache                        仅检查已更改的文件-默认值:false
  --cache-file path::String      缓存文件的路径,不推荐使用:使用--cache-location - 默认值:.eslintcache
  --cache-location path::String  缓存文件或目录的路径

Miscellaneous:
  --init                         运行配置初始化向导-默认值:false
  --debug                        输出调试信息
  -h, --help                     显示help文档
  -v, --version                  输出版本号
  --print-config path::String    打印给定文件的配置

3.2 Дополнение общих концепций параметров

3.2.1 Парсер

  1. esprima: парсер, использовавшийся на заре eslint;
  2. espree: разработан на основе esprema v1.2.2, теперь парсер по умолчанию;
  3. @babel/eslint-parser: синтаксический анализатор расширенной грамматики js;
  4. @typescript-eslint/parser: парсер для ts;

3.2.2 Конфигурация правил

  1. "off" или 0: отключить правило;
  2. "warn" или 1: включить правило, использовать ошибки уровня предупреждения: warn (не приводит к выходу из программы);
  3. «ошибка» или 2: включить правило, использовать уровень ошибки error: error (при срабатывании программа завершится);

3.2.3 Типы конфигурации, поддерживаемые расширениями

  1. Начиная с eslint: официальное расширение ESLint;
  2. В начале плагина: расширение типа плагина, однозначное соответствие с конфигурацией в конфигах;
  3. Начиная с пакета eslint-config: npm, вы можете опустить префикс eslint-config- при использовании;
  4. Путь к файлу;

Общие расширения:

  1. eslint:recommended: рекомендуемые встроенные правила ESLint, то есть те правила, которые отмечены галочкой в ​​списке правил ESLint;
  2. eslint:all: все правила, встроенные в ESLint;
  3. eslint-config-standard: стандартная спецификация JS;
  4. eslint-config-prettier: закрывает конфликтующие правила в ESLint и других расширениях;
  5. eslint-plugin-vue: официальный плагин конфигурации eslint для vue.
    1. плагин:vue/база:база;
    2. плагин: vue/основной: существенный;
    3. плагин: vue/рекомендуется: рекомендуется;
    4. плагин: vue/настоятельно рекомендуется: настоятельно рекомендуется;

3.3 Настройка файлов или каталогов, для которых не требуется lint

Вы можете указать соответствующий файл или каталог в .eslintignore, чтобы избежать обнаружения при выполнении eslint (сам eslint игнорирует node_modules и bower_components), например:

mock
build/*.js
config/*.js

4 Совместное использование конфигурации ESLint

Спецификации каждой команды разные.Компания надеется, что спецификации каждой линейки продуктов согласуются, поэтому конфигурацию можно будет разделить и упаковать в пакет npm для прямой настройки и использования разными командами;

Как написать файл конфигурации?

  1. Создайте папку с именем eslint-config-myconfig;
  2. воплощать в жизньyarn init -y; (имя модуля должно начинаться с eslint-config-, имя файла проекта указывать необязательно);
  3. Создайте index.js и напишите в нем конфигурацию .eslintrc.js, которая будет использоваться совместно;
  4. использоватьpeerDependenciesESLint, от которого зависит объявление поля (явно плагину требуется ESLint для правильной работы);
  5. Вы можете отправить пакет;

PS: Все плагины, написанные в виде отправки пакетов, поддерживают форму @scope/eslint-xxx-xxx,Подробности;

Как использовать вышеуказанный пакет?

  1. Установите такие пакеты, как:yarn add eslint-config-myconfig -D;
  2. Настройте конфигурацию расширений в файле .eslintrc в проекте и см. основные сведения об использовании;

5 Плагин ESLint

5.1 Что такое плагин ESLint?

Плагины могут добавлять в ESLint различные расширения и являются сторонними модулями, определяющими правила, среды, процессоры или конфигурации;

Как настроить плагин ESLint?

использоватьgenerator-eslintСоздайте проект. Имя модуля проекта должно начинаться с eslint-plugin-. При его использовании удалите eslint-plugin-;

Например, имя пакета npm: eslint-plugin-myplugin;

5.1.1 Определение правил

Правила: Правильный метод обнаружения eslint;
Метод определения: предусматривает, что объект правил должен быть выставлен;

// 这是插件的index.js
module.exports = {
	rules: {
		'my-rule': {
			// 规则的一些数据配置
			meta: {
				// 规则的类型 "problem"、"suggestion" 或 "layout"
				type: 'suggestion',
				// 文档信息 自定义规则或插件中可省略,对eslint核心规则是必须的
				docs: {
					description: '规则的简短描述,在eslint规则首页展示',
					category: '规则在规则首页处于的分类',
					recommended: true, // "extends": "eslint:recommended"属性是否启用该规则
					url: 'https://eslint.org/docs/rules/no-extra-semi' // 访问完整文档的 url
				},
				// 打开修复功能,如果没有 fixable 属性,即使规则实现了 fix 功能,ESLint 也不会进行修复。如果规则不是可修复的,就省略 fixable 属性
				fixable: 'code',
				// 指定该规则对应的配置,用于验证配置的选项是否有效
				schema: [
            {
                "enum": ["always", "never"]
            },
            {
                "type": "object",
                "properties": {
                    "exceptRange": {
                        "type": "boolean"
                    }
                },
                "additionalProperties": false
            }
        ]
			},
			// create 返回一个对象,对象的格式是key对应一个回调方法;这个对象包含了ESLint在遍历JavaScript代码的AST树(ESTree定义的AST)时,用来访问节点的方法。
			// context 当前执行eslint时的上下文对象,其中包含了各种相关数据,如eslint的配置信息、当前遍历节点的信息、报告问题的方法等;
			create: function (context) {
				return {
					// callback functions
					ReturnStatement: function (node) {
						// at a ReturnStatement node while going down
					},
					// at a function expression node while going up:
					'FunctionExpression:exit': function checkLastSegment (node) {
						// report problem for function if last code path segment is reachable
					},
					'ArrowFunctionExpression:exit': function checkLastSegment (node) {
						// report problem for function if last code path segment is reachable
					},
					onCodePathStart: function (codePath, node) {
						// at the start of analyzing a code path
					},
					onCodePathEnd: function (codePath, node) {
						// at the end of analyzing a code path
					}
				};
			}
		}
	}
};

Как использовать:

module.exports = {
  	"plugins": ["myplugin"],
  	"rules": {
    		"myplugin/my-rule": [2, "never", { "exceptRange": true }],
    }
}

5.1.1.1 Параметры правил

Метапараметр правил предназначен для заполнения некоторой базовой информации, а значение параметра создания представляет собой метод обратного вызова, используемый для выполнения правила обнаружения AST;

Параметр контекста создания:

  1. id: имя правила, настроенное в правилах .eslintrc, как в случае использования выше.myplugin/my-rule;
  2. options: параметры правила, настроенные в правилах .eslintrc, например результат приведенного выше примера: ["never", {exceptRange: true}]
  3. отчет: используется для выдачи предупреждений или ошибок, оценки вызова в обратном вызове;Конкретные параметры;

Дополнительные параметры контекста:ESL междунар. VELO для /docs/…;

Возвращаемый объект создания:

  • Если ключ является типом узла или селектором, ввнизПри обходе дерева ESLint вызываетvisitorфункция;
  • Если ключ является типом узла или селектором с:exit,существуетвверхПри обходе дерева ESLint вызываетvisitorфункция;
  • Если ключ является именем события, ESLintАнализ пути кодапередачаhandlerфункция;

Тип узла:Тип узла AST;

детали следующим образом:

серийный номер Введите исходное имя китайское имя описывать
1 Program тело программы тело всего кода
2 VariableDeclaration объявление переменной объявить переменную, например, var let const
3 FunctionDeclaration объявление функции объявить функцию, например, function
4 ExpressionStatement оператор выражения Обычно путем вызова такой функции, как console.log()
5 BlockStatement оператор блока Код, заключенный в блок {}, например, if (condition) {var a = 1;}
6 BreakStatement оператор перерыва обычно относится к разрыву
7 ContinueStatement оператор продолжения обычно относится к продолжению
8 ReturnStatement оператор возврата обычно относится к возвращению
9 SwitchStatement оператор переключения Обычно относится к Switch в операторе Switch Case.
10 IfStatement Если оператор управления потоком Оператор потока управления, обычно называемый if(условие){}else{}
11 Identifier идентификатор Идентичности, такие как identi в var identi = 5 при объявлении переменной
12 CallExpression выражение вызова Обычно относится к вызову функции, такой как console.log().
13 BinaryExpression бинарное выражение Обычно относится к операциям, таким как 1+2
14 MemberExpression выражение члена Обычно относится к члену вызывающего объекта, например члену журнала консольного объекта.
15 ArrayExpression выражение массива Обычно относится к массиву, например [1, 3, 5]
16 NewExpression Новое выражение Обычно относится к использованию нового ключевого слова
17 AssignmentExpression выражение присваивания Обычно относится к значению возвращаемого функцией значения переменной
18 UpdateExpression Обновить выражение Обычно относится к обновлению значений членов, например i++
19 Literal буквальный буквальный
20 BooleanLiteral логический литерал логическое значение, такое как true false
21 NumericLiteral числовой литерал число, например 100
22 StringLiteral символьный литерал строка, например, vansenb
23 SwitchCase Заявление о случае Обычно относится к Case в операторе Switch.

Кстати, вы можете взглянуть на типы узлов vue:GitHub.com/v UE JS/v UE - о...

селектор: это строка, которую можно использовать для сопоставления узлов в абстрактном синтаксическом дереве (AST). Это полезно для описания конкретных синтаксических шаблонов в коде. Селекторы не ограничиваются сопоставлением одного типа узла. Например, селектор «VariableDeclarator > Identifier» будет соответствовать всем идентификаторам, имеющим VariableDeclarator.Подробности;

мероприятие: анализ событий, вызванных кодовым путем;

module.exports = function(context) {
	return {
		/**
		 * 这在分析代码路径的开始时被调用,此时,代码路径对象只有初始段。
		 *
		 * @param {CodePath} codePath - The new code path.
		 * @param {ASTNode} node - The current node.
		 * @returns {void}
		 */
		"onCodePathStart": function(codePath, node) {
			// do something with codePath
		},
		
		/**
		 * 这在分析代码路径的末尾被调用。此时,代码路径对象已经完成。
		 *
		 * @param {CodePath} codePath - The completed code path.
		 * @param {ASTNode} node - The current node.
		 * @returns {void}
		 */
		"onCodePathEnd": function(codePath, node) {
			// do something with codePath
		},
		
		/**
		 * 这在创建代码路径段时调用。
		 * 这意味着代码路径是分叉或合并的。
		 * 在这段时间内,该段具有先前的段,并且已被判断为可到达或不可到达。
		 *
		 * @param {CodePathSegment} segment - The new code path segment.
		 * @param {ASTNode} node - The current node.
		 * @returns {void}
		 */
		"onCodePathSegmentStart": function(segment, node) {
			// do something with segment
		},
		
		/**
		 * 这是在代码路径段离开时调用的。
		 * 此时还没进入下个阶段。
		 *
		 * @param {CodePathSegment} segment - The leaved code path segment.
		 * @param {ASTNode} node - The current node.
		 * @returns {void}
		 */
		"onCodePathSegmentEnd": function(segment, node) {
			// do something with segment
		},
		
		/**
		 * 在代码路径段被循环时调用的。
		 * 通常每段在创建时都有以前的段,
		 * Usually segments have each previous segments when created,
		 * but when looped, a segment is added as a new previous segment into a
		 * existing segment.
		 *
		 * This is called when a code path segment was looped.Usually segments have each previous segments when created,but when looped, a segment is added as a new previous segment into aexisting segment.
		 *
		 * 当循环代码路径段时调用此函数。通常创建段时,段具有每个先前段,但循环时,段作为新的先前段添加到现有段中。
		 * @param {CodePathSegment} fromSegment - A code path segment of source.
		 * @param {CodePathSegment} toSegment - A code path segment of destination.
		 * @param {ASTNode} node - The current node.
		 * @returns {void}
		 */
		"onCodePathSegmentLoop": function(fromSegment, toSegment, node) {
			// do something with segment
		}
	};
};

ESL междунар. VELO для /docs/…

5.1.2 Определение среды

Среда: это групповая конфигурация, например, jquery внутри всех глобальных переменных;

Среда плагина может определять следующие объекты:
глобальные:То же, что и глобальные переменные в файле конфигурации.
параметры парсера:То же, что и parserOptions в файле конфигурации.

Определение: объект окружения должен быть открыт;

// 这是插件的index.js
module.exports = {
    environments: {
        jquery: {
            globals: {
                $: false
            },
            parserOptions: {
            }
        }
    }
};

Как использовать:

module.exports = {
  	"plugins": ["myplugin"],
  	"env": {
    		"myplugin/jquery": true,
    }
}

5.1.3 Определение процессора

eslint может определять только js, если это другие файлы, то нужно настраивать кастомные процессоры;
Метод определения: процессоры должны быть открыты, с суффиксом файла в качестве ключа, включая функцию, которая принимает содержимое файла и имя файла в качестве параметров и возвращает массив строк для обнаружения;

// 这是插件的index.js
// processor-name
module.exports = {
	processors: {
		
		// 不同后缀名 (.js, .jsx, .html, etc.)
		".ext": {
			// 获取文件的文本和文件名
			preprocess: function(text, filename) {
				
				// 在这里,您可以去掉任何非JS内容,并将其拆分为多个字符串以进行lint
				return [string];  // return an array of strings to lint
			},
			
			// 获取Message[][]和文件名
			postprocess: function(messages, filename) {
				// `messages`参数是一个包含消息对象的二维数组,其中每个数组项的第一个参数包含了preprocess()方法返回的文本相关的lint消息数组
				// postprocess 方法接受一个二维数组,包含检测消息和文件名。输入数组中的每一项都对应从 preprocess 方法返回的部分。preprocess 方法必须调整所有错误的位置,使其与原始的未处理的代码中的位置相对应,并将它们聚合成一个打平的数组并返回。
				// 返回你想保留的一维数组
				return messages[0];
			},
			
			supportsAutofix: true // (optional, defaults to false)
		}
	}
};

Как использовать:

// 方式一:统一
module.exports = {
  	"plugins": ["myplugin"],
  	"processor": "myplugin/processor-name"
}
// 方式二:为特定类型的文件指定处理器
module.exports = {
  	"plugins": ["myplugin"],
  	"overrides": [
        {
            "files": ["*.md"],
            "processor": "a-plugin/markdown"
        },
        {// 在 config 部分为命名代码块指定其他配置
            "files": ["**/*.md/*.js"],
            "rules": {
                "strict": "off"
            }
        }
    ]
}

5.1.4 Определение конфигурации

В дополнение к совместному использованию конфигурации путем отправки пакетов напрямую (Пункт 4 этой главыметод), вы также можете поделиться конфигурацией в виде плагинов, а также поддерживает несколько конфигураций плагина; например, если вы написали несколько правил и хотите поделиться конфигурацией нескольких стилей кода с помощью способ, вы можете использовать это;

// 这是插件的index.js
module.exports = {
    configs: {
        myConfig: {
            plugins: ["myPlugin"],
            env: ["browser"],
            rules: {
                semi: "error",
                "myPlugin/my-rule": "error",
                "eslint-plugin-myPlugin/another-rule": "error"
            }
        },
        myOtherConfig: {
            plugins: ["myPlugin"],
            env: ["node"],
            rules: {
                "myPlugin/my-rule": "off",
                "eslint-plugin-myPlugin/another-rule": "off"
                "eslint-plugin-myPlugin/yet-another-rule": "error"
            }
        }
    }
};

Как использовать:

  1. Добавьте плагин в конфигурацию плагинов;
  2. Конфигурация расширения используется напрямую;
module.exports = {
	plugins: ['myPlugin'],
  extends: ['plugin:myPlugin/myConfig', 'plugin:myPlugin/myOtherConfig']
}

5.2 Как прописать правила отдельно в проекте?

Написание отдельного плагина требует упаковки, что приводит к длительному процессу добавления правил и не обязательно подходит для других линеек продуктов, в этом случае пользовательские правила нужно добавлять в одном проекте;

5.2.1 Метод 1: IDE не распознает

Используйте собственный параметр eslint --rulesdir, чтобы получить правила в дополнительных файлах проекта; этот метод действителен только при запуске команды eslint;

Шаги настройки:

  1. Добавьте папку eslint-rules в каталог того же уровня проекта .eslintrc и добавьте в этот каталог пользовательские правила (создание правила: 5.1.1);
  2. Добавьте соответствующее правило xxx:2 в правила в .eslintrc;
  3. Измените команду eslint на:eslint --rulesdir eslint-rules --ext .vue,.js,.ts src; (также можно настроить в webpack или vite)

Результаты: команда будет обнаружена;
Недостатки: Редактор его не распознает, и он будет помечать первую строку каждого файла красным, чтобы сказать, что соответствующее правило не может быть найдено, и реальная проблема не будет помечена красным;

5.2.2 Метод 2: распознавание IDE

Используйте плагин eslint-plugin-rulesdir;
шаг:

  1. Добавьте папку eslint-rules в каталог того же уровня проекта .eslintrc и добавьте в этот каталог пользовательские правила (создание правила: 5.1.1);
  2. Установитьплагин:yarn eslint-plugin-rulesdir -D;
  3. Измените конфигурацию .eslintrc;
const rulesDirPlugin = require('eslint-plugin-rulesdir');
// 规则对应的目录 可以是字符串或字符串数组
rulesDirPlugin.RULES_DIR = 'eslint-rules';

module.exports = {
    // ...
    plugins: ['rulesdir'],
    rules: {
        // xxx为对应的自定义规则
        'rulesdir/xxx': ['error'],
    },
};

Результат: Не нужно указывать --rulesdir, правила распознаются, и редактор тоже распознает;

6 Оптимальное использование сопутствующих инженерных решений

Инжиниринг проекта может повысить эффективность разработки и уменьшить количество ошибок, которых легко избежать; ниже приведены некоторые полезные инструменты, которые можно использовать с eslint:

  1. husky: выполнить команду eslint перед фиксацией, если eslint не прошла, фиксация не удалась;
  2. lint-staged: Хуки запуска хаски только для полученных постановочных файлов;
  3. prettier: изменить стиль кода, независимо от стиля кода, независимо от некоторых низкоуровневых проблем; если есть какие-то конфигурации, конфликтующие с eslint, вы можете сотрудничатьeslint-plugin-prettierиспользуется с эслинтом;
  4. mrm: автоматическая установка и настройка husky и lint-staged в соответствии с package.json, поэтому обязательно перед этим установите и настройте все инструменты качества кода, такие как Prettier и ESlint;

Использование этих инструментов не будет повторяться, это относительно просто, просто проверьте официальные документы;