feat(linter/node): implement no-new-require (#6165)

Co-authored-by: Don Isaac <donald.isaac@gmail.com>
This commit is contained in:
Jelle van der Waa 2024-10-16 02:06:23 +02:00 committed by GitHub
parent 9e9fa9e741
commit 8c78f9719b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 91 additions and 0 deletions

View file

@ -492,6 +492,7 @@ mod vitest {
mod node {
pub mod no_exports_assign;
pub mod no_new_require;
}
oxc_macros::declare_all_lint_rules! {
@ -738,6 +739,7 @@ oxc_macros::declare_all_lint_rules! {
nextjs::no_typos,
nextjs::no_unwanted_polyfillio,
node::no_exports_assign,
node::no_new_require,
oxc::approx_constant,
oxc::bad_array_method_on_arguments,
oxc::bad_bitwise_operator,

View file

@ -0,0 +1,73 @@
use oxc_ast::AstKind;
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
use crate::{context::LintContext, rule::Rule, AstNode};
fn no_new_require(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Unexpected use of new with require")
.with_label(span)
.with_help("Initialise the constructor separate from the import statement")
}
#[derive(Debug, Default, Clone)]
pub struct NoNewRequire;
declare_oxc_lint!(
/// ### What it does
///
/// Warn about calling `new` on `require`.
///
/// ### Why is this bad?
///
/// The `require` function is used to include modules and might return a constructor. As this
/// is not always the case this can be confusing.
///
/// ### Examples
///
/// Examples of **incorrect** code for this rule:
/// ```js
/// var appHeader = new require('app-header');
/// ```
///
/// Examples of **correct** code for this rule:
/// ```js
/// var AppHeader = require('app-header');
/// var appHeader = new AppHeader();
/// ```
NoNewRequire,
restriction);
impl Rule for NoNewRequire {
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
let AstKind::NewExpression(new_expression) = node.kind() else {
return;
};
if !new_expression.callee.is_specific_id("require") {
return;
};
ctx.diagnostic(no_new_require(new_expression.span));
}
}
#[test]
fn test() {
use crate::tester::Tester;
let pass = vec![
"var appHeader = require('app-header')",
"var AppHeader = new (require('app-header'))",
"var AppHeader = new (require('headers').appHeader)",
"var AppHeader = require('app-header'); var appHeader = new AppHeader();",
];
let fail = vec![
"var appHeader = new require('app-header')",
"var appHeader = new require('headers').appHeader",
];
Tester::new(NoNewRequire::NAME, pass, fail).test_and_snapshot();
}

View file

@ -0,0 +1,16 @@
---
source: crates/oxc_linter/src/tester.rs
---
⚠ eslint-plugin-node(no-new-require): Unexpected use of new with require
╭─[no_new_require.tsx:1:17]
1 │ var appHeader = new require('app-header')
· ─────────────────────────
╰────
help: Initialise the constructor separate from the import statement
⚠ eslint-plugin-node(no-new-require): Unexpected use of new with require
╭─[no_new_require.tsx:1:17]
1 │ var appHeader = new require('headers').appHeader
· ──────────────────────
╰────
help: Initialise the constructor separate from the import statement