• Stars
    star
    1,163
  • Rank 38,760 (Top 0.8 %)
  • Language
    TypeScript
  • Created almost 6 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Extend the Angular CLI's default build behavior without ejecting, e. g. for Angular Elements

ngx-build-plus

Extend the Angular CLI's default build behavior without ejecting:

  • 📄 Extend the default behavior by providing a partial config that just contains your additional settings
  • 📄 Alternative: Extend the default behavior by providing a custom function
  • 📦 Optional: Build a single bundle (e. g. for Angular Elements)
  • ☑️ Inherits from the default builder, hence you have the same options
  • ☑️ Provides schematics for some advanced use cases like webpack externals
  • 🍰 Simple to use
  • ⏏️ No eject needed

Credits

Big thanks to Rob Wormald and David Herges!

Get the right version

  • Angular 6-7/ CLI 6-7: ngx-build-plus@^7
  • Angular 8/ CLI 8: ngx-build-plus@^8.0.0
  • Angular 9/ CLI 9: ngx-build-plus@^9.0.0
  • Angular 10/ CLI 10: ngx-build-plus@^10.0.0
  • Angular 11/ CLI 11: ngx-build-plus@^11.0.0
  • Angular 12/ CLI 12: ngx-build-plus@^12.0.0
  • Angular 13/ CLI 13: ngx-build-plus@^13.0.0
  • Angular 14/ CLI 14: ngx-build-plus@^14.0.0
  • Angular 15/ CLI 15: ngx-build-plus@^15.0.0

Updating to Version 8

ng update ngx-build-plus --force

Breaking Changes

Version 7

  • The switch single-bundle now defaults to false to align with the CLI's default behavior.

Version 9

  • keepPolyfills and keepStyles default to true to avoid misunderstandings.

Schematics and Options

Options

  • ng build --single-bundle: Puts everything reachable from the main entry point into one bundle. Polyfills, scripts, and styles stay in their own bundles as the consuming application might have its own versions of these.

Adding ngx-build-plus

ng add ngx-build-plus

Getting started

This shows a minimal example for getting started. It uses a minimal partial webpack configuration that is merged into the CLI's one. Representative for all possible custom webpack configurations, the used one just leverages the DefinePlugin to create a global VERSION constant during the build.

Please find the example shown here in the sample application in the folder projects/getting-started.

  1. Create a new Angular project with the CLI

  2. Add ngx-build-plus: ng add ngx-build-plus

    Note: If you want to add it to specific sub project in your projects folder, use the --project switch to point to it: ng add ngx-build-plus --project getting-started

    Remark: This step installs the package via npm and updates your angular.json so that your project uses custom builders for ng serve and ng build.

  3. Add a file webpack.partial.js to the root of your (sub-)project:

    const webpack = require('webpack');
    
    module.exports = {
        plugins: [
            new webpack.DefinePlugin({
                "VERSION": JSON.stringify("4711")
            })
        ]
    }
  4. Use the global variable VERSION in your app.component.ts:

    import { Component } from '@angular/core';
    
    declare const VERSION: string;
    
    @Component({
        selector: 'app-root',
        templateUrl: './app.component.html',
        styleUrls: ['./app.component.css']
    })
    export class AppComponent {
        title = 'Version: ' + VERSION;
    }
  5. Start your application with the --extra-webpack-config switch pointing to your partial webpack config:

    ng serve --extra-webpack-config webpack.partial.js -o
    

    If your project is a CLI based sub project, use the --project switch too:

    ng serve --project getting-started -o --extra-webpack-config webpack.partial.js
    

    Hint: Consider creating a npm script for this command.

  6. Make sure that the VERSION provided by your webpack config is displayed.

ngx-build-plus and Angular Elements

While ngx-build-plus can be used in every Angular configuration, it also comes with some schematics automating some scenarios for Angular Elements. More information about can be found here.

Using Plugins

Plugins allow you to provide some custom code that modifies your webpack configuration. In addition to that, they also provide a pre- and a post-hook for tasks that need to take happen before and after bundling. This is an example for an plugin:

export default {
    pre(options) {
        console.debug('pre');
    },
    config(cfg) {
        console.debug('config');
        return cfg;
    },
    post(options) {
        console.debug('post');
    }
}

As this plugin is written with TypeScript you need to compile it.

The config method works like a configHook (see above).

To use a plugin, point to it's JavaScript representation (not the TypeScript file) using the --plugin switch:

ng build --plugin ~dist\out-tsc\hook\plugin

The prefix ~ points to the current directory. Without this prefix, ngx-build-plus assumes that the plugin is an installed node_module.

Using different merging strategies

You can also use plugins to implement different merging strategies. The following plugin demonstrates this:

