Yves Yves - 3 months ago 101
AngularJS Question

How to write Angular2 npm module - Angular2 RC 6

I can't get my head around how to write a npm module for angular2.

Even though I found 2 tutorials (One, Two) there's none covering how to implement a angular2 module (

@NgModule
) as npm package.

What I don't understand, when exactly do I need to inject the module like the
BrowserModule
for example? Do I even have to inject it with my module or is it enough to just inject the directives?

My Plugin so far:

- https://github.com/yves-s/ng2-flexbox-grid/tree/develop

- https://www.npmjs.com/package/ng2-flexbox-grid

Currently it's a copy and update to RC6 of @btmorton's angular2-grid

But I can't get it to work.

UPDATE:

This is the current state of my module ng2-flexbox-grid.ts

export * from './src/directives';
export * from './src/components';
export * from './src/interfaces';

import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';

import {NgGrid, NgGridItem} from './src/directives';

const mapValuesToArray = (obj) => Object.keys(obj).map(key => obj[key]);
// const directives = mapValuesToArray(directiveItems);

export default {
directives: [NgGrid, NgGridItem]
}

@NgModule({
declarations: [],
imports: [
BrowserModule,
CommonModule
],
exports: [NgGrid, NgGridItem]
})
export class Ng2FlexboxGridModule {}





UPDATE - Solution

With the help of @Clint I could bring that baby home.

Probably the biggest problem was that I wasn't aware of how exactly
@NgModule
works. And I'm pretty sure it would have helped if I had carefully read the
@NgModule
docs


The important part though is to declare and export the modules directives. With that you just have to import the
FlexboxGridModule
to use it's exported directives.

Export:

import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {NgGrid, NgGridItem} from './src/directives';

@NgModule({
imports: [BrowserModule],
declarations: [NgGrid, NgGridItem],
exports: [NgGrid, NgGridItem]
})
export class FlexboxGridModule {}


Import:

import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';

import {AppComponent} from './app.component';
import {FlexboxGridModule} from "ng2-flexbox-grid";

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

Answer

You need to have an NgModule in your project. Your Module should then export all the modules which declare your directives that you wish to expose. I have made an angular 2 component library that does exactly this. It's fairly simple, I suggest you take a look.

https://github.com/cpamp21/ng-bcomponents

If you're curious about the change from no modules to using modules, you can review this commit

https://github.com/cpamp21/ng-bcomponents/commit/f619d48de7fff35012660229a8bd43244d38baa2

UPDATE

You inject the module BrowserModule when your component uses directives such as ngModel, ngIf, ngFor, etc. Actually, BrowserModule exports CommonModule so you really only need the BrowserModule.

When you make a module, you should be sure that it imports the modules and declares the components that it uses. In your code your declarations property has an empty array. It should look like this:

declarations: [NgGrid, NgGridItem],

I think your main problem is how you are consuming the library. In the project where you consume Ng2FlexboxGridModule all you need to do is add Ng2FlexboxGridModule to your imports, you should not add the directives from within the module to your declarations.