Node.js Best Practices

repository·master·Indexed 13 days ago

https://github.com/goldbergyoni/nodebestpractices

A community-driven collection of Node.js best practices, architectural patterns, and coding styles. Covers topics including static analysis, project layering, error management, dependency locking, and the use of tools like ESLint, Prettier, PM2, and Istanbul/NYC to build professional-grade applications.

Tokens
183.8K
Snippets
398
Records
1K
Agent score
97%

What's inside Node.js Best Practices

  1. Overview of Node.js Best Practices

    master

    This repository provides a comprehensive collection of best practices for developing production-ready Node.js applications. The guidance is organized into several key domains:

    • Project Architecture: Structuring solutions by business components, layering components, and managing configuration.
    • Error Handling: Managing asynchronous errors, extending error objects, and implementing graceful shutdowns.
    • Code Patterns and Style: Using ESLint, naming conventions, and modern JavaScript syntax (Async/Await, Arrow functions).
    • Testing and Quality: API testing, the AAA pattern, test coverage, and mocking external services.
    • Production Readiness: Monitoring, logging, deployment strategies, and environment management.
    • Security: Protecting against injection, managing secrets, validating schemas, and securing dependencies.
    • Performance: Avoiding event loop blocking and preferring native methods.
    • Docker: Multi-stage builds, image security, and efficient caching.
  2. Overview of Node.js Best Practices

    master

    This repository is a comprehensive, community-driven collection of Node.js best practices, architectural recommendations, and coding style guidelines. It currently contains over 100 items designed to help developers write high-quality Node.js applications.

    Key features include:

    • Categorized Content: Items are organized using tags such as #strategic (for high-level architecture), #new (for recent updates), and #advanced (for senior developers).
    • Deep Dives: Most best practices include a 🔗לקריאה נוספת (Read More) link that provides expanded information, including code examples, blog citations, and further technical details.
    • Community Driven: The collection is updated weekly through community contributions, including code fixes, translations, and new ideas.
  3. What is the AAA pattern in testing?

    master

    The AAA pattern (Arrange, Act, Assert) is a structural convention used to organize test cases. It aims to make tests declarative rather than imperative, ensuring that the reader can immediately distinguish between the setup (fixture), the execution of the system under test (SUT), and the verification of the results.

    It is conceptually similar to the XUnit 'Setup, Exercise, Verify, Teardown' pattern.

  4. Use secure and hierarchical environment-aware configuration

    master

    A robust configuration system should meet three criteria:

    1. Hybrid Loading: Read keys from both configuration files and environment variables.
    2. Secret Management: Store sensitive secrets outside of the main codebase.
    3. Hierarchy: Use a hierarchical structure to make configuration easy to navigate.

    Recommended npm packages to implement these patterns include:

    • rc
    • nconf
    • config
    • convict
  5. Choose a CI platform for your Node.js project

    master

    When selecting a Continuous Integration (CI) platform, the decision typically depends on the required level of customization versus ease of setup:

    • SaaS Solutions (e.g., CircleCI, Travis CI): Best for teams wanting minimal setup time. They offer powerful solutions using Docker containers with very little configuration required. They support running custom shell commands, custom Docker images, workflow adjustments, and matrix builds.
    • Jenkins: Best if you need deep control over infrastructure or if you prefer using a formal programming language (like Java) to control infrastructure and CI logic. It is highly extensible and powerful but requires more management than SaaS options.
  6. Avoid routing logs within the application

    master
    Do not implement log routing logic inside your application code. Instead, write logs to stdout using a logger utility and let the execution environment (e.g., Docker containers, Kubernetes, or server managers) handle the routing to destinations like Splunk, Graylog, or ElasticSearch. This maintains a clean separation of concerns.
  7. Choose an Integration Engine (IE) platform

    master

    When selecting an Integration Engine (IE) platform for your Node.js project, the choice typically falls between the flexibility of self-hosted solutions like Jenkins and the simplicity of SaaS providers like CircleCI or Travis CI.

    Decision Criteria

    • SaaS Providers (e.g., CircleCI, Travis CI): Best for minimal configuration time. They offer robust solutions including Docker container support and are ideal if you want a simpler, managed experience.
    • Jenkins: Best when you need high levels of control and customization. Choose Jenkins if you need to program the IE logic using a formal programming language like Java or if you need to manage a highly detailed, custom-tailored pipeline.

    In summary, choose a cloud-based SaaS solution for simplicity, or Jenkins if you require deep control over the underlying infrastructure and complex workflow logic.

  8. Difference between uncaughtException and unhandledRejection

    master

    It is critical to understand that uncaughtException and unhandledRejection handle different types of errors:

    1. uncaughtException: Catches synchronous errors thrown in the main execution thread that were not wrapped in a try/catch block.
    2. unhandledRejection: Catches errors occurring inside Promises that do not have a .catch() handler attached to the chain.

    Because uncaughtException does not catch promise rejections, you must implement both to ensure full coverage of error scenarios.

  9. Logger Requirements

    master

    A production-ready logger should meet these three requirements:

    1. Timestamp each log line: Every entry must include a timestamp to identify when the event occurred.
    2. Digestible format: The logging format should be easily readable by both humans and machines (e.g., JSON).
    3. Multiple configurable destination streams: The logger should support multiple transports. For example, you might write all logs to one file, but trigger an additional write to an error file and send an email simultaneously when an error occurs.
  10. Understand dependency lockfile formats

    master

    Lockfiles represent the exact dependency tree, including nested dependencies.

    • npm-shrinkwrap.json: An older or specific way to extract the exact dependency tree. It is useful for publishing packages where you want to ensure consumers get the exact same sub-dependencies.
    • package-lock.json: The standard lockfile used by npm 5 and above. It includes version numbers, resolution URLs, and integrity hashes to ensure the downloaded package is authentic and unchanged.
    // Example of a package-lock.json structure
    {
        "name": "package-name",
        "version": "1.0.0",
        "lockfileVersion": 1,
        "dependencies": {
            "cacache": {
                "version": "9.2.6",
                "resolved": "https://registry.npmjs.org/cacache/-/cacache-9.2.6.tgz",
                "integrity": "sha512-YK0Z5Np5t755edPL6gfdCeGxtU0rcW/DBhYhYVDckT+7AFkCCtedf2zru5NRbBLFk6e7Agi/RaqTOAfiaipUfg=="
            }
        }
    }
  11. Configure X-XSS-Protection

    master

    This header enables the Cross-site scripting (XSS) filter built into most modern web browsers.

    Supported values:

    • 0: Disables the XSS filter.
    • 1: Enables the XSS filter and allows automatic page cleansing.
    • 1; mode=block: Enables the XSS filter and prevents the page from rendering if an attack is detected.
    • 1; report=<domainToReport>: Enables the filter and sends reports of violations to the specified domain.
    X-XSS-Protection: 1; report=http://example.com/xss-report
  12. Separate Express 'application' from 'server'

    master
    Do not define your entire Express application in a single large file. Separate the API definition (e.g., app.js) from the network configuration (the server). A better structure places the API definition alongside its components. This allows you to test the API via internal calls rather than relying solely on HTTP requests, which makes testing faster and more reliable.