Repository and File Structure Organization
Monorepo Layout
All libraries reside in a single monorepo, enabling shared tooling, unified dependency management, and atomic cross‑package changes. The repository root contains workspace‑level configuration files, while each library is an independent package under a dedicated directory.
Library Internal Structure
Every library follows a consistent, predictable layout. The core implementation lives under src/lib/, while the single public entry point is src/public-api.ts. Configuration files required by the Angular Package Format (ng-package.json, tsconfig.lib.json) are placed at the library root.
ng-package.jsondefines the entry point assrc/public-api.tsand ensures the built output follows the Angular Package Format.tsconfig.lib.jsonextends the roottsconfig.base.jsonand enables strict mode for the library.package.jsonspecifies the library name (@company/filter), version, and necessary peer dependencies (@angular/core,@angular/common, etc.).
Test and Storybook Colocation
Unit tests and Storybook stories are kept in the same directory as the source file they relate to. This colocation makes it easy to find, run, and maintain tests and stories, and it naturally scopes changes.
Unit tests: files with the suffix
.spec.ts(e.g.,filter.component.spec.ts). They sit next to the implementation file, not in a separate__tests__folder.Storybook stories: files with the suffix
.stories.ts(e.g.,filter.component.stories.ts). A story is mandatory for every exported component; it lives alongside the component’s.ts,.scss, and.spec.tsfiles.
Barrel Exports and index.ts
To keep public-api.ts concise and maintainable, barrel files (index.ts) are used throughout the library’s internal structure. Each logical group (components, services, directives, models) aggregates its exports into a single barrel, and public-api.ts re‑exports only from those barrels.
Example:
This approach:
Prevents
public-api.tsfrom growing into a thousand‑line file.Provides clear boundaries and discoverability of public symbols.
Allows internal refactoring without touching the public entry point, as long as the barrel exports remain stable.
File Naming Conventions
Consistent naming reduces mental overhead and simplifies refactoring.
Components: kebab‑case file name, dots for suffixes –
filter-chip.component.ts,filter-chip.component.scss,filter-chip.component.spec.ts,filter-chip.component.stories.ts.Services: kebab‑case with
.service.ts–filter-api.service.ts.Directives: kebab‑case with
.directive.ts–highlight.directive.ts.Pipes: kebab‑case with
.pipe.ts–truncate.pipe.ts.Modules: kebab‑case with
.module.ts–filter.module.ts.Models / types: descriptive kebab‑case with
.models.tsor.types.ts–filter.models.ts,notification.types.ts.Styles:
.scssextension, colocated with the component unless shared across several components (in which case a dedicated_shared.scsspartial may be placed in astyles/subdirectory).
All source files are located inside src/lib/ (or its subdirectories). Only the files that are explicitly exported from public-api.ts (directly or through barrels) become part of the library’s public API.