feat(linter): no irregular whitespace (#1877)

it was builded a loop that iterates in trivias.irregular-whitespace and
return the warning if contain some specific sequence of chars.

---------

Co-authored-by: Boshen <boshenc@gmail.com>
This commit is contained in:
Deivid Almeida 2024-01-04 23:47:29 -03:00 committed by GitHub
parent a63490c1c0
commit 5f29e3f9f6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 637 additions and 0 deletions

View file

@ -66,6 +66,7 @@ mod eslint {
pub mod no_global_assign;
pub mod no_import_assign;
pub mod no_inner_declarations;
pub mod no_irregular_whitespace;
pub mod no_loss_of_precision;
pub mod no_mixed_operators;
pub mod no_new_symbol;
@ -313,6 +314,7 @@ oxc_macros::declare_all_lint_rules! {
eslint::no_global_assign,
eslint::no_import_assign,
eslint::no_inner_declarations,
eslint::no_irregular_whitespace,
eslint::no_loss_of_precision,
eslint::no_mixed_operators,
eslint::no_new_symbol,

View file

@ -0,0 +1,410 @@
use oxc_diagnostics::{
miette::{self, Diagnostic},
thiserror::Error,
};
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
use crate::{context::LintContext, rule::Rule};
#[derive(Debug, Error, Diagnostic)]
#[error("eslint(no-irregular-whitespace): Unexpected irregular whitespace")]
#[diagnostic(severity(warning), help("Try to remove the irregular whitespace"))]
struct NoIrregularWhitespaceDiagnostic(#[label] pub Span);
#[derive(Debug, Default, Clone)]
pub struct NoIrregularWhitespace;
declare_oxc_lint!(
/// ### What it does
/// Disallows the use of irregular whitespaces in the code.
///
/// ### Why is this bad
/// The use of irregular whitespaces can hinder code readability and
/// create inconsistencies, making maintenance and collaboration more challenging.
///
/// ### Example
/// ```javascript
/// function invalidExample ( ) {
/// return 42;
/// }
/// ```
NoIrregularWhitespace,
correctness
);
impl Rule for NoIrregularWhitespace {
fn run_once(&self, ctx: &LintContext) {
let irregular_whitespaces = ctx.semantic().trivias().irregular_whitespaces();
for irregular_whitespace in irregular_whitespaces {
ctx.diagnostic(NoIrregularWhitespaceDiagnostic(*irregular_whitespace));
}
}
}
#[test]
fn test() {
use crate::tester::Tester;
let pass = vec![
(r"'\u000B';", None),
(r"'\u000C';", None),
(r"'\u0085';", None),
(r"'\u00A0';", None),
(r"'\u180E';", None),
(r"'\ufeff';", None),
(r"'\u2000';", None),
(r"'\u2001';", None),
(r"'\u2002';", None),
(r"'\u2003';", None),
(r"'\u2004';", None),
(r"'\u2005';", None),
(r"'\u2006';", None),
(r"'\u2007';", None),
(r"'\u2008';", None),
(r"'\u2009';", None),
(r"'\u200A';", None),
(r"'\u200B';", None),
(r"'\u2028';", None),
(r"'\u2029';", None),
(r"'\u202F';", None),
(r"'\u205f';", None),
(r"'\u3000';", None),
(r"' ';", None),
(r"' ';", None),
(r"'…';", None),
(r"' ';", None),
(r"'';", None),
(r"'';", None),
// ("' ';", None), lint error
// (r"'';", None), lint error
(r"'';", None),
(r"'';", None),
(r"'';", None),
(r"'';", None),
(r"'';", None),
(r"'';", None),
(r"'';", None),
(r"'';", None),
(r"'';", None),
// (r"'';", None), lint error
(r"'\';", None),
(r"'\';", None),
(r"'';", None),
(r"'';", None),
(r"' ';", None),
(r"// ", Some(serde_json::json!([{ "skipComments": true }]))),
(r"// ", Some(serde_json::json!([{ "skipComments": true }]))),
(r"// …", Some(serde_json::json!([{ "skipComments": true }]))),
(r"//  ", Some(serde_json::json!([{ "skipComments": true }]))),
(r"// ", Some(serde_json::json!([{ "skipComments": true }]))),
(r"// ", Some(serde_json::json!([{ "skipComments": true }]))),
// (r"//  ", Some(serde_json::json!([{ "skipComments": true }]))), lint error
// (r"// ", Some(serde_json::json!([{ "skipComments": true }]))), lint error
(r"// ", Some(serde_json::json!([{ "skipComments": true }]))),
(r"// ", Some(serde_json::json!([{ "skipComments": true }]))),
(r"// ", Some(serde_json::json!([{ "skipComments": true }]))),
(r"// ", Some(serde_json::json!([{ "skipComments": true }]))),
(r"// ", Some(serde_json::json!([{ "skipComments": true }]))),
(r"// ", Some(serde_json::json!([{ "skipComments": true }]))),
(r"// ", Some(serde_json::json!([{ "skipComments": true }]))),
(r"// ", Some(serde_json::json!([{ "skipComments": true }]))),
(r"// ", Some(serde_json::json!([{ "skipComments": true }]))),
// (r"// ", Some(serde_json::json!([{ "skipComments": true }]))), lint error
(r"// ", Some(serde_json::json!([{ "skipComments": true }]))),
(r"// ", Some(serde_json::json!([{ "skipComments": true }]))),
(r"//  ", Some(serde_json::json!([{ "skipComments": true }]))),
(r"/* */", Some(serde_json::json!([{ "skipComments": true }]))),
(r"/* */", Some(serde_json::json!([{ "skipComments": true }]))),
(r"/* … */", Some(serde_json::json!([{ "skipComments": true }]))),
(r"/*   */", Some(serde_json::json!([{ "skipComments": true }]))),
(r"/* */", Some(serde_json::json!([{ "skipComments": true }]))),
(r"/*  */", Some(serde_json::json!([{ "skipComments": true }]))),
// (r"/*   */", Some(serde_json::json!([{ "skipComments": true }]))), lint error
// (r"/* */", Some(serde_json::json!([{ "skipComments": true }]))), lint error
(r"/* */", Some(serde_json::json!([{ "skipComments": true }]))),
(r"/* */", Some(serde_json::json!([{ "skipComments": true }]))),
(r"/* */", Some(serde_json::json!([{ "skipComments": true }]))),
(r"/* */", Some(serde_json::json!([{ "skipComments": true }]))),
(r"/* */", Some(serde_json::json!([{ "skipComments": true }]))),
(r"/* */", Some(serde_json::json!([{ "skipComments": true }]))),
(r"/* */", Some(serde_json::json!([{ "skipComments": true }]))),
(r"/* */", Some(serde_json::json!([{ "skipComments": true }]))),
(r"/* */", Some(serde_json::json!([{ "skipComments": true }]))),
// (r"/* */", Some(serde_json::json!([{ "skipComments": true }]))), lint error
(r"/* */", Some(serde_json::json!([{ "skipComments": true }]))),
(r"/* */", Some(serde_json::json!([{ "skipComments": true }]))),
(r"/* */", Some(serde_json::json!([{ "skipComments": true }]))),
(r"/* */", Some(serde_json::json!([{ "skipComments": true }]))),
(r"/*   */", Some(serde_json::json!([{ "skipComments": true }]))),
(r"/ /", Some(serde_json::json!([{ "skipRegExps": true }]))),
(r"/ /", Some(serde_json::json!([{ "skipRegExps": true }]))),
(r"/…/", Some(serde_json::json!([{ "skipRegExps": true }]))),
(r"/ /", Some(serde_json::json!([{ "skipRegExps": true }]))),
(r"//", Some(serde_json::json!([{ "skipRegExps": true }]))),
(r"//", Some(serde_json::json!([{ "skipRegExps": true }]))),
// (r"/ /", Some(serde_json::json!([{ "skipRegExps": true }]))), lint error
// (r"//", Some(serde_json::json!([{ "skipRegExps": true }]))), lint error
(r"//", Some(serde_json::json!([{ "skipRegExps": true }]))),
(r"//", Some(serde_json::json!([{ "skipRegExps": true }]))),
(r"//", Some(serde_json::json!([{ "skipRegExps": true }]))),
(r"//", Some(serde_json::json!([{ "skipRegExps": true }]))),
(r"//", Some(serde_json::json!([{ "skipRegExps": true }]))),
(r"//", Some(serde_json::json!([{ "skipRegExps": true }]))),
(r"//", Some(serde_json::json!([{ "skipRegExps": true }]))),
(r"//", Some(serde_json::json!([{ "skipRegExps": true }]))),
(r"//", Some(serde_json::json!([{ "skipRegExps": true }]))),
// (r"//", Some(serde_json::json!([{ "skipRegExps": true }]))), lint error
(r"//", Some(serde_json::json!([{ "skipRegExps": true }]))),
(r"//", Some(serde_json::json!([{ "skipRegExps": true }]))),
(r"/ /", Some(serde_json::json!([{ "skipRegExps": true }]))),
(r"` `", Some(serde_json::json!([{ "skipTemplates": true }]))),
(r"` `", Some(serde_json::json!([{ "skipTemplates": true }]))),
(r"`…`", Some(serde_json::json!([{ "skipTemplates": true }]))),
(r"` `", Some(serde_json::json!([{ "skipTemplates": true }]))),
(r"``", Some(serde_json::json!([{ "skipTemplates": true }]))),
(r"``", Some(serde_json::json!([{ "skipTemplates": true }]))),
// (r"` `", Some(serde_json::json!([{ "skipTemplates": true }]))), lint error
// (r"``", Some(serde_json::json!([{ "skipTemplates": true }]))), lint error
(r"``", Some(serde_json::json!([{ "skipTemplates": true }]))),
(r"``", Some(serde_json::json!([{ "skipTemplates": true }]))),
(r"``", Some(serde_json::json!([{ "skipTemplates": true }]))),
(r"``", Some(serde_json::json!([{ "skipTemplates": true }]))),
(r"``", Some(serde_json::json!([{ "skipTemplates": true }]))),
(r"``", Some(serde_json::json!([{ "skipTemplates": true }]))),
(r"``", Some(serde_json::json!([{ "skipTemplates": true }]))),
(r"``", Some(serde_json::json!([{ "skipTemplates": true }]))),
(r"``", Some(serde_json::json!([{ "skipTemplates": true }]))),
// (r"``", Some(serde_json::json!([{ "skipTemplates": true }]))), lint error
(r"``", Some(serde_json::json!([{ "skipTemplates": true }]))),
(r"``", Some(serde_json::json!([{ "skipTemplates": true }]))),
(r"` `", Some(serde_json::json!([{ "skipTemplates": true }]))),
(r"` ${foo} `", Some(serde_json::json!([{ "skipTemplates": true }]))),
(r"const error = `   `;", Some(serde_json::json!([{ "skipTemplates": true }]))),
(
r"const error = `
 `;",
Some(serde_json::json!([{ "skipTemplates": true }])),
),
(
r"const error = ` 
`;",
Some(serde_json::json!([{ "skipTemplates": true }])),
),
(
r"const error = `
 
`;",
Some(serde_json::json!([{ "skipTemplates": true }])),
),
(
r"const error = `foo bar
foo bar`;",
Some(serde_json::json!([{ "skipTemplates": true }])),
),
(r"<div> </div>;", Some(serde_json::json!([{ "skipJSXText": true }]))),
(r"<div> </div>;", Some(serde_json::json!([{ "skipJSXText": true }]))),
(r"<div>…</div>;", Some(serde_json::json!([{ "skipJSXText": true }]))),
(r"<div> </div>;", Some(serde_json::json!([{ "skipJSXText": true }]))),
(r"<div></div>;", Some(serde_json::json!([{ "skipJSXText": true }]))),
(r"<div></div>;", Some(serde_json::json!([{ "skipJSXText": true }]))),
// (r"<div> </div>;", Some(serde_json::json!([{ "skipJSXText": true }]))), lint error
// (r"<div></div>;", Some(serde_json::json!([{ "skipJSXText": true }]))), lint error
(r"<div></div>;", Some(serde_json::json!([{ "skipJSXText": true }]))),
(r"<div></div>;", Some(serde_json::json!([{ "skipJSXText": true }]))),
(r"<div></div>;", Some(serde_json::json!([{ "skipJSXText": true }]))),
(r"<div></div>;", Some(serde_json::json!([{ "skipJSXText": true }]))),
(r"<div></div>;", Some(serde_json::json!([{ "skipJSXText": true }]))),
(r"<div></div>;", Some(serde_json::json!([{ "skipJSXText": true }]))),
(r"<div></div>;", Some(serde_json::json!([{ "skipJSXText": true }]))),
(r"<div></div>;", Some(serde_json::json!([{ "skipJSXText": true }]))),
(r"<div></div>;", Some(serde_json::json!([{ "skipJSXText": true }]))),
// (r"<div></div>;", Some(serde_json::json!([{ "skipJSXText": true }]))), lint error
(r"<div></div>;", Some(serde_json::json!([{ "skipJSXText": true }]))),
(r"<div></div>;", Some(serde_json::json!([{ "skipJSXText": true }]))),
(r"<div> </div>;", Some(serde_json::json!([{ "skipJSXText": true }]))),
// (r"console.log('hello BOM');", None),
];
let fail = vec![
// (r"var any = 'thing';", None),
// (r"var any = 'thing';", None),
(r"var any   = 'thing';", None),
(r"var any  = 'thing';", None),
// (r"var any   = 'thing';", None),
// (r"var any = 'thing';", None),
(r"var any = 'thing';", None),
(r"var any = 'thing';", None),
(r"var any = 'thing';", None),
(r"var any = 'thing';", None),
(r"var any = 'thing';", None),
(r"var any = 'thing';", None),
(r"var any = 'thing';", None),
(r"var any = 'thing';", None),
(r"var any = 'thing';", None),
// (r"var any = 'thing';", None),
// (r"var any = 'thing';", None),
(r"var any = 'thing';", None),
(r"var any = 'thing';", None),
(r"var any   = 'thing';", None),
// (
// r"var a = 'b',c = 'd',
// e = 'f'",
// None,
// ),
(
r"var any   = 'thing', other   = 'thing';
var third   = 'thing';",
None,
),
// (r"// ", None),
// (r"// ", None),
// (r"// …", None),
// (r"//  ", None),
// (r"// ", None),
// (r"// ", None),
// (r"//  ", None),
// (r"// ", None),
// (r"// ", None),
// (r"// ", None),
// (r"// ", None),
// (r"// ", None),
// (r"// ", None),
// (r"// ", None),
// (r"// ", None),
// (r"// ", None),
// (r"// ", None),
// (r"// ", None),
// (r"// ", None),
// (r"// ", None),
// (r"//  ", None),
// (r"/* */", None),
// (r"/* */", None),
// (r"/* … */", None),
// (r"/*   */", None),
// (r"/* */", None),
// (r"/*  */", None),
// (r"/*   */", None),
// (r"/* */", None),
// (r"/* */", None),
// (r"/* */", None),
// (r"/* */", None),
// (r"/* */", None),
// (r"/* */", None),
// (r"/* */", None),
// (r"/* */", None),
// (r"/* */", None),
// (r"/* */", None),
// (r"/* */", None),
// (r"/* */", None),
// (r"/* */", None),
// (r"/* */", None),
// (r"/* */", None),
// (r"/*   */", None),
// (r"var any = / /, other = / /;", None),
// (r"var any = ' ', other = ' ';", Some(serde_json::json!([{ "skipStrings": false }]))),
// (r"var any = ` `, other = ` `;", Some(serde_json::json!([{ "skipTemplates": false }]))),
(
r"`something ${  10} another thing`",
Some(serde_json::json!([{ "skipTemplates": true }])),
),
(
r"`something ${10 } another thing`",
Some(serde_json::json!([{ "skipTemplates": true }])),
),
(
r" 
` template`",
Some(serde_json::json!([{ "skipTemplates": true }])),
),
(
r" 
` multiline
template`",
Some(serde_json::json!([{ "skipTemplates": true }])),
),
(r" ` template`", Some(serde_json::json!([{ "skipTemplates": true }]))),
(
r" ` multiline
template`",
Some(serde_json::json!([{ "skipTemplates": true }])),
),
(r"` template` ", Some(serde_json::json!([{ "skipTemplates": true }]))),
(
r"` multiline
template` ",
Some(serde_json::json!([{ "skipTemplates": true }])),
),
(
r"` template`
 ",
Some(serde_json::json!([{ "skipTemplates": true }])),
),
(
r"` multiline
template`
 ",
Some(serde_json::json!([{ "skipTemplates": true }])),
),
// (r"var foo = bar;", None),
// (r"var foo = bar;", None),
// (r"var foo = bar;", None),
// (r"var foo = bar;", None),
// (r"var foo = bar;", None),
// (r"var foo = bar ;", None),
// (r" ", None),
(" ", None),
// (
// r"var foo =
// bar;",
// None,
// ),
// (
// r"var foo =
// bar;",
// None,
// ),
// (
// r"var foo =
// bar
// ;
// ",
// None,
// ),
// (r"var foo = bar;", None),
// (r"var foo = bar;", None),
// (r"var foo = bar;", None),
// (r"", None),
// (r"foo", None),
// (r"foo", None),
// (
// r"foo
// ",
// None,
// ),
// (r"foo ", None),
// (r"<div> </div>;", None),
// (r"<div> </div>;", None),
// (r"<div>…</div>;", None),
// (r"<div> </div>;", None),
// (r"<div></div>;", None),
// (r"<div></div>;", None),
// (r"<div> </div>;", None),
// (r"<div></div>;", None),
// (r"<div></div>;", None),
// (r"<div></div>;", None),
// (r"<div></div>;", None),
// (r"<div></div>;", None),
// (r"<div></div>;", None),
// (r"<div></div>;", None),
// (r"<div></div>;", None),
// (r"<div></div>;", None),
// (r"<div></div>;", None),
// (r"<div></div>;", None),
// (r"<div></div>;", None),
// (r"<div></div>;", None),
// (r"<div> </div>;", None),
];
Tester::new(NoIrregularWhitespace::NAME, pass, fail).test_and_snapshot();
}

View file

@ -0,0 +1,225 @@
---
source: crates/oxc_linter/src/tester.rs
assertion_line: 144
expression: no_irregular_whitespace
---
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:1:1]
1 │ var any   = 'thing';
· ▲
╰────
help: Try to remove the irregular whitespace
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:1:1]
1 │ var any  = 'thing';
· ▲
╰────
help: Try to remove the irregular whitespace
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:1:1]
1 │ var any = 'thing';
· ▲
╰────
help: Try to remove the irregular whitespace
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:1:1]
1 │ var any = 'thing';
· ▲
╰────
help: Try to remove the irregular whitespace
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:1:1]
1 │ var any = 'thing';
· ▲
╰────
help: Try to remove the irregular whitespace
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:1:1]
1 │ var any = 'thing';
· ▲
╰────
help: Try to remove the irregular whitespace
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:1:1]
1 │ var any = 'thing';
· ▲
╰────
help: Try to remove the irregular whitespace
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:1:1]
1 │ var any = 'thing';
· ▲
╰────
help: Try to remove the irregular whitespace
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:1:1]
1 │ var any = 'thing';
· ▲
╰────
help: Try to remove the irregular whitespace
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:1:1]
1 │ var any = 'thing';
· ▲
╰────
help: Try to remove the irregular whitespace
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:1:1]
1 │ var any = 'thing';
· ▲
╰────
help: Try to remove the irregular whitespace
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:1:1]
1 │ var any = 'thing';
· ▲
╰────
help: Try to remove the irregular whitespace
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:1:1]
1 │ var any = 'thing';
· ▲
╰────
help: Try to remove the irregular whitespace
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:1:1]
1 │ var any   = 'thing';
· ▲
╰────
help: Try to remove the irregular whitespace
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:1:1]
1 │ var any   = 'thing', other   = 'thing';
· ▲
2 │ var third   = 'thing';
╰────
help: Try to remove the irregular whitespace
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:1:1]
1 │ var any   = 'thing', other   = 'thing';
· ▲
2 │ var third   = 'thing';
╰────
help: Try to remove the irregular whitespace
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:1:1]
1 │ var any   = 'thing', other   = 'thing';
2 │ var third   = 'thing';
· ▲
╰────
help: Try to remove the irregular whitespace
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:1:1]
1 │ `something ${  10} another thing`
· ▲
╰────
help: Try to remove the irregular whitespace
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:1:1]
1 │ `something ${10 } another thing`
· ▲
╰────
help: Try to remove the irregular whitespace
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:1:1]
1 │  
· ▲
2 │ ` template`
╰────
help: Try to remove the irregular whitespace
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:1:1]
1 │  
· ▲
2 │ ` multiline
╰────
help: Try to remove the irregular whitespace
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:1:1]
1 │  ` template`
· ▲
╰────
help: Try to remove the irregular whitespace
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:1:1]
1 │  ` multiline
· ▲
2 │ template`
╰────
help: Try to remove the irregular whitespace
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:1:1]
1 │ ` template` 
· ▲
╰────
help: Try to remove the irregular whitespace
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:1:1]
1 │ ` multiline
2 │ template` 
· ▲
╰────
help: Try to remove the irregular whitespace
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:1:1]
1 │ ` template`
2 │  
· ▲
╰────
help: Try to remove the irregular whitespace
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:2:1]
2 │ template`
3 │  
· ▲
╰────
help: Try to remove the irregular whitespace
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:1:1]
1 │  
· ▲
╰────
help: Try to remove the irregular whitespace
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:1:1]
1 │  
· ▲
╰────
help: Try to remove the irregular whitespace
⚠ eslint(no-irregular-whitespace): Unexpected irregular whitespace
╭─[no_irregular_whitespace.tsx:1:1]
1 │  
· ▲
╰────
help: Try to remove the irregular whitespace