Receber por email
← Voltar para o catálogo

standards-javascript

This skill provides JavaScript coding standards and is automatically loaded for JavaScript projects. It includes modern ES2025 patterns, async handling, and recommended tooling.

55estrelas
Atualizado há 5 meses

Ver no GitHub ↗ Licença: MIT

Como adicionar

/plugin marketplace add b33eep/claude-code-setup

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/standards-javascript/svg)](https://www.skillteca.com.br/skills/standards-javascript)

Skills relacionadas

Ver todas de Desenvolvimento →

Alerta por categoria

Receba novas skills de Desenvolvimento toda segunda

1 email curto, só com as skills novas de Desenvolvimento. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

JavaScript Coding Standards

Core Principles

  1. Simplicity: Simple, understandable code
  2. Readability: Readability over cleverness
  3. Maintainability: Code that's easy to maintain
  4. Testability: Code that's easy to test
  5. DRY: Don't Repeat Yourself - but don't overdo it

General Rules

  • Early Returns: Use early returns to avoid nesting
  • Descriptive Names: Meaningful names for variables and functions
  • Minimal Changes: Only change relevant code parts
  • No Over-Engineering: No unnecessary complexity
  • Minimal Comments: Code should be self-explanatory. No redundant comments!
  • Async/Await: Always use async/await for async operations

Naming Conventions

| Element | Convention | Example | |---------|------------|---------| | Variables/Functions | camelCase | getUserById, isActive | | Classes | PascalCase | UserService, ApiClient | | Constants | UPPER_SNAKE_CASE | MAX_RETRY_COUNT | | Private | Prefix with _ or # | _internalMethod, #privateField | | Files | kebab-case or camelCase | user-service.js, userService.js | | Event Handlers | Prefix with handle | handleClick, handleSubmit |

Project Structure

myproject/
├── src/
│   ├── index.js              # Entry point
│   ├── config.js             # Settings, env vars
│   ├── models/
│   │   └── user.js           # Domain models
│   ├── services/
│   │   └── user-service.js   # Business logic
│   ├── routes/
│   │   └── user-routes.js    # API routes
│   └── utils/
│       └── helpers.js        # Utility functions
├── tests/
│   ├── services/
│   │   └── user-service.test.js
│   └── setup.js
├── package.json
└── README.md

ES Modules (Preferred)

// math.js - Named exports
export function add(a, b) {
    return a + b;
}

export function multiply(a, b) {
    return a * b;
}

// app.js - Import
import { add, multiply } from './math.js';

// Default export
export default class UserService {
    // ...
}

// Import default
import UserService from './user-service.js';

package.json for ES Modules:

{
    "type": "module",
    "exports": {
        ".": "./src/index.js",
        "./utils": "./src/utils/index.js"
    }
}

Async/Await Patterns

// Always use async/await for async operations
async function fetchUserData(userId) {
    try {
        const response = await fetch(`https://api.example.com/users/${userId}`);

        if (!response.ok) {
            throw new Error(`API error: ${response.statusText}`);
        }

        return await response.json();
    } catch (error) {
        console.error('Fetch failed:', error);
        throw error;
    }
}

// Parallel execution with Promise.all
async function fetchMultipleUsers(userIds) {
    const users = await Promise.all(
        userIds.map(id => fetchUserData(id))
    );
    return users;
}

// Race with timeout
async function fetchWithTimeout(promise, timeout) {
    return Promise.race([
        promise,
        new Promise((_, reject) =>
            setTimeout(() => reject(new Error('Timeout')), timeout)
        ),
    ]);
}

// Get all results, including failures
async function fetchAllSettled(urls) {
    const results = await Promise.allSettled(
        urls.map(url => fetch(url).then(r => r.json()))
    );
    return results;
}

Best Practices

// Prefer const over let
const users = [];

// Use nullish coalescing and optional chaining
const name = user?.profile?.name ?? 'Anonymous';

// Prefer template literals
const message = `Hello, ${user.name}!`;

// Use destructuring
const { id, name, email } = user;
function processUser({ id, name }) { }

// Prefer array methods over loops
const activeUsers = users.filter(u => u.isActive);
const userNames = users.map(u => u.name);
const totalAge = users.reduce((sum, u) => sum + u.age, 0);

// Use Object.freeze for immutable constants
const CONFIG = Object.freeze({
    apiUrl: 'https://api.example.com',
    maxRetries: 3,
});

// Private class fields with #
class UserService {
    #apiClient;

    constructor(apiClient) {
        this.#apiClient = apiClient;
    }

    async getUser(id) {
        return this.#apiClient.get(`/users/${id}`);
    }
}

Express Framework

import express from 'express';

const app = express();
app.use(express.json());

// Routes
app.get('/users', (req, res) => {
    res.json([
        { id: 1, name: 'John' },
        { id: 2, name: 'Jane' },
    ]);
});

app.post('/users', (req, res) => {
    const { name } = req.body;
    res.status(201).json({ id: 3, name });
});

app.get('/users/:id', (req, res) => {
    const { id } = req.params;
    res.json({ id: parseInt(id), name: 'User' });
});

// Error handling middleware (must be last)
app.use((err, req, res, next) => {
    console.error(err.stack);
    res.status(500).json({ error: 'Internal Server Error' });
});

app.listen(3000, () => {
    console.log('Server running on :3000');
});

Middleware Pattern:

// Logging middleware
const logger = (req, res, next) => {
    console.log(`${req.method} ${req.path}`);
    next();
};

// Authentication middleware
const authenticateToken = (req, res, next) => {
    const authHeader = req.headers['authorization'];
    const token = authHeader?.split(' ')[1];

    if (!token) {
        return res.status(401).json({ error: 'Missing token' });
    }

    // Verify token...
    req.user = decodedUser;
    next();
};

app.use(logger);
app.use('/api/protected', authenticateToken);

Fastify Framework

import Fastify from 'fastify';

const fastify = Fastify({ logger: true });

fastify.get('/users/:id', async (request, reply) => {
    const { id } = request.params;
    return { id: parseInt(id), name: 'User' };
});

fastify.post('/users', async (request, reply) => {
    const { name } = request.body;
    reply.code(201);
    return { id: 1, name };
});

fastify.listen({ port: 3000 }, (err, address) => {
    if (err) throw err;
    console.log(`Server listening at ${address}`);
});

Error Handling

// Custom error classes
class AppError extends Error {
    constructor(message, statusCode = 500) {
        super(message);
        this.name = 'AppError';
        this.statusCode = statusCode;
    }
}

class NotFoundError extends AppError {
    constructor(resource) {
        super(`${resource} not found`, 404);
        this.name = 'NotFoundError';
    }
}

// Result pattern for explicit error handling
function divide(a, b) {
    if (b === 0) {
        return { ok: false, error: 'Division by zero' };
    }
    return { ok: true, value: a / b };
}

const result = divide(10, 2);
if (result.ok) {
    console.log(result.value);
} else {
    console.error(result.error);
}

Testing with Vitest

import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { add, multiply } from './math.js';

describe('Math utils', () => {
    it('should add numbers', () => {
        expect(add(2, 3)).toBe(5);
    });

    it('should multiply numbers', () => {
        expect(multiply(2, 3)).toBe(6);
    });
});

// Integration test example
describe('API Endpoints', () => {
    let server;

    beforeEach(() => {
        server = createServer();
    });

    afterEach(() => {
        server.close();
    });

    it('GET /users returns user list', async () => {
        const response = await fetch('http://localhost:3000/users');
        const data = await response.json();

        expect(response.ok).toBe(true);
        expect(Array.isArray(data)).toBe(true);
    });
});

Environment Configuration

// config.js
const config = {
    development: {
        port: 3000,
        database: 'mongodb://localhost:27017/mydb',
        logLevel: 'debug',
    },
    production: {
        port: process.env.PORT || 8080,
        database: process.env.DATABASE_URL,
        logLevel: 'info',
    },
};

const env = process.env.NODE_ENV || 'development';
Compartilhar X LinkedIn