Fast start Angular, Ionic, ngrx project from scratch

Parham
Code道
Published in
7 min readApr 18, 2018

I always question how to start a new project. Even one month gap between projects on the same stack means many dependencies and libraries are updated with potential breaking changes.

If you are only interested in final solution jump to the section titled A better solution at the end of this article.

Time of AngularJS

We tried different approaches and it was important to learn from experience.

  1. Use projects like Yeoman or angular-seed each time to generate the base project but usually they had many files that we didn’t not need for all projects which would make it hard to maintain.
  2. Copying useful modules and reusable code from our previous project and start a new project.
  3. Separate the base scaffolding project and put it in a different git repository then clone this repository and change things like names and start a new project.

I found the 3rd option to be the most effective for us. Here are pros and cons:

Pros:

  • Creating our own scaffolding saved us more time and we had a chance to write more reusable code and common modules like: Validations, reusable UI components and utility packages.
  • We even added basic layout and modules like login which was common between our typical business application projects. This significantly improved our development pace.

Cons:

  • Your projects UI/UX may become very similar if you don’t try to be a little creative.
  • Some devs may try to fit a problem into an existing solution even if it’s not a good match because it seems easier than writing from scratch.
  • You can start doing complicated implementation because you are trying to generalise in code you write in the seed project.
  • Junior devs copy, paste file across multiple project, mixing things and you may end up with many files and packages copied by mistake because the developer didn’t have a good understanding of what is required.

I recommend this approach after you get proficient with a stack but be mindful that you need to maintain this project separately.

Angular time

  • The first Angular 2 project we did, I used a seed project to create the base project.
    I was faced with many new technologies and coding paradigm shifts. Putting project time pressure on top it was really hard to get my head around all and we just managed to successfully deliver the project with the an early release of Angular 2.
    We didn’t use TypeScript and Angular modular architecture efficiently.
    We were new to RxJs and reactive programming and it was all confusing.
  • In second and third Angular project we did a better job with TS and got a hold of RxJs but still it was very unfamiliar compared to the good old JS Promises.
  • At this point, I was still copying an existing module or project to start a new one. Then changing names and sometimes forget things here and there and leaving traces of old project in the new one.😔
  • Moving forward with Angular and introduction of their CLI I found it really powerful to generate the project from scratch with minimum dependencies and only include what is required.
  • This was great but we also started using ngrx for state management and needed to write a lot of boilerplate code. Angular CLI didn’t have any support for ngrx so it would not get us too far. So we didn’t use CLI effectively and kept copying stuff around.
  • In our 4th Angular project I had a chance to revise our project start up approach again. We Created the project with Angular CLI and it improved our speed to get the base running and also use angular feature modules but adding ngrx reducers, action, effects was still a slow and repetitive process.

Is there a better way?

I was supposed to start a new Ionic project recently and I was facing the same question. How should I create the base project?

I was thinking that I wish there was a CLI that can help me generate these artifacts:

  • Base ionic app and it’s scaffolding.
  • Creating new Angular feature modules and components.
  • Generating ngrx artifacts (reduces, actions and effects) for a component in my feature module.

I found that ngrx has released a scaffolding tool called ngrx/schematics that can help me with generating ngrx artifacts but it only works with Angular CLI.

If you have used Ionic you know that it does not expose Angular CLI and its configs by default. Same for webpack. So it kind of forces you to go through ionic CLI and uses Angular CLI under the hood.

I found that there is a way to configure and access Angular CLI and use it side by side with Ionic CLI. This was a good hint o make a hybrid solution.😊

A better solution

  • Use Ionic CLI to generate base Ionic app with the template you like
  • Use Angular CLI to generate feature modules and ngrx artifacts.

Here are the steps:

1. Create base Ionic app with Ionic CLI

~ npm install -g ionic
~ npm install -g cordova
~ npm install -g @angular/cli
~ ionic start myApp tabs
~ npm run ionic:serve

You should see project running on http://localhost:8100/

2. Setting up Angular CLI and ngrx/schematics

  • First install @angular/cli locally and also install ngrx/schematics and its dependencies.