var merge = require('webpack-merge');
var webpack = require('webpack');

exports.default = {
    config: function(cfg) {
        const strategy = merge.strategy({
            'plugins': 'prepend'
        });

        return strategy (cfg, {
            plugins: [
                new webpack.DefinePlugin({
                    "VERSION": JSON.stringify("4711")
                })
            ]
        });
    }
}

To execute this, use the following command:

ng build --plugin ~my-plugin.js

One more time, the ~ tells ngx-build-plus that the plugin is not an installed node_module but a local file.

Advanced example: Externals and Angular Elements

Please note, that we don't recomment webpack externals anymore for several reasons (better alternatives, Angular now ships without UMD bundles, etc.). Instead we recomment Webpack Module Federation.

This shows another example for using ngx-build-plus. It uses a custom webpack configuration to define some dependencies of an Angular Element as external which can be loaded separately into the browser and shared among several bundles.

If you are not interested into this very use case, skip this section.

The result of this description can be found in the repository's sample directory.

  1. Create a new Angular CLI based project and install @angular/elements as well as @webcomponents/custom-elements which provides needed polyfills:

    npm i @angular/elements --save
    
  2. Expose a component as an Custom Element:

    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule, Injector } from '@angular/core';
    import { createCustomElement } from '@angular/elements';
    
    import { AppComponent } from './app.component';
    
    @NgModule({
        imports: [
            BrowserModule
        ],
        declarations: [
            AppComponent
        ],
        providers: [],
        bootstrap: [],
        entryComponents:[AppComponent]
    })
    export class AppModule { 
    
        constructor(private injector: Injector) {
        }
    
        ngDoBootstrap() {
            const elm = createCustomElement(AppComponent, { injector: this.injector });
            customElements.define('custom-element', elm);
        }
    
    }
  3. Install ngx-build-plus:

    When using Angular >= 7 and CLI >= 7, you can simply use ng add for installing ngx-build-plus:

    ng add ngx-build-plus 
    

    If you are using a monorepo, mention the project you want to install ngx-build-plus for:

    ng add ngx-build-plus --project myProject
    
  4. Add polyfills:

    ng g ngx-build-plus:wc-polyfill --project myProject
    
  5. Execute the externals schematic:

    ng g ngx-build-plus:externals --project myProject
    
  6. This creates a partial webpack config in your project's root:

    module.exports = {
        "externals": {
            "rxjs": "rxjs",
            "@angular/core": "ng.core",
            "@angular/common": "ng.common",
            "@angular/platform-browser": "ng.platformBrowser",
            "@angular/elements": "ng.elements"
        }
    }
  7. Build your application. You can use the npm script created by the above mentioned schematic:

    npm run build:myProject:externals
    
  8. Angular will now be compiled into a scripts.js and can be reused amongs several seperately compiled bundles. Your code is in the main bundle which is quite tiny b/c it does not contain Angular.

Further information about this can be found in my blog here.

Angular Trainings, Consultings, Schulungen

see http://www.softwarearchitekt.at

More Repositories

1

angular-oauth2-oidc

Support for OAuth 2 and OpenId Connect (OIDC) in Angular.
TypeScript
1,832
star
2

angular-crud

TypeScript
283
star
3

module-federation-plugin-example

TypeScript
195
star
4

angular-elements-dashboard

Dynamic Dashboard with Angular Elements and Web Components
CSS
189
star
5

yarp-auth-proxy

C#
171
star
6

angular-microapp

CSS
145
star
7

module-federation-with-angular-dynamic

Dynamic Module Federation with Angular
TypeScript
101
star
8

standalone-example-cli

TypeScript
92
star
9

angular-microfrontend

JavaScript
87
star
10

module-federation-with-angular

Demonstrates webpack 5 Module Federation with Angular and the Angular Router.
TypeScript
72
star
11

angular-ddd

JavaScript
71
star
12

multi-framework-micro-frontend

TypeScript
64
star
13

angular2-oauth2

JavaScript
63
star
14

Angular_MicroApps_Different_Technologies

CSS
56
star
15

module-federation-with-angular-dynamic-workflow-designer

Example for building a plugin-based workflow designer with Angular and Dynamic Module Federation
TypeScript
54
star
16

meta-router

A lightweight and solid approach towards micro frontends (SPAs/ clients for micro services)
JavaScript
44
star
17

strategic-design

Example for using Strategic Design with Angular and Nx
TypeScript
38
star
18

ddd-bk

36
star
19

native-federation-core-microfrontend

TypeScript
36
star
20

federation-demo

TypeScript
28
star
21

monorepo_domains

TypeScript
27
star
22

angular-2-reuse-strategy-sample

TypeScript
26
star
23

multi-framework-version

