Add eslint, prettier, env to the application.
It’s a pity that Angular, by default, does not generate all this itself. Changing schematics can improve the quality of several thousand Angular projects.
Connect eslint:
yarn ng add @angular-eslint/schematics
Three packages have been added to package.json:
{ "devDependencies": { …, "angular-eslint": "18.0.1", "eslint": "^9.3.0", "typescript-eslint": "8.0.0-alpha.20" } }
And in target in angular.json:
{ "projects": { "buy-and-fly": { "architect": { …, "lint": { "builder": "@angular-eslint/builder:lint", "options": { "lintFilePatterns": [ "src/**/*.ts", "src/**/*.html" ] } } } } }, "cli": { "schematicCollections": [ "@angular-eslint/schematics" ] } }
The eslint.config.js file was also created:
// @ts-check const eslint = require("@eslint/js"); const tseslint = require("typescript-eslint"); const angular = require("angular-eslint"); module.exports = tseslint.config( { files: ["**/*.ts"], extends: [ eslint.configs.recommended, ...tseslint.configs.recommended, ...tseslint.configs.stylistic, ...angular.configs.tsRecommended, ], processor: angular.processInlineTemplates, rules: { "@angular-eslint/directive-selector": [ "error", { type: "attribute", prefix: "app", style: "camelCase", }, ], "@angular-eslint/component-selector": [ "error", { type: "element", prefix: "app", style: "kebab-case", }, ], }, }, { files: ["**/*.html"], extends: [ ...angular.configs.templateRecommended, ...angular.configs.templateAccessibility, ], rules: {}, } );
Basic linters are good, but you can make them better!
Add a plugin:
yarn add -D eslint-plugin-simple-import-sort
Let's include several rules:
// @ts-check const eslint = require('@eslint/js'); const tseslint = require('typescript-eslint'); const angular = require('angular-eslint'); const simpleImportSort = require('eslint-plugin-simple-import-sort'); module.exports = tseslint.config( { files: ['**/*.ts'], extends: [ eslint.configs.recommended, ...tseslint.configs.recommended, ...tseslint.configs.stylistic, ...angular.configs.tsRecommended, { plugins: { 'simple-import-sort': simpleImportSort, }, rules: { 'simple-import-sort/imports': [ 'error', { groups: [['^\\u0000'], ['^@?(?!baf)\\w'], ['^@baf?\\w'], ['^\\w'], ['^[^.]'], ['^\\.']], }, ], 'simple-import-sort/exports': 'error', }, }, ], processor: angular.processInlineTemplates, rules: { '@angular-eslint/directive-selector': [ 'error', { type: 'attribute', prefix: 'baf', style: 'camelCase', }, ], '@angular-eslint/component-selector': [ 'error', { type: 'element', prefix: 'baf', style: 'kebab-case', }, ], '@typescript-eslint/naming-convention': [ 'error', { selector: 'default', format: ['camelCase'], leadingUnderscore: 'allow', trailingUnderscore: 'allow', filter: { regex: '^(ts-jest|\\^.*)$', match: false, }, }, { selector: 'default', format: ['camelCase'], leadingUnderscore: 'allow', trailingUnderscore: 'allow', }, { selector: 'variable', format: ['camelCase', 'UPPER_CASE'], leadingUnderscore: 'allow', trailingUnderscore: 'allow', }, { selector: 'typeLike', format: ['PascalCase'], }, { selector: 'enumMember', format: ['PascalCase'], }, { selector: 'property', format: null, filter: { regex: '^(host)$', match: false, }, }, ], complexity: 'error', 'max-len': [ 'error', { code: 140, }, ], 'no-new-wrappers': 'error', 'no-throw-literal': 'error', '@typescript-eslint/consistent-type-definitions': 'error', 'no-shadow': 'off', '@typescript-eslint/no-shadow': 'error', 'no-invalid-this': 'off', '@typescript-eslint/no-invalid-this': ['warn'], '@angular-eslint/no-host-metadata-property': 'off', }, }, { files: ['**/*.html'], extends: [...angular.configs.templateRecommended, ...angular.configs.templateAccessibility], rules: {}, }, )'], ['^\\.']], }, ], 'simple-import-sort/exports': 'error', }, }, ], processor: angular.processInlineTemplates, rules: { '@angular-eslint/directive-selector': [ 'error', { type: 'attribute', prefix: 'baf', style: 'camelCase', }, ], '@angular-eslint/component-selector': [ 'error', { type: 'element', prefix: 'baf', style: 'kebab-case', }, ], '@typescript-eslint/naming-convention': [ 'error', { selector: 'default', format: ['camelCase'], leadingUnderscore: 'allow', trailingUnderscore: 'allow', filter: { regex: '^(ts-jest|\\^.*)$', match: false, }, }, { selector: 'default', format: ['camelCase'], leadingUnderscore: 'allow', trailingUnderscore: 'allow', }, { selector: 'variable', format: ['camelCase', 'UPPER_CASE'], leadingUnderscore: 'allow', trailingUnderscore: 'allow', }, { selector: 'typeLike', format: ['PascalCase'], }, { selector: 'enumMember', format: ['PascalCase'], }, { selector: 'property', format: null, filter: { regex: '^(host)$', match: false, }, }, ], complexity: 'error', 'max-len': [ 'error', { code: 140, }, ], 'no-new-wrappers': 'error', 'no-throw-literal': 'error', '@typescript-eslint/consistent-type-definitions': 'error', 'no-shadow': 'off', '@typescript-eslint/no-shadow': 'error', 'no-invalid-this': 'off', '@typescript-eslint/no-invalid-this': ['warn'], '@angular-eslint/no-host-metadata-property': 'off', }, }, { files: ['**/*.html'], extends: [...angular.configs.templateRecommended, ...angular.configs.templateAccessibility], rules: {}, }, )
Change the application prefix in angular.json from app to baf.
Please note that the eslint-plugin-import plugin is not supported in eslint 9.
There is a heated discussion on github - github.com/import-js/eslint-plugin-import/issues/2948
Add prettier:
yarn add -D prettieryarn add -D prettier
Let's define the rules in .prettierrc.json:
yarn add -D prettier{ "bracketSpacing": true, "printWidth": 140, "semi": true, "singleQuote": true, "tabWidth": 2, "useTabs": false }
Exclude everything that should not be formatted in .prettierignore:
yarn add -D prettier# Add files here to ignore them from prettier formatting /dist /coverage /tmp /node_modules /nginx /.vscode /.idea package-lock.json package.json yarn.lock .angular /junit junit.xml /.nx/cache
In the IDE in the prettier settings - **/*.{js,ts,jsx,tsx,vue,astro,scss,css,html,json}.
All sources are on github, in the repository - github.com/Fafnur/buy-and-fly
The demo can be viewed here - buy-and-fly.fafn.ru/
My groups: telegram, medium, vk, x.com, linkedin, site
Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.
Copyright© 2022 湘ICP备2022001581号-3