This repository serves as a personal compendium of coding best practices, architectural guidelines, and valuable development remarks. It documents lessons learned and preferred approaches gathered across various programming languages and frameworks I've worked with, including JavaScript, TypeScript, Vue.js, Nuxt.js, and will expand to others in the future.
The goal is to foster consistent, maintainable, and testable code, serving as a quick reference and a living record of my evolving understanding of software development. For a broader collection of development and IT resources, including articles, tutorials, and tools, be sure to check out the Dev and IT Resource project.
- Core Principles & General Advice
- Architectural Patterns & Design Choices
- Language & Framework Specific Remarks
- Utilities
- Useful Tools & Resources
- Testing Strategies & Tooling
- Presentation-Style Remarks
- NPM Package Management & Publishing
- Repository Structure
These are foundational guidelines applicable to almost any programming context.
- General Coding Principles
- Favor Modularity and Single Responsibility
- Embrace Immutability
- Practice Defensive Programming
- Consistent and Descriptive Naming
- Smart Error Handling & User Feedback
- Performance Awareness
- Continuous Learning & Refactoring
- Code Reviews & Pair Programming
- Git Workflow & Hooks (
pre-commit
andpre-push
Strategy)- Recommended
pre-commit
actions (Linter, Formatter, Type Checking) - Recommended
pre-push
actions (Unit Tests, PR Workflow with Squashing) - Commit Message Formatting (Conventional Commits with Commitlint)
- Recommended
- GitHub Actions: CI/CD Pipeline Recommendations
- Recommended CI/CD stages and jobs (PR checks, Deployments).
- Importance of CI/CD even with Git hooks.
- EditorConfig for Consistent Code Style
- Using
.editorconfig
to enforce consistent coding styles across different editors. - Key settings: Indentation, Line Endings, Character Set, End of Line, Trim Trailing Whitespace, Insert Final Newline.
- Using
- AI Learning Caution: The Importance of Struggle
- The dangers of over-reliance on AI tools for coding.
- Key skills you miss out on when AI does the heavy lifting.
- How to use AI as a tool, not a crutch: struggle first, then ask for help.
- The importance of critical thinking, problem-solving, and building intuition.
In-depth explanations of high-level architectural patterns and significant design decisions.
- Facade Pattern: Simplifying Complex Interactions in the Frontend
- Rationale for simplifying complex subsystem interactions.
- Benefits: Reduced component complexity, centralized orchestration, improved maintenance.
- Examples of direct calls vs. Facade usage.
- When and where to apply the pattern.
- Monads: Either and Maybe for Robust Data Flow
- Detailed explanation of
Either
andMaybe
Monads. - Functional Programming principles encouraged by Monads (Immutability, Pure Functions, Composition, Separation of Concerns).
- Combined power with Domain Management for decoupled and agnostic code.
- Detailed explanation of
- API Service Layer Design
- Rationale for dedicated service classes with static methods.
- Benefits: Separation of Concerns, Testability, Reusability, Consistent Error Handling.
- Domain Management using Abstraction (IDomain & Null Object Pattern)
- Defining
IDomain
interface and concrete domain classes. - Advantages: Eliminating Null Checks, Decoupling from API Structure, Encapsulation of Business Logic.
- Defining
- Why Separate UI, Service, Domain, Validation, and Store Layers
- Fundamental reasons for separating concerns in application architecture.
- Benefits: Maintainability, Testability, Readability, Reusability, Scalability, Flexibility.
- Functional Programming Principles for Clean Code
- Deep dive into Pure Functions, Immutability, First-Class/Higher-Order Functions, Composition, and Declarative vs. Imperative Programming.
- Impact on Clean Code Architecture goals (Testability, Modularity, Readability, Predictability).
Practical advice and common patterns specific to particular technologies.
- Guide to Fully Leveraging TypeScript
- Preventing Duplicate Function/Anonymous Function Addition
- Async/Await Explained: Why We Wait (Again and Again)
- Understanding the wrapping of
async
functions and the importance ofawait
. - Real-world example of fetching user data with multiple
await
s. - The concept of "unwrapping" promises in application logic.
- Understanding the wrapping of
- Composable/Utility Function Export Pattern
- Module Import Style Guidelines
- Store (State Management) Usage Scope
- Reactivity with
shallowRef
Considerations - Pinia Store Structure: Controlling External Exposure
- Using Composition API for true encapsulation.
- Extracting internal logic to utilities.
- Naming conventions.
In this section, we explore practical utility classes that demonstrate various coding patterns and provide reusable solutions for common tasks.
- Description: This utility class provides a set of common string manipulation methods (like
capitalize
,toLowerCase
,trim
,replace
, etc.) designed to be chainable. It also includes helpful validation methods such asisEmpty
,isLessThan
,isMoreThan
, andisEqual
. This allows you to apply multiple transformations and perform checks on a string in a clean, readable, and fluent manner, mimicking natural language. - Key Learning Points:
- Fluent API / Method Chaining: How to design methods that return
this
(the current instance) to enable chaining multiple operations. - Static Factory Methods: Using
StringUtils.of()
to create instances without thenew
keyword, making the API more user-friendly and consistent. - Encapsulation: Managing internal string state (
currentString
) safely within the class. - Practical String Manipulation & Validation: Reusable helpers for common string tasks and checks, improving code readability and reducing repetition.
- Fluent API / Method Chaining: How to design methods that return
- Description: This utility class provides a set of common number manipulation methods (like
add
,multiply
,toFixed
,round
, etc.) designed to be chainable. It also includes helpful validation methods such asisZero
,isLessThan
,isMoreThan
,isEqual
,isBetween
,isEven
,isOdd
,isFinite
, andisDivisibleBy
. This allows you to apply multiple transformations and perform checks on a number in a clean, readable, and fluent manner, mimicking natural language. - Key Learning Points:
- Fluent API / Method Chaining: How to design methods that return
this
(the current instance) to enable chaining multiple operations. - Static Factory Methods: Using
NumberUtils.of()
to create instances without thenew
keyword, making the API more user-friendly and consistent. - Encapsulation: Managing internal number state (
currentNumber
) safely within the class. - Practical Number Manipulation & Validation: Reusable helpers for common number tasks and checks, improving code readability and reducing repetition.
- Fluent API / Method Chaining: How to design methods that return
- Description: This utility class provides a set of common monetary calculation and formatting methods (like
add
,subtract
,multiply
,divide
,toPercentage
,format
, etc.) designed to be chainable. It internally handles monetary values as integers (e.g., cents) to meticulously avoid floating-point inaccuracies inherent in JavaScript's standard number type, ensuring precision. It also includes helpful validation methods such asisZero
,isPositive
,isNegative
,isEqual
,isLessThan
, andisMoreThan
. This allows you to apply multiple financial transformations and perform checks on monetary values in a clean, readable, and fluent manner, mimicking natural language. - Key Learning Points:
- Fluent API / Method Chaining: How to design methods that return
this
(the current instance) to enable chaining multiple operations. - Static Factory Methods: Using
MoneyUtils.of()
to create instances without thenew
keyword, making the API more user-friendly and consistent. - Encapsulation: Managing internal monetary state (
_cents
,_currency
,_scale
) safely within the class. - Precision in Financial Calculations: A critical pattern for handling money by storing values as integers (e.g., cents) to prevent common floating-point errors.
- Practical Monetary Operations & Validation: Reusable helpers for common financial tasks and checks, improving code readability and reducing repetition in e-commerce or financial applications.
- Fluent API / Method Chaining: How to design methods that return
- Description: This utility class provides a set of common logical operations and validation methods for boolean values (like
and
,or
,not
,xor
,isTrue
,isFalsy
, etc.) designed to be chainable. It robustly handles various input types, converting them to their boolean equivalent for operations. This allows you to build complex conditional logic and perform checks on boolean states in a clean, readable, and fluent manner, mimicking natural language. - Key Learning Points:
- Fluent API / Method Chaining: How to design methods that return
this
(the current instance) to enable chaining multiple logical operations. - Static Factory Methods: Using
BooleanUtils.of()
to create instances without thenew
keyword, making the API more user-friendly and consistent. - Encapsulation: Managing internal boolean state (
currentBoolean
) safely within the class. - Truthiness and Falsiness: Practical application of JavaScript's truthy/falsy concepts in validation methods.
- Practical Logical Operations & Validation: Reusable helpers for common conditional checks and boolean transformations, improving code readability and reducing complex
if/else
or nested logical expressions.
- Fluent API / Method Chaining: How to design methods that return
This document serves as a curated list of valuable tools and resources that can significantly enhance various aspects of software development, design, and productivity. These tools are categorized to help you quickly find what you need for different tasks.
- Useful Tools and Resources
- Description: A comprehensive list of external tools and resources categorized by their utility (e.g., Email & SMTP Testing, Diagramming, Career & Resume Building, Web Development & Database Tools, AI & Document Interaction). Each entry provides a brief description and relevant keywords for quick discovery.
- Keywords: Developer tools, web development resources, software engineering tools, productivity tools, design tools, AI tools, database tools, email testing, diagramming, resume builder.
Insights into testing methodologies and specific tool configurations.
- Component Stubbing in Vue Tests
- Mocking
useRuntimeConfig
in Nuxt.js with Vitest - Resolving Nuxt 3 Virtual Module Errors in Vitest (
#app
etc.) - Test File Exclusion and Alias Resolution (Nuxt.js/Vite/Vitest)
- Vite's conventional exclusion of test files.
- Alias and auto-import issues in test files.
- IDE behavior differences.
- Testing Reactive Composables in Nuxt & Vitest: Overcoming Mocking Challenges
- Vitest's strict matchers (
toBe
,toEqual
,toStrictEqual
). - The "different instances" problem with reactive mocks in Nuxt/Vitest.
- Why global mocks in
vitest.setup.ts
can fail for reactive state. - A robust pattern for centralizing singleton mocks and applying them locally.
- Vitest's strict matchers (
Longer, more detailed explanations that might be suitable for internal presentations or deep dives.
- Vue.js Form Validation: Best Practices
- Why direct component validation is not a best practice.
- Recommended approaches: Client-side libraries, custom composables/utilities, server-side validation.
- The Trouble with Using "Raw API Data" Directly in Frontend Components
- The problem with using raw DTOs directly in frontend components.
- Common issues: Naming inconsistencies, excess data, reactivity challenges, testing difficulties.
- Recommended solution: Transform DTOs into "UI-Friendly" objects (Domain Objects or ViewModels).
- Benefits of this approach: Cleaner code, easier testing, better maintainability.
This section covers common challenges and best practices related to managing, versioning, and publishing NPM packages, including strategies for testing and structuring reusable plugin "flavors."
- NPM Publish Troubleshooting
- The 24-hour "no-go" rule for deleting and republishing.
- Managing versions with
Changesets
(automated versioning and changelogs). - Handling build and transpilation issues.
- Ensuring all necessary files are included in the published package.
- Authentication and permissions for publishing.
- Strategies for local package testing (
npm link
,npm pack
). - Creating plugin "flavors" using
package.json
exports
for different configurations. - Linting Your Own Plugin's Code (
eslint-config-epsvue
) to maintain high quality. - Test Your npm plugin locally for testing your code locally.
This section outlines the current directory and file structure for the coding-remarks
repository itself.
.
├── .git/ \# Git version control directory
├── .github/ \# GitHub specific configurations (e.g., workflows)
│ ├── workflows/
│ | └── ci.yml \# GitHub Actions CI workflow (npm-based)
│ └── pull_request_template.md
├── .husky/ \# Git hooks managed by Husky
│ ├── pre-commit \# Runs lint-staged
│ ├── commit-msg \# Runs commitlint
│ └── \_/ \# Husky internal directory
├── .vscode/ \# VS Code editor settings (optional)
│ └── settings.json
├── remarks/ \# Categorized general coding remarks
│ ├── general/ \# General coding advice details
│ │ ├── ai-learning-caution.md
│ │ ├── editorconfig.md
│ │ ├── general-coding-principles.md
│ │ ├── git-workflow-hooks.md
│ │ ├── github-actions-ci-recommendations.md
│ │ └── useful-tools-and-resources.md \# NEW: Useful tools and resources
│ ├── vue-nuxt/ \# Vue.js & Nuxt.js specific remarks
│ │ ├── composable-utility-export-pattern.md
│ │ ├── module-import-style.md
│ │ ├── pinia-store-encapsulation.md
│ │ ├── reactivity-shallowref.md
│ │ └── store-usage-scope.md
│ ├── typescript-javascript/ \# TypeScript & JavaScript specific remarks
│ │ ├── async-await-explained.md
│ │ ├── leveraging-typescript.md
│ │ └── prevent-duplicate-function-addition.md
│ ├── styling/ \# Styling related remarks
│ │ └── tailwind-color-configuration.md
│ └── testing/ \# Specific testing tool configurations/issues
│ ├── component-stubbing-vue.md
│ ├── mocking-useRuntimeConfig-vitest.md
│ ├── nuxt-virtual-module-resolution.md
│ ├── test-file-exclusion-and-aliases.md
│ └── vitest-nuxt-reactive-mocks.md
├── patterns/ \# In-depth explanations of architectural patterns
│ ├── api-service-layer-design.md
│ ├── domain-management-abstraction.md
│ ├── functional-programming-principles.md
│ ├── facade-pattern.md
│ ├── monads-either-maybe.md
│ └── why-separate-layers.md
├── presentations/ \# Longer, presentation-style remarks or deep dives
│ ├── dto-advice-frontend.md
│ └── vue-form-validation-best-practices.md
├── npm/ \# NPM package related remarks and troubleshooting
│ ├── eslint-plugin-local-testing.md \# Moved from remarks/testing
│ ├── npm-publish-troubleshooting.md \# Moved from remarks/testing
│ └── stylelint-configuration.md \# Moved from remarks/styling
├── utils/ \# General utility functions and classes
│ ├── string-utils.ts
│ ├── number-utils.ts
│ ├── money-utils.ts
│ └── boolean-utils.ts
├── .commitlintrc.json \# Commitlint configuration
├── .editorconfig \# Editor style configuration
├── .gitignore \# Git ignore rules
├── package.json \# Project dependencies and scripts
├── package-lock.json \# npm lock file
├── README.md \# This document\! (The main entry point)
├── .prettierignore \# Prettier ignore file
└── .prettierrc.json \# Prettier configuration