Skip to content

πŸ…°οΈπŸ¦Έ Template to start developing a Progressive Web Application with Angular, Transloco, Angular Universal, SSR/ISR, TailwindCSS, Jest, Cypress, ESLint, Prettier, Husky, etc.

License

borjapazr/angular-skeleton

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

69 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Node.js, Typescript and Express template
Node.js, Typescript and Express template

GitHub package.json version GitHub CI Workflow Status GitHub CD Workflow Status GitHub LICENSE Demo Documentation

πŸ…°οΈπŸ¦Έ Production-ready template for Progressive Web Applications implemented with Angular, TailwindCSS, Transloco, ngx-isr, etc.

ℹ️ About β€’ πŸ“‹ Features β€’ 🀝 Contributing β€’ πŸ›£οΈ Roadmap β€’ 🎯 Credits β€’ 🚩 License


ℹ️ About

The main goal of this project is to provide a base template for the generation of a production-ready web application made with Angular. The idea is to avoid having to configure all the tools involved in a project every time it is started and thus be able to focus on the definition and implementation of the business logic.

πŸ“£ This is an opinionated template. The architecture of the code base and the configuration of the different tools used has been based on best practices and personal preferences.

πŸš€ Quick start

  • Start project in development mode:

    npm run start:dev
  • Start project in production mode:

    npm run start:prod

πŸ“‹ Features

  • Angular: Angular is a platform for building mobile and desktop web applications.
  • Angular Universal: Server-side rendering (SSR) with Angular Universal.
  • TailwindCSS: A utility-first CSS framework packed with classes like flex, pt-4, text-center and rotate-90 that can be composed to build any design, directly in your markup.
  • ng-lazyload-image: A super small libary for lazy loading images for Angular apps with zero dependencies
  • ngx-isr: Incremental Static Regeneration (ISR) enables developers and content editors to use static-generation on a per-page basis, without needing to rebuild the entire site. With ISR, you can retain the benefits of static while scaling to millions of pages.
  • i18n using Transloco
  • Unit tests using Jest
  • e2e tests using Cypress
  • Spell check
  • Linting with ESLint
  • Formatting with Prettier
  • Stylelint: A mighty, modern linter that helps you avoid errors and enforce conventions in your styles.
  • HTMLHint: A linter for HTML that helps you avoid errors and enforce conventions in your HTML.
  • Commit messages must meet conventional commits format
  • Git hooks with Husky and lint-staged
  • Containerised using Docker and Docker Compose
  • GitHub Actions
  • Makefile as project entrypoint
  • A lot of emojis πŸ›Έ

πŸ—‚ Codebase structure

