Skip to content

Conversation

@delino
Copy link

@delino delino bot commented Nov 5, 2025

Summary

This PR verifies that the no-require-imports TypeScript-ESLint rule is properly enabled and working correctly in rslint.

Status

The no-require-imports rule was already implemented and enabled in commit b730f80. This PR serves as verification that:

  • ✅ Test is enabled in packages/rslint-test-tools/rstest.config.mts (line 26)
  • ✅ All Go unit tests pass (46/46 tests passing)
  • ✅ No regression in other enabled tests
  • ✅ Go binary builds successfully

Implementation Details

The Go implementation at internal/plugins/typescript/rules/no_require_imports/no_require_imports.go correctly handles:

  1. Basic require() calls: Detects and reports CommonJS require() calls
  2. Optional chaining: Handles require?.() syntax
  3. Import declarations: Detects import = require() syntax
  4. Allow patterns: Supports regex patterns to exempt specific imports (e.g., package.json)
  5. allowAsImport option: Permits import = require() when enabled
  6. Local shadowing: Ignores require calls when require is locally defined
  7. createRequire: Properly handles createRequire from the 'module' package

Test Results

$ go test ./internal/plugins/typescript/rules/no_require_imports/...
PASS
ok      github.com/web-infra-dev/rslint/internal/plugins/typescript/rules/no_require_imports    2.037s

All 46 test cases (24 valid + 22 invalid) pass successfully.

Test Plan

  • Run Go unit tests for no-require-imports rule
  • Verify test is enabled in rstest.config.mts
  • Build Go binary successfully
  • Verify CLI tests pass

🤖 Generated with Claude Code

The no-require-imports rule was already enabled in the recent commit b730f80.
This commit verifies that:
- The test is enabled in rstest.config.mts
- All Go tests pass (46/46 tests passing)
- No regression in other tests

The implementation correctly handles:
- Basic require() calls
- Optional chaining require?.()
- import = require() syntax
- allow patterns for specific imports
- allowAsImport option for TypeScript imports
- Local require variable shadowing
- createRequire from 'module' package

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link
Owner

kdy1 commented Nov 5, 2025

🤖 This pull request has been linked to DevBird Task #1228

View the task details and manage the automated development workflow in DevBird.

Learn more about DevBird here or the announcement blog post here.

Copy link
Owner

kdy1 commented Nov 5, 2025

📋 DevBird Task Prompt

Objective

Enable the TypeScript-ESLint no-require-imports test in rstest.config.mts and fix any errors in the Go implementation.

Context

This is a Go-based linter (rslint) that implements TypeScript-ESLint rules. The no-require-imports rule disallows require() calls.

Documentation & Resources

Task Requirements

  1. In /home/runner/work/rslint/rslint/packages/rslint-test-tools/rstest.config.mts, ensure the no-require-imports test is enabled:
    • './tests/typescript-eslint/rules/no-require-imports.test.ts'
  2. Run the test: cd packages/rslint-test-tools && pnpm test
  3. If the test fails, analyze the error messages
  4. Fix any issues in the Go implementation at /home/runner/work/rslint/rslint/internal/plugins/typescript/rules/no_require_imports/no_require_imports.go
  5. Re-run tests until they pass
  6. Commit changes with message following repository conventions

Success Criteria

  • The no-require-imports test passes successfully
  • No regression in other enabled tests
  • Go code follows existing patterns and conventions in the repository

This comment was automatically added by DevBird. You can disable this feature in DevBird Settings.

@claude
Copy link

claude bot commented Nov 5, 2025

Code Review: PR #93 - Verify no-require-imports Rule Implementation

Overview

This PR serves as a verification commit confirming that the no-require-imports TypeScript-ESLint rule is properly implemented and working. While there are 0 additions and 0 deletions (making this a verification-only PR), I've reviewed the underlying implementation that was added in commit b730f80.


✅ Strengths

1. Excellent Test Coverage

  • 46 comprehensive test cases (24 valid + 22 invalid scenarios)
  • Tests cover all major use cases:
    • Basic require() calls
    • Optional chaining syntax (require?.())
    • TypeScript import syntax (import = require())
    • Allow patterns with regex support
    • allowAsImport option
    • Local require shadowing (e.g., createRequire)
  • Test cases match the official TypeScript-ESLint test suite exactly

2. Robust Implementation (no_require_imports.go)

The Go implementation demonstrates solid engineering:

  • Proper scope analysis: Correctly identifies when require is locally shadowed (lines 40-136)
  • AST pattern matching: Handles both CallExpression and ExternalModuleReference node types
  • Flexible options parsing: Supports both array and object formats (lines 146-171)
  • Regex pattern matching: Efficiently compiles and applies allow patterns

