The Initial Structure of an Angular App

I would like to start a series of articles on Angular development from scratch. Focusing on the fundamentals of the framework and what’s happening under the hood. In this post, we’re going to focus on the initial setup and the project structure of an Angular application.

The first thing we have to do to start working with Angular is to install the Angular-CLI.

We are going to discuss Angular-CLI more in-depth in another article.

So, you can install it by running the following command:

npm install -g @angular/cli

And when we have the Angular CLI installed, we can see the list of options with the command:

ng help

The Angular CLI is the best way to create the setup for a new Angular application. Because it takes care of all the work associated with setting up the tooling.

To create a new project with the Angular CLI simply write:

ng new app-name // <= name of your app here

This will create the initial project structure for our application. Even though the setup is created for us. It is important to understand the different parts of the application and the configuration being used. Let’s have a look!

The initial project structure

The first three folders we see at the top are:

  • The /e2e folder for end to end testing
  • The /node_modules folder containing all the modules that the application needs
  • The /src folder with the source code. (In addition to these folders)
  • The CLI will also create a /dist folder. When we build the application running the command ‘ng build‘.
Initial project structure of an Angular app created with the Angular CLI

The .editorconfig file contains the configuration for the text editor, you can see the list of options for this file on the website https://editorconfig.org/

I personally like to add a .vscode folder at the root of the project containing a settings.json file with my desired configuration for the editor. By doing this I can have specific options for the Visual Studio Code editor. For example, using the editor.formatOnSave option, that formats the code using the Prettier extension.

As we can see, the CLI initialized a Git repository and created a .gitignore file. This contains the list of files and folders to be ignored by Git.

Next, we have the angular.json file. This file is essential to the project, as it contains CLI configuration defaults for all the projects in the workspace. It also includes important configuration options. This is for the build, serve, and the test tools that the CLI uses.

Here we can see some options from the angular.json file:

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "play": { // <= name of the current project created by the Angular-CLI
      "projectType": "application",
      "schematics": {
        "@schematics/angular:component": {
          "style": "scss" // <= default styles preprocessor for the project
        }
      },
      "root": "",
      "sourceRoot": "src", // <= src folder containing the source code for the app 
      "prefix": "app", // <= prefix for the directives for the components created by the angular-cli
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/play", // <= output directoy for build
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.app.json", // <= typescript configuration file
            "aot": false,
            "assets": [ // <= assets location
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [ // <= styles files
              "src/styles.scss"
            ],
            "scripts": []
          },
          "configurations": {
            "production": { // <= build configuration for production
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
      ...

More information on the angular.json file: https://angular.io/guide/file-structure and https://angular.io/guide/workspace-config

The browserlist file is used by the build system to adjust CSS and JS output to support specific browsers.

The CLI creates the package.json file, which contains a list of the packages needed by all the projects in the workspace. It also defines the commands to run the application, to build it and to run tests. And you can add other additional configurations, such as the Prettier format or Babel, for example.

{
  "name": "angular",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    ...
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "~8.2.0",
    "@angular/common": "~8.2.0",
    "@angular/compiler": "~8.2.0",
    "@angular/core": "~8.2.0",
    "@angular/forms": "~8.2.0",
    "@angular/platform-browser": "~8.2.0",
    "@angular/platform-browser-dynamic": "~8.2.0",
    "@angular/router": "~8.2.0",
    ...
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.802.2",
    "@angular/cli": "~8.2.2",
    "@angular/compiler-cli": "~8.2.0",
    ...
  }
}

The Dependencies are the packages that are essential to run and build the application. The devDependencies are the only ones necessary for the development and they don’t need to be used for the final build.

The package-lock.json file is added by NPM and its purpose is to lock the specific versions of the packages. This makes sure that the installation is always the same in different environments.

Tsconfig.json – The TypeScript compiler configuration file contains the configuration settings for the TypeScript compiler.  (https://angular.io/guide/typescript-configuration)

One thing that’s worth noticing here is that the compiler is targeting es2015 (ES6) by default. You might want to change that to ES5 if you need to target older browsers.

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "module": "esnext", // <= esnext module
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2015", // <= targeting es2015 by default
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2018",
      "dom"
    ]
  },
  "angularCompilerOptions": {
    "fullTemplateTypeCheck": true,
    "strictInjectionParameters": true
  }
}

Tsconfig.app.json and Tsconfig.spec.json extend the tsconfig configuration file and add some specific configuration settings. This is for the app and for testing.

The Tslint.json file contains rules for the TypeScript linter. They will display warnings when the rules are violated.

Inside the /src folder we have the index.html file for the application and the main.ts file that bootstrap the application and the /assets folder. This will contain the images and other assets for our application. And the /app folder that contains all the code for the app, like the modules, the services, the components, the templates and more.