angular-skeleton/
β”œβ”€β”€ .github/
β”œβ”€β”€ .husky/
β”œβ”€β”€ .vscode/
β”œβ”€β”€ cypress/
β”‚   β”œβ”€β”€ e2e/
β”‚   β”œβ”€β”€ fixtures/
β”‚   β”œβ”€β”€ support/
β”‚   β”œβ”€β”€ coverage.webpack.js
β”‚   └── tsconfig.json
β”œβ”€β”€ docker/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ app/
β”‚   β”‚   β”œβ”€β”€ core/
β”‚   β”‚   β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”‚   β”œβ”€β”€ constants/
β”‚   β”‚   β”‚   β”œβ”€β”€ enums/
β”‚   β”‚   β”‚   β”œβ”€β”€ guards/
β”‚   β”‚   β”‚   β”œβ”€β”€ handlers/
β”‚   β”‚   β”‚   β”œβ”€β”€ interceptors/
β”‚   β”‚   β”‚   β”œβ”€β”€ loaders/
β”‚   β”‚   β”‚   β”œβ”€β”€ models/
β”‚   β”‚   β”‚   β”œβ”€β”€ resolvers/
β”‚   β”‚   β”‚   β”œβ”€β”€ services/
β”‚   β”‚   β”‚   β”œβ”€β”€ strategies/
β”‚   β”‚   β”‚   β”œβ”€β”€ tokens/
β”‚   β”‚   β”‚   β”œβ”€β”€ utils/
β”‚   β”‚   β”‚   β”œβ”€β”€ ...
β”‚   β”‚   β”‚   └── core.module.ts
β”‚   β”‚   β”œβ”€β”€ features
β”‚   β”‚   β”‚   β”œβ”€β”€ feature-a
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ models/
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ pages/
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ services/
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ ...
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ home-routing.module.ts
β”‚   β”‚   β”‚   β”‚   └── home.module.ts
β”‚   β”‚   β”‚   β”œβ”€β”€ feature-b
β”‚   β”‚   β”‚   └── ...
β”‚   β”‚   β”œβ”€β”€ shared/
β”‚   β”‚   β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”‚   β”œβ”€β”€ directives/
β”‚   β”‚   β”‚   β”œβ”€β”€ modules/
β”‚   β”‚   β”‚   β”œβ”€β”€ pipes/
β”‚   β”‚   β”‚   β”œβ”€β”€ services/
β”‚   β”‚   β”‚   └── shared.module.ts
β”‚   β”‚   β”œβ”€β”€ app-routing.module.ts
β”‚   β”‚   β”œβ”€β”€ app.browser.module.ts
β”‚   β”‚   β”œβ”€β”€ app.component.html
β”‚   β”‚   β”œβ”€β”€ app.component.scss
β”‚   β”‚   β”œβ”€β”€ app.component.ts
β”‚   β”‚   β”œβ”€β”€ app.module.ts
β”‚   β”‚   └── app.server.module.ts
β”‚   β”œβ”€β”€ assets/
β”‚   β”‚   β”œβ”€β”€ i18n/
β”‚   β”‚   β”œβ”€β”€ icons/
β”‚   β”‚   └── images/
β”‚   β”œβ”€β”€ environments/
β”‚   β”œβ”€β”€ styles/
β”‚   β”‚   β”œβ”€β”€ abstracts/
β”‚   β”‚   β”œβ”€β”€ base/
β”‚   β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”œβ”€β”€ layout/
β”‚   β”‚   β”œβ”€β”€ vendors/
β”‚   β”‚   └── main.scss
β”‚   β”œβ”€β”€ types/
β”‚   β”œβ”€β”€ favicon.ico
β”‚   β”œβ”€β”€ favicon.png
β”‚   β”œβ”€β”€ index.html
β”‚   β”œβ”€β”€ jest.mocks.ts
β”‚   β”œβ”€β”€ jest.setup.ts
β”‚   β”œβ”€β”€ main.browser.ts
β”‚   β”œβ”€β”€ main.server.ts
β”‚   β”œβ”€β”€ manifest.webmanifest
β”‚   β”œβ”€β”€ polyfills.ts
β”‚   β”œβ”€β”€ robots.txt
β”‚   └── styles.scss
β”œβ”€β”€ .browserslistrc
β”œβ”€β”€ .commitlintrc.js
β”œβ”€β”€ .cspell.json
β”œβ”€β”€ .czrc
β”œβ”€β”€ .dockerignore
β”œβ”€β”€ .editorconfig
β”œβ”€β”€ .env
β”œβ”€β”€ .eslintcache
β”œβ”€β”€ .eslintignore
β”œβ”€β”€ .eslintrc.js
β”œβ”€β”€ .gitignore
β”œβ”€β”€ .htmlhintrc
β”œβ”€β”€ .lintstagedrc.js
β”œβ”€β”€ .ncurc.js
β”œβ”€β”€ .npmignore
β”œβ”€β”€ .prettierignore
β”œβ”€β”€ .prettierrc.js
β”œβ”€β”€ .stylelintcache
β”œβ”€β”€ .stylelintignore
β”œβ”€β”€ .tool-versions
β”œβ”€β”€ .versionrc.js
β”œβ”€β”€ CHANGELOG.md
β”œβ”€β”€ LICENSE
β”œβ”€β”€ Makefile
β”œβ”€β”€ README.md
β”œβ”€β”€ TODO.md
β”œβ”€β”€ angular.json
β”œβ”€β”€ cypress.config.ts
β”œβ”€β”€ jest.config.js
β”œβ”€β”€ ngsw-config.json
β”œβ”€β”€ nyc.config.js
β”œβ”€β”€ package-lock.json
β”œβ”€β”€ package.json
β”œβ”€β”€ routes.txt
β”œβ”€β”€ server.ts
β”œβ”€β”€ stylelint.config.js
β”œβ”€β”€ tailwind.config.js
β”œβ”€β”€ transloco.config.js
β”œβ”€β”€ tsconfig.app.json
β”œβ”€β”€ tsconfig.json
β”œβ”€β”€ tsconfig.server.json
└── tsconfig.spec.json

πŸŽ›οΈ Code style and best practices

⚠️ This section has yet to be fully documented.

  • Prettier
  • ESLint
  • Stylelint
  • HTMLHint
  • commitlint

πŸ›’ Barrel files

Barrel files are used to organize exports. This significantly reduces the size of the import blocks.

🏞 Application layout

⚠️ This section has yet to be fully documented.

  • Flexbox layout
  • TailwindCSS
  • Dark theme
  • Styles (SCSS) folder structure

🌐 Internationalization (i18n)

⚠️ This section has yet to be fully documented.

  • Transloco
  • Route language prefixing

🏎 Server Side Rendering (SSR) and Incremental Static Rendering (ISR)

⚠️ This section has yet to be fully documented.

  • Angular Universal
  • Domino
  • ngx-isr

πŸ“‡ Prerendering

⚠️ This section has yet to be fully documented.

  • Angular Universal

πŸ“ˆ SEO

⚠️ This section has yet to be fully documented.

  • CustomPageTitleStrategy

πŸ”° Progressive Web Application (PWA)

