Demonstrates ng-packagr alongside Nx Workspace.
Develop your libraries and applications in a monorepo. Build distribution-ready binaries in Angular Package Format.
This project was generated with Angular CLI version 1.5.0 using Nrwl Nx.
The following transcript documents reproducible steps to set up this project.
First, create an Nx Workspace. This repository was created with the sandbox install script:
$ curl -fsSL https://raw.githubusercontent.com/nrwl/nx/master/packages/install/install-next.sh | bash -s nx-packagedAlternatively, you could convert an existing Angular CLI project to Nx Workspace. Please see the Nx documentation how to do that.
For show-casing and documenting your library, create an Angular app in the Nx Workspace.
$ ng generate app one-app$ ng generate lib one-lib
$ ng generate lib two-lib --ngmoduleLet's generate a component in the Angular library:
$ ng generate component myButton --app=two-libWe also need to export the component through an Angular module in two-lib.module.ts:
import { MyButtonComponent } from './my-button/my-button.component';
@NgModule({
imports: [CommonModule],
declarations: [MyButtonComponent],
exports: [MyButtonComponent]
})
export class TwoLibModule {}And let's also implement some very veeee-ry smart business code in one-lib.ts:
export class OneLib {
public foo(): string {
return "bar";
}
}Now, import the libraries with @nx-packaged/one-lib and @nx-packaged/two-lib in our application.
Add the TwoLibModule to app.module.ts:
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { TwoLibModule } from '@nx-packaged/two-lib';
@NgModule({
imports: [ /* ... */ TwoLibModule],
declarations: [AppComponent],
bootstrap: [AppComponent]
})
export class AppModule {}Use the OneLib class in app.component.ts:
import { Component, OnInit } from '@angular/core';
import { OneLib } from '@nx-packaged/one-lib';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
business: OneLib = new OneLib();
}Wire up all the parts in app.component.html:
<h2>Develop Angular libraries with ng-packagr in a monorepo</h2>
<p>Here is a reusable button component, implemented in a library:</p>
<app-my-button></app-my-button>
<p>Here is reusable business code from a library:</p>
<pre><code>{{ business.foo() }}</code></pre>Run the app with the standard Angular CLI command:
$ ng serveOpen your browser at http://localhost:4200 and you will see "my-button works!" and "bar" printed on the screen.
Add ng-packagr to development dependencies:
$ yarn add --dev ng-packagrFor each library, add a package.json in the library folders.
Here is the example for the first library:
{
"$schema": "../../node_modules/ng-packagr/package.schema.json",
"name": "@nx-packaged/one-lib",
"version": "1.0.0",
"ngPackage": {
"lib": {
"entryFile": "index.ts"
},
"dest": "@nx-packaged/one-lib"
}
}Add a build script to the package.json in the repository root folder:
"scripts": {
"build:libs": "ng-packagr -p libs/one-lib/package.json"
}Now, build the library to its binary representation with the following command:
$ yarn build:libsThe binaries are written to @nx-packaged/one-lib in the repository root folder!
Add a configuration for Angular CLI to build the app from Angular Package Format bundles in the @nx-packaged folder.
The Nx Workspace configuration (by default) builds the app from TypeScript sources in libs/*.
This is a great way to verify that the application works with the distribution-ready binaries:
$ ng build --app one-app-from-packages --prodHowever, it also forces you to re-build the library every time you change the sources!
During development you can now use ng serve for hot-reloading.
On a CI server and in build scripts, you can use the above ng build command to verify the binaries in Angular Package Format!
Relevant configuration in .angular-cli.json:
{
"name": "one-app-from-packages",
"root": "apps/one-app/src",
"outDir": "dist/apps/one-app",
"assets": [
"assets",
"favicon.ico"
],
"index": "index.html",
"main": "main.ts",
"polyfills": "polyfills.ts",
"test": "../../../test.js",
"tsconfig": "../../../tsconfig.packages.json",
"testTsconfig": "../../../tsconfig.spec.json",
"prefix": "app",
"styles": [
"styles.css"
],
"scripts": [],
"environmentSource": "environments/environment.ts",
"environments": {
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
}
}