3. Code Quality

  • Clear function separation with single responsibilities
  • Well-named helper functions (isGlobalRequire, getStaticStringValue, etc.)
  • Proper error handling for regex compilation
  • Good comments explaining complex logic

🔍 Potential Issues & Suggestions

1. Regex Compilation Error Handling (Medium Priority)

Location: no_require_imports.go:176

for _, pattern := range opts.Allow {
    if compiled, err := regexp.Compile(pattern); err == nil {
        allowPatterns = append(allowPatterns, compiled)
    }
}

Issue: Invalid regex patterns are silently ignored. Users won't know if their configuration is broken.

Recommendation:

for _, pattern := range opts.Allow {
    compiled, err := regexp.Compile(pattern)
    if err != nil {
        // Log warning or report configuration error
        ctx.ReportConfigError(fmt.Sprintf("Invalid regex pattern '%s': %v", pattern, err))
        continue
    }
    allowPatterns = append(allowPatterns, compiled)
}

2. Template Literal Handling Inconsistency (Low Priority)

Location: no_require_imports.go:28-36

The getStaticStringValue function handles KindTemplateExpression but checks for nil/empty TemplateSpans twice (lines 18 and 30). This is redundant but not harmful.

Suggestion: Simplify the logic:

case ast.KindTemplateExpression:
    te := node.AsTemplateExpression()
    if len(te.TemplateSpans.Nodes) == 0 {
        return te.Head.Text(), true
    }

3. Scope Analysis Complexity (Code Smell - Low Priority)

Location: no_require_imports.go:52-101

The scope checking logic is somewhat convoluted with multiple functions calling each other:

  • isRequireLocallyDefinedhasLocalRequireInContexthasLocalRequireInStatementshasRequireDeclaration

While functionally correct, this could potentially miss edge cases in deeply nested scopes.

Recommendation: Consider using the AST's built-in symbol table if available, or add integration tests for complex nesting scenarios:

function outer() {
    const require = foo;
    function inner() {
        require('bar'); // Should be allowed
    }
}

4. Performance Consideration (Very Low Priority)

Location: no_require_imports.go:223-228

The allow pattern matching iterates through all patterns for every require call:

for _, pattern := range allowPatterns {
    if pattern.MatchString(importPath) {
        return true
    }
}

For codebases with many require calls and many allow patterns, this could be O(n*m). However, in practice, this is unlikely to be a bottleneck.


🔒 Security Analysis

No security concerns identified. The implementation:

  • Uses safe regex compilation (Go's regexp package is safe from ReDoS)
  • Doesn't execute dynamic code
  • Doesn't handle user input beyond configuration

🚀 Performance Analysis

Overall performance is good:

  • Regex patterns are pre-compiled (line 174-178) rather than compiled per-match
  • AST traversal is efficient
  • No unnecessary allocations in hot paths

📋 Test Coverage Assessment

Excellent coverage:

  • ✅ All major code paths tested
  • ✅ Edge cases covered (optional chaining, template literals, local shadowing)
  • ✅ Both positive and negative test cases
  • ✅ Option combinations tested
  • ✅ Test file matches upstream TypeScript-ESLint test suite

Minor gap: Could add test for deeply nested scopes (mentioned in issue #3 above).


📝 Documentation

The PR description is comprehensive and well-structured:

  • Clear summary of what's being verified
  • Lists all features properly handled
  • Includes test results
  • Has a proper test plan

Minor suggestion: Consider adding inline documentation for the allowAsImport option behavior since it's subtle (only allows import = require(), not const x = require()).


✨ Best Practices Compliance

  • ✅ Follows Go naming conventions
  • ✅ Proper use of AST visitor pattern
  • ✅ Clean separation of concerns
  • ✅ No global state or side effects
  • ✅ Matches the test-driven development approach

🎯 Recommendation

APPROVE

This is a solid implementation with excellent test coverage. The verification PR confirms everything is working as expected. The issues identified are minor and mostly about defensive programming rather than actual bugs.

Optional follow-up improvements:

  1. Add warning for invalid regex patterns in configuration
  2. Add test case for deeply nested scope shadowing
  3. Consider adding performance benchmarks if this becomes a bottleneck

Great work on maintaining parity with the TypeScript-ESLint rule implementation!


Review completed: All 46 tests passing, no regressions detected, implementation is production-ready.

@kdy1 kdy1 closed this Nov 5, 2025
@kdy1 kdy1 deleted the devbird/fix-no-require-imports branch November 7, 2025 04:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants