with one click
alias-nested-modules
// Define module aliases at the top of the file instead of using fully qualified nested module names in function bodies. Improves code readability and maintainability while addressing Credo style warnings.
// Define module aliases at the top of the file instead of using fully qualified nested module names in function bodies. Improves code readability and maintainability while addressing Credo style warnings.
Create, adjust, or inspect OpenAPI declarations for Blockscout API v2 endpoints. Use this skill whenever the user asks to: add an OpenAPI spec to an endpoint that lacks one, update a spec after controller/view changes, audit or fix an existing OpenAPI declaration, or work with open_api_spex annotations in the Blockscout codebase. Also trigger when the user mentions 'swagger', 'openapi', 'open_api_spex', 'API spec', 'API schema', or 'operation macro', or when debugging failures like 'response schema mismatch', 'CastAndValidate rejection', 'json_response validation error', 'Unexpected field', or extra/missing keys in API responses.
Use when refactoring Elixir multi-clause functions, extracting helper functions, or fixing Credo readability warnings caused by placing `defp` helpers between clauses of the same function. Keeps function clauses contiguous and moves helpers below the full clause group.
Ensure every newly introduced environment variable is also added to docker-compose/envs/common-blockscout.env so local Docker setups stay aligned with runtime configuration.
Replace `with` expressions that contain only a single `<-` clause and an `else` branch with a `case` expression. This addresses the Credo warning "with contains only one <- clause and an else branch, consider using case instead" and produces cleaner, more idiomatic Elixir code.
Use when working on Elixir code with Credo predicate naming warnings, boolean helper functions, or renaming functions that start with is_. Prevents violations like: Predicate function names should not start with 'is' and should end in a question mark.
Ensure that aliases are alphabetically ordered within their groups to maintain consistent code style and address Credo readability warnings.
| name | alias-nested-modules |
| description | Define module aliases at the top of the file instead of using fully qualified nested module names in function bodies. Improves code readability and maintainability while addressing Credo style warnings. |
When using modules with long, nested names multiple times in your code, Elixir's alias directive allows you to create shorter references at the top of the module. This improves code readability, reduces duplication, and makes refactoring easier. Credo warns when nested modules are called directly in function bodies instead of being aliased.
defmodule MyApp.Service do
# ❌ BAD: No aliases, long nested module names in functions
def fetch_data do
MyApp.ExternalServices.API.Client.fetch()
end
def process_data(data) do
MyApp.ExternalServices.API.Parser.parse(data)
end
def validate_result(result) do
MyApp.ExternalServices.API.Validator.validate(result)
end
end
# ❌ BAD: Nested module call in private function
defmodule Explorer.Chain.Metrics.Queries.IndexerMetrics do
defp multichain_search_enabled? do
Explorer.MicroserviceInterfaces.MultichainSearch.enabled?()
end
end
defmodule MyApp.Service do
# ✅ GOOD: Aliases defined at module top
alias MyApp.ExternalServices.API.Client
alias MyApp.ExternalServices.API.Parser
alias MyApp.ExternalServices.API.Validator
def fetch_data do
Client.fetch()
end
def process_data(data) do
Parser.parse(data)
end
def validate_result(result) do
Validator.validate(result)
end
end
# ✅ GOOD: Module aliased at the top
defmodule Explorer.Chain.Metrics.Queries.IndexerMetrics do
alias Explorer.MicroserviceInterfaces.MultichainSearch
defp multichain_search_enabled? do
MultichainSearch.enabled?()
end
end
# ✅ Simple alias - uses last segment as the name
alias MyApp.Services.EmailService
EmailService.send()
# ✅ Group related modules
alias MyApp.Models.{User, Post, Comment}
User.find(id)
Post.create(attrs)
Comment.list_by_post(post_id)
# ✅ Use custom name to avoid conflicts or for clarity
alias MyApp.External.API.Client, as: ExternalClient
alias MyApp.Internal.API.Client, as: InternalClient
ExternalClient.request()
InternalClient.request()
# ✅ Common aliasing pattern for nested structures
alias MyApp.Services.{
Authentication,
Authorization,
Notification
}
defmodule Explorer.Chain.Metrics.Queries.IndexerMetrics do
import Ecto.Query
alias Ecto.Adapters.SQL
alias Explorer.Chain.Address.TokenBalance
alias Explorer.Repo
# No alias for MultichainSearch
defp multichain_search_enabled? do
# ⚠️ Credo warning: Nested modules could be aliased
Explorer.MicroserviceInterfaces.MultichainSearch.enabled?()
end
defp check_feature_x do
Explorer.MicroserviceInterfaces.MultichainSearch.feature_x_enabled?()
end
end
defmodule Explorer.Chain.Metrics.Queries.IndexerMetrics do
import Ecto.Query
alias Ecto.Adapters.SQL
alias Explorer.Chain.Address.TokenBalance
alias Explorer.MicroserviceInterfaces.MultichainSearch
alias Explorer.Repo
# ✅ Module aliased at top, cleaner function bodies
defp multichain_search_enabled? do
MultichainSearch.enabled?()
end
defp check_feature_x do
MultichainSearch.feature_x_enabled?()
end
end
# ✅ OK: Single use of a module - aliasing adds noise
def one_time_call do
MyApp.RarelyUsed.Module.function()
end
# ✅ OK: Very short module name
def use_map do
Map.get(data, :key)
end
# ✅ OK: Kernel or Elixir standard library
def use_enum do
Enum.map(list, &process/1)
end
Follow this conventional order for imports and aliases:
defmodule MyApp.Service do
# 1. Use statements
use GenServer
# 2. Import statements
import Ecto.Query
# 3. Alias statements (alphabetically)
alias Ecto.Adapters.SQL
alias MyApp.Models.User
alias MyApp.Services.{EmailService, SmsService}
# 4. Require statements
require Logger
end
[D] ↘ Nested modules could be aliased at the top of the invoking module.
alias directive at the top of the modulemix credo to verify the warning is resolvedCredo.Check.Readability.AliasOrder - Checks alias alphabetical orderCredo.Check.Readability.ModuleDoc - Ensures modules have documentationCredo.Check.Design.AliasUsage - Reports nested module usage