⚠️ This section has yet to be fully documented.

  • Service Worker configuration
  • Stale while revalidate strategy
  • Offline support

🌠 Image lazy-loading

⚠️ This section has yet to be fully documented.

  • ng-lazyload-image

πŸ’¨ Module preloading strategies

⚠️ This section has yet to be fully documented.

πŸ›£ Route reusability

  • RouteReuseStrategy

πŸ’ Pipes

⚠️ This section has yet to be fully documented.

πŸ§ͺ Testing

⚠️ This section has yet to be fully documented.

Unit and integration tests

  • Jest
  • jest-extended

e2e tests

  • Cypress

🐐 Makefile rules

The main actions on this project are managed using a Makefile as an entrypoint.

Usage: make TARGET [ARGUMENTS]

Targets:
  build/csr                 Build csr image
  build/ssr                 Build ssr image
  clean/csr                 Clean CSR application
  clean/ssr                 Clean SSR application
  help                      Show this help
  start/csr                 Start application in Client Side Rendering mode
  start/ssr                 Start application in Server Side Rendering mode
  stop/csr                  Stop application in Client Side Rendering mode
  stop/ssr                  Stop application in Server Side Rendering mode

⚑ Scripts

package.json scripts:

  ...
  "scripts": {
    "start:dev": "ng serve --configuration development --port 4200 --open",
    "start:prod": "ng serve --configuration production --port 4300 --open",
    "start:ssr:dev": "ng run angular-skeleton:serve-ssr:development --port 4201 --open",
    "start:ssr:prod": "ng run angular-skeleton:serve-ssr:production --port 4301 --open",
    "build:dev": "rimraf dist && ng build --configuration development",
    "build:prod": "rimraf dist && ng build --configuration production && npm run build:optimize",
    "build:ssr:dev": "rimraf dist && ng build --configuration development && ng run angular-skeleton:server:development",
    "build:ssr:prod": "rimraf dist && ng build --configuration production && ng run angular-skeleton:server:production && npm run build:optimize",
    "build:prerender:dev": "rimraf dist && ng run angular-skeleton:prerender:development",
    "build:prerender:prod": "rimraf dist && ng run angular-skeleton:prerender:production && npm run build:optimize",
    "build:optimize": "run-s optimize:* && ngsw-config dist/browser ./ngsw-config.json",
    "optimize:i18n": "transloco-optimize dist/browser/assets/i18n",
    "serve:pwa": "http-server -p 4400 -P http://localhost:4400? dist/browser -o",
    "serve:ssr": "node dist/server/main.js",
    "i18n:extract": "transloco-keys-manager extract",
    "i18n:find": "transloco-keys-manager find",
    "check:types": "tsc --pretty --noEmit && tsc --project cypress/tsconfig.json --pretty --noEmit",
    "check:format": "prettier --check .",
    "check:lint": "eslint . --ext .js,.ts --color",
    "check:html": "htmlhint .",
    "check:scss": "stylelint 'src/**/*.{css,scss}' --color",
    "check:spelling": "cspell --config=.cspell.json \"{README.md,TODO.md,.github/*.md,src/**/*.ts,src/**/*.json}\"",
    "check:i18n": "transloco-validator src/assets/i18n/*.json src/assets/i18n/**/*.json",
    "check:staged": "lint-staged",
    "fix:format": "prettier --check --write --ignore-unknown .",
    "fix:lint": "npm run check:lint -- --fix",
    "fix:scss": "npm run check:scss -- --fix",
    "test": "cross-env NODE_ENV=test jest --verbose --colors --runInBand",
    "test:spec": "npm run test -- --testPathPattern=spec",
    "test:unit": "npm run test -- --testPathPattern=unit",
    "test:int": "npm run test -- --testPathPattern=integration",
    "e2e": "ng e2e",
    "e2e:run": "ng run angular-skeleton:cypress-run",
    "e2e:open": "ng run angular-skeleton:cypress-open",
    "e2e:coverage:view": "http-server -p 9004 ./coverage-e2e/lcov-report -o",
    "test:watch": "npm run test -- --watch",
    "test:coverage": "npm run test -- --coverage --silent",
    "test:coverage:view": "http-server -p 9003 ./coverage/lcov-report -o",
    "reset-hard": "git clean -dfx && git reset --hard && npm install",
    "version": "standard-version -t",
    "prepare-release": "run-s reset-hard version",
    "commit": "cz",
    "update-deps": "npm-check-updates -u",
    "prepare": "husky install"
  },
  ...

🀝 Contributing

Just fork and open a pull request. All contributions are welcome πŸ€—

πŸ›£οΈ Roadmap

Please, check TODO for the current roadmap.

🎯 Credits

To implement this project I have based myself on many similar projects. There were countless of them and I gave them all a star.

πŸ™ Thank you very much for these wonderful creations.

⭐ Stargazers

Stargazers repo roster for @borjapazr/angular-skeleton

🚩 License

MIT @ borjapazr. Please see License for more information.