Creating Angular Module and Deploy it to npm

Building Angular web application is fun and easy. Angular application is build from modules (at least one) and each module has components and services.

One great thing about modules is that you can build your own module as unit of reuse and then deploy it to one or more package managers like npm.

While building a web application, you can download, install and easily use modules that provide common services (http , routing, xml, …) and useful components (Grids, smart controls, useful pipes and more)

In this post i will go over the process of creating a new module with services and components , deploy it to npm and use it in other application:

To start lets create a new angular application

# ng new SimpleModule

You can use the application module or delete it and create a new one:

# ng g m Samp

Now create a simple service:

# ng g s Math

With simple test method:

import { Injectable } from '@angular/core';

@Injectable()
export class MathService {

  constructor() { }
  add(a:number,b:number):number{
    return a+b;
  }
}

Create a simple component:

# ng g c --it Simp

And simply change its template:

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-simp',
  template: `
    <p>
      Component from Module
    </p>
  `,
  styleUrls: ['./simp.component.css']
})
export class SimpComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

Now declare the service and the component in the module class decorator:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import {MathService} from "../math.service";
import {SimpComponent} from "../simp/simp.component";

@NgModule({
  imports: [
    CommonModule
  ],
  declarations: [SimpComponent],
  providers: [MathService],
  exports: [SimpComponent]
})
export class SimpModModule { }

You should export the components (add to exports array) and provide the services (add to the providers array)

Thats it – we finished with our featured module now we need to make some more steps to deploy it to npm:

Adding to git and github

The project is already has a git repository (generated by Angular CLI)

Open a new repository in github and push the project:

# git remote add origin https://github.com/[username]/[repository].git
# git push -u origin master

Install all requirements and add –save to update package.json file

# npm install reflect-metadata --save
# npm install es6-shim --save

 

Publish to NPM

Open an account in npmjs.com

Set the following settings:

npm set init-author-name 'Liran BH'   
npm set init-author-email '[email protected]'
npm set init-author-url 'https://devarea.com'
npm set init-license 'MIT'
npm set save-exact true

Add a file index.ts to the root directory and export the module, the service and the component:

export {MathService} from './src/app/math.service';
export {SimpModModule} from './src/app/simp-mod/simp-mod.module';
export {SimpComponent} from './src/app/simp/simp.component';

Note that you can deploy it without the source code (typescript) using ng build command

To connect to your npm account type:

# npm adduser

Edit the package.json file, set the version and set private to false:

{
  "name": "dev-area-samp",
  "version": "1.0.2",
  ...
  "private": false,
....


}

After each change update the git and the github:

# git add .
# git commit –m 'basic files'
# git push

to deploy type:

# npm publish

every time you deploy the package you need to change the version and for release add a tag:

# git tag 1.0.3
# git push --tags
# npm publish

Testing Your package:

Create a new Angular Application

# ng new TestApp

Install our package using npm:

# npm install dev-area-samp

Now, declare the imported module – SimpModModule in your app.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import {SimpModModule} from 'dev-area-samp';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    SimpModModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Now you can create an instance of the service and use it and also can add the component using its selector:

import { Component } from '@angular/core';
import {MathService} from 'dev-area-samp';

@Component({
  selector: 'app-root',
  template: `
    <h1>
      Welcome to {{title}}! {{num}}
    </h1>
    <button (click)="onclick()">Service</button>
    <app-simp></app-simp>
  `,
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app';
  num:number;
  constructor(private _ser:MathService){

  }
  onclick()
  {
    this.num = this._ser.add(100,200);
  }
}

Module dependency

If you want to import the module to your app.module , you need to import the components and also the services but if you import it for child (featured module) you don’t need the services because if the service will be provided by more than one module, you’ll get an error

For that reason it is a convention to declare a method forRoot() in the module class to return the service provider:

import {SimpComponent} from "../simp/simp.component";

@NgModule({
  imports: [
    CommonModule
  ],
  declarations: [SimpComponent],
  exports: [SimpComponent]
})
export class SimpModModule {
  static forRoot(): ModuleWithProviders {
    return {
      ngModule: SimpModModule,
      providers: [MathService]
    }
  }

}

 

Client

If you want to use the module in the main app.module call forRoot:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import {SimpModModule} from 'dev-area-samp';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    SimpModModule.forRoot()
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

If you need only the component, or want to import the module in a child featured module use only the module name:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import {SimpModModule} from 'dev-area-samp';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    SimpModModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

You can see the code here, or test it using npm install

 

Tagged

4 thoughts on “Creating Angular Module and Deploy it to npm

  1. Is it POSSIBLE TO CREATE A MODULE AND USE IT WITHOUT NPM INSTALL RATHER FROM LOCAL DIRECTORY.
    PLEASE INFORM IF THAT’S POSSIBLE

  2. Hello,
    Thank you very much for your tutorial. I tried it step by step to publish my module. even i used your source code publish it but in all cases i received an error message as below. could you please let me know what is the reason of this error.

    ERROR in ./node_modules/dev-ramin-packagr/index.ts
    Module build failed: Error: C:\Users\armanfar\sampleApps\testApp\node_modules\dev-ramin-packagr\index.ts is missing from the TypeScript compilation. Please make sure it is in your tsconfig via the ‘files’ or ‘include’ property.
    The missing file seems to be part of a third party library. TS files in published libraries are often a sign of a badly packaged library. Please open an issue in the library repository to alert its author and ask them to package the library using the Angular Package Format (https://goo.gl/jB3GVv).
    at AngularCompilerPlugin.getCompiledFile (C:\Users\armanfar\sampleApps\testApp\node_modules\@ngtools\webpack\src\angular_compiler_plugin.js:749:23)
    at plugin.done.then (C:\Users\armanfar\sampleApps\testApp\node_modules\@ngtools\webpack\src\loader.js:41:31)
    at process._tickCallback (internal/process/next_tick.js:68:7)
    i 「wdm」: Failed to compile.

    Thanks in advance.

    1. It seems like you don’t have index.ts file in your root folder of package.

  3. nice post, but i its not working… @RAMIN i also getting….

Comments are closed.