~ npm install --save-dev @angular/cli@latest
~ npm install @ngrx/schematics --save-dev
~ npm install @ngrx/{store,effects,entity,store-devtools} --save
  • Create a .angular-cli.json file in your root directory, beside your ionic.config.json file.

Angular CLI (ng) will use it to know where to generate new files. The only contents it needs to have are:

{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"apps": [
{
"root": "src"
}
]
}
  • Make @ngrx/schematics the default collection as described above, e.g.:
ng set defaults.schematics.collection=@ngrx/schematics

that command will modify the file .angular-cli.json so that you don't have to type --collection @ngrx/schematicswith every command.

  • Make SCSS the default style format (the default for Ionic):
ng set defaults.styleExt scss
  • After that, you can use ng with the same instructions as above, e.g.:
ng generate store State --root --module app.module.ts

Note: as Ionic currently doesn’t support Angular’s environment.ts files, you will have to remove them from the imports and adjust the changed files manually, but apart from that, you can use the generated files normally. You will probably have to remove from app.module.ts the line with:

import { environment } from '../environments/environment';

And change the line with:

!environment.production ? StoreDevtoolsModule.instrument() : [],//to:StoreDevtoolsModule.instrument(),

during development, and probably remove that line in production.

And in the file in reducers/index.ts remove the line:

import { environment } from '../../environments/environment';

and change the line:

export const metaReducers: MetaReducer<State>[] = !environment.production ? [] : [];//to:export const metaReducers: MetaReducer<State>[] = [];

during development, and probably remove that line in production.

3. Add a new feature module and component with Angular CLI

You should be able to run ng command and see Angular CLI help. Now we can use CLI to create a new module.

  • Add a new feature module
ng generate module myNewModule

This causes the CLI to create a folder called my-new-module with a file inside called my-new-module.module.ts.

Go to generated module my-new-module.module.ts and import IonicPageModule. This necessary for module to be able to use ionic directives.

  • Add a new component in feature module
ng generate component — spec false my-new-module/myNewComponent 

This generates a folder for the new component within the my-new-module folder and updates the feature module.

When you generate components (like containers) they are generated with a styleUrls pointing to the .scss file. But by default, Ionic doesn’t include styles directly in each component, so, you will need to remove that line from the components you create with ng.

  • Go to generated feature module and add components defined in declarations array to exports and entryComponents array as well.
  • To incorporate the feature module into your app, you have to let the root module, app.module.ts, know about it. To import it into the AppModule, add it to the imports in app.module.ts and to the imports array

4. Add your first reducer, action and effect with ngrx/schematics

  • Generate feature module root reducer
ng generate reducer /my-new-module/myNewModule — group — module /my-new-module/my-new-module.module.ts

The name you pass for this reducer is gonna appear in the root of state as the entry so pick a good name.

  • Add a reducer to your component
ng generate r /my-new-module/my-new-component/Example -r ../reducers/my-new-module.reducer.ts

This will add a reducer for Example in the folder you specify based on path (my-new-module/my-new-component) and add it to module root reducer.

Paths defined here are all relative and /src/app/ is prepended to them.

  • Add an action to your component
ng generate action /my-new-module/my-new-component/Example
  • Add an effect to your component
ng generate effect — spec false /my-new-module/my-new-component/Example — module /my-new-module/my-new-module.module.ts

Now your src should look like this:

Congrats! You successfully created a feature module, a component inside it with all necessary ngrx bits.

Some house keeping

Remember that we are using angular feature module architecture so you need to add EffectsModule.forRoot([]) to your imports in app.module.ts for feature module effects to work.

Also you can get rid of ionic pages folder and change your app.component.ts to use your new component as the entry.

rootPage: any = MyNewComponentComponent;

Conclusion

Steps 1, 2 are one off and when you setup the base project you will be able to create new feature modules and ngrx artifacts easily and avoid copy, pastes.

This will improve your development speed but also give your code better consistency if you have many developers on project.

Of course after setting up this project I recommend to put it in separate repository and you can use it as Ionic seed application. So next time you will just clone it and do a npm install instead of step 1 and 2.

--

--

Parham
Code道
Editor for

Web & mobile developer, @Auth0Ambassador. Follow me for content on JavaScript, Angular, React, Ionic & Capacitor, Progressive web apps & UI/UX.