TypeScript
24
star
24

angular-oauth-oidc

Sample showing how to use Angular with OAuth2 & OIDC
JavaScript
23
star
25

sa-cli

TypeScript
23
star
26

astro-last-minute

Astro
22
star
27

ngUpgrade-without-preparation

TypeScript
22
star
28

native-federation-react-example

TypeScript
21
star
29

schematics-book

HTML
20
star
30

native-federation-vite-angular-demo

TypeScript
19
star
31

microservice-angular-iframe

Creating Angular-Frontends for Microservices
TypeScript
17
star
32

web-components

Examples for using Web Components in Angular
JavaScript
17
star
33

schematics-sample

My Schematics Sample, Updated Version
TypeScript
15
star
34

nx-and-module-federation

TypeScript
15
star
35

angular-without-modules

TypeScript
14
star
36

angular-ssr

TypeScript
14
star
37

module-federation-light

TypeScript
13
star
38

lazy-loading-ng-conf

TypeScript
12
star
39

snake

TypeScript
12
star
40

angular2-aot-webpack2-rollup

TypeScript
12
star
41

angular8

TypeScript
12
star
42

simple-microfrontend-demo

CSS
12
star
43

monorepo-demo

CSS
11
star
44

module_federation_shared_versions

TypeScript
11
star
45

progresive-web-apps-with-angular-2-demo

Showcase for PWA with Angular 2
TypeScript
11
star
46

angular-book

Beispiele von unserem Angular Buch
TypeScript
11
star
47

angular2-pwa-serviceworker-basta2016

JavaScript
10
star
48

demo-nx-standalone

TypeScript
10
star
49

ngconf-angular-elements-workshop

CSS
9
star
50

standalone-example-nx

TypeScript
9
star
51

build-elements

CSS
9
star
52

ivy-potential

JavaScript
9
star
53

DDD_Nx

JavaScript
9
star
54

ngconf-angular-elements-workshop-external

JavaScript
9
star
55

module_federation_nx_mono_repo

TypeScript
9
star
56

sa-nx

TypeScript
9
star
57

modern-arc

TypeScript
8
star
58

angular2-newest-new-router-guards-oauth

TypeScript
8
star
59

angular-oidc-lib

Simple Lib for using OAuth2 and OIDC in Angular
JavaScript
8
star
60

adv-mf-examples

TypeScript
8
star
61

angular2-rc1-sample

TypeScript
7
star
62

nx-module-federation-demo

TypeScript
7
star
63

angular-intro

TypeScript
7
star
64

microapps-hyperlinks

CSS
7
star
65

http-client-demo

CSS
7
star
66

hero-shop

TypeScript
7
star
67

flight-app

TypeScript
7
star
68

nx-angular-demo

TypeScript
7
star
69

toyc

TypeScript
7
star
70

angular2-oauth-oidc-demo

TypeScript
7
star
71

ngUpgrade-aot-sample

TypeScript
6
star
72

schematics-ng-add

TypeScript
6
star
73

workshop-fest-2020-05

JavaScript
6
star
74

standalone-components-elements

TypeScript
6
star
75

schematics-intro

CSS
6
star
76

5-best-practices-angular

JavaScript
6
star
77

ng-upgrade-workshop-starterkit

Starterkit for Angular migration workshop
TypeScript
6
star
78

angularjs_ce

CSS
6
star
79

module-federation-plugin-example-nx

TypeScript
6
star
80

flights-ddd-demo

TypeScript
6
star
81

nx-ddd-demo

TypeScript
6
star
82

signals-component-communication

TypeScript
6
star
83

dynamic-dashboard-with-dynamic-components-sample

TypeScript
5
star
84

angular3-app

TypeScript
5
star
85

basta_2019_angular_best_practices

JavaScript
5
star
86

microfrontend-prototype

JavaScript
5
star
87

ngUpgrade-lite-sample

TypeScript
5
star
88

pwa-show-case

TypeScript
5
star
89

native-federation-core-example

TypeScript
5
star
90

ddd

TypeScript
5
star
91

advanced-routing-angular-days-munich-mar-2017

TypeScript
4
star
92

ngconf-performance

CSS
4
star
93

schematics-ngVikings-2018

CSS
4
star
94

articles

HTML
4
star
95

monorepo_mf

TypeScript
4
star
96

nx_monorepo

JavaScript
4
star
97

angular-elements-ngconf-2019

CSS
4
star
98

angular-architecture-ngHamburg-march-2018

CSS
4
star
99

ng-upgrade-workshop-solution

Solution for my Angular Migrating Workshop (Migrating to Angular 2) from ngEurope
TypeScript
4
star
100

webpack_5_module_federation_and_angular_cli

TypeScript
4
star