Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 7 library - how to bundle dependencies without adding them to the main app

I have an Angular 7 application that I created with the @angular/cli and then I added a library to using ng generate library. It works fine in dev mode and such. There's no problems.

I'd like to keep the dependencies that are relevant to the library contained to it; And not clutter up the main application's package.json. So, naturally, I did npm install --save [xyx] to the library folder. That worked fine. Still runs great in dev mode.

But when I try to do ng build --prod, suddenly it can't find the dependencies that are part of the library. The reason why is obvious, of course; They're not being properly bundled in. I've investigated npm's bundleDependencies feature to no avail, and I've looked at the lib: { embedded: ... } and whitelistedNonPeerDependencies option for ng-package.json, but I can't seem to make any of them do quite what I want.

This isn't a make or break requirement; If it's absolutely mandatory, I will just install the dependencies in the main application. But I'd very much like to avoid that. Perhaps it's an unreasonable goal, I am unsure.

Any help would be greatly appreciated.

like image 435
Ciel Avatar asked Dec 06 '18 19:12

Ciel


People also ask

Which file contains the dependency version of Angular libraries used in your app?

Angular packageslink The following Angular packages are included as dependencies in the default package. json file for a new Angular workspace.

What is difference between package and library in Angular?

The package is simply a namespace. The package also contains sub-packages inside it. Library: The library is having a collection of related functionality of codes that allows you to perform many tasks without writing your code.


Video Answer


1 Answers

I tried to do what you described locally and didn't have an issue. Here were the steps I took.

  1. npm install @angular/cli
  2. node_modules/.bin/ng new installtest
  3. cd installtest
  4. node_modules/.bin/ng generate library libtest
  5. cd projects/libtest
  6. npm install --save numeral
  7. npm install --save-dev @types/numeral
  8. added ro.pipe.ts to projects/libtest/src

    import { Pipe, PipeTransform } from '@angular/core';
    
    import * as numeral from 'numeral';
    
    @Pipe({name: 'decimalUnit'})
    export class RoPipe implements PipeTransform {
      constructor() {
        numeral.register('locale', 'ro', {
            delimiters: {
                thousands: '.',
                decimal: ','
            },
            abbreviations: {
                thousand: 'k',
                million: 'm',
                billion: 'b',
                trillion: 't'
            },
            ordinal: function (number) {
                return number === 1 ? 'er' : 'ème';
            },
            currency: {
                symbol: 'RON'
            }
        });
    
        numeral.locale('ro');
    }
    
      public transform(value: string, numDecimals: number) {
        const b = numeral(value);
        let x = '0,0.';
        for (let i = 0; i < numDecimals; i++) {
            x = x + '0';
        }
    
        return b.format(x);
      }
    }
    
  9. update projects/libtest/src/lib/libtest.module.ts

    import { NgModule } from '@angular/core';
    import { LibtestComponent } from './libtest.component';
    import { RoPipe } from './ro.pipe';
    
    @NgModule({
      declarations: [LibtestComponent, RoPipe],
      imports: [
      ],
      exports: [LibtestComponent, RoPipe]
    })
    export class LibtestModule { }
    
  10. update projects/libtest/src/public_api.ts

    export * from './lib/libtest.service';
    export * from './lib/libtest.component';
    export * from './lib/libtest.module';
    export * from './lib/ro.pipe';
    
  11. update tsconfig.json. add "projects/libtest/node_modules/@types" to "typeRoots" array

  12. update src/app/app.module.ts

    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    import { LibtestModule } from 'projects/libtest/src/public_api';
    
    import { AppComponent } from './app.component';
    
    @NgModule({
      declarations: [
        AppComponent
      ],
      imports: [
        BrowserModule,
        LibtestModule
      ],
      providers: [],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    
  13. update src/app/app.component.html

    <label>{{ '12345678' | decimalUnit:2 }}</label>
    <br>
    <label>{{ '12345678' | decimalUnit:0 }}</label>
    <br>
    <label>{{ '12345678' | decimalUnit:2 }}</label>
    <br>
    <label>{{ '12345678' | decimalUnit:2 }}</label>
    <br>
    <label>{{ '12345678' | decimalUnit:2 }}</label>
    

After this, I ran npm run start to verify that it works with the dev build. Next I ran npm run start -- --prod to verify that it works with the prod build. Both worked. The last thing I did was to run npm run build and npm run build -- --prod and loaded the website through IIS, both of which worked. I put the full repo project on GitHub for reference.

You don't really provide an MVCE. So it is hard to tell you why your particular project isn't working at the moment. If the above steps don't work for you, please provide more detail as to what you have tried exactly that is failing(or at least a minimal project that can reproduce the issue you are encountering).

like image 105
peinearydevelopment Avatar answered Oct 24 '22 04:10

peinearydevelopment