Skip to content

Gradle plugin enabling build of angular application/components along side with gradle backend build.

License

Notifications You must be signed in to change notification settings

langrp/gradle-angular-plugin

Repository files navigation

Gradle Angular Plugin

Build Status License Version

This plugin enables you to run build of your backend along side of your angular base frontend. In order to do so the plugin uses NodeJs plugin, which enables additional features. The angular plugin handles:

  • Initialization of new angular project
  • Distribution and versioning
  • Dependency management
  • Artifact publishing

To start using the plugin add this into your build.gradle file.

plugins {
    id "com.palawanframe.angular" version "0.3.2"
}

Based on configuration stage the plugin enables certain tasks. For gradle project without angular files only enables task is

  • angularInit - initializes angular project.

Once angular project is fully initialized the plugin enables full set of tasks:

  • angularCli - task to execute angular cli from gradle. Arguments:
    • cmd - defines one of supported commands 'new', 'generate', etc.
    • args - specifies additional arguments to the command e.g. "library components" to generate new library
  • compileAngular - compiles main angular source set (more below)
  • distZip - wraps compiled main source set into zip file
  • publishToNodeModules - publishes main angular source set into specified node_modules directory

Configuring Plugin

You can configure basic extension block of NodeJs plugin with additional parameters as shown below. The plugin extends NodeJs parameters for simple configuration, but you can still use node extension block.

angular {
    // Node module group used as parent folder in node_modules directory for all dependencies,
    // default uses gradle project group
    group = "com.palawanframe.sample"

    // Angular build output location, default '${buildDir}/angular/main' 
    output = "${buildDir}/resources/main/static/ng"

    // Angular CLI version for initialization of the project. If omitted the latest will be used
    version = "8.3.17"

    node {
        // The rest of NodeJs parameters
        version = "12.13.1"
        download = true
        workingDir = rootProject.file(".gradle/nodejs")
        
        npm {
            version = "6.13.1"
            workingDir = rootProject.file(".gradle/npm")
        }
    }
}

Initialize Project

Once gradle project is configured with above parameters the plugin can initialize angular project. This will happen using angular CLI command of ng new. The task supports basic parameters of CLI, in which the style parameter is mandatory to create new angular application. If omitted only angular CLI will be initialized in NodeJs project.

./gradlew ngInit --style=scss --routing --skipGit

This task will create file structure of NodeJs project with angular cli and quick shell scripts npm and ng depending whether local copy of node needs to be downloaded. From here we initialize angular project using cli

./ng new application --directory=.

Gradle Structure

Still incubating feature

Structures angular project into multi project build where main application would be placed in specific directory, similarly to gradle structure. This allows to multi project build with main angular application, libraries as well as backend projects, all built from single command. Use additional parameter mainProject on angularInit task.

./gradlew ngInit --style=scss --routing --skipGit --mainProject=frontend-app
./gradlew ng --cmd generate --args library --args components

The task will initialize structure for main angular application called frontend-app and place it into same named directory. All necessary files will be moved along with update on angular.json file. Adding additional angular libraries/application will be placed next to the main application (notice library directory components).

project
├─── gradle
├─── node_modules  
├─── components
|    ├─── src
|    ├─── karma.conf.js
|    └─── ng-package.json
├─── frontend-app
│    ├─── e2e
|    ├─── src
|    |    karma.conf.js
│    │    tsconfig.app.json
|    |    tsconfig.spec.json
│    └─── tslint.json
│   ng
|   npm
│   angular.json
|   package.json
└───README.md

For multi project builds the node dependencies can and should be shared across all applications and components. As such the top level gradle project will handle node dependencies of NodeJs plugin. Every angular build depends on the node configuration build steps. It may seem blocked for the first build, but any other execution will be faster.

Source Set

The plugin works with source set container for each angular project, which is not managed as gradle project. This does not require to define gradle project for each angular project, but rather use source sets only. Those source sets are initialized automatically by the plugin. Each source set supports:

  1. Compilation using compile<Name>Angular task
  2. Dependency management using <name>Angular configuration

Where name is camel case angular project name as defined in angular.json.

Versioning

The plugin can modify NodeJs descriptor file package.json to define version as defined in gradle project. The file will be modified only when gradle project version changes.

Dependency Management

The plugin manages dependencies specific to angular project to allow modularization of an application. You can create gradle multi-project with angular libraries and main angular application, in which main application depends on libraries built by other gradle projects. Or publish your library into your repository and depend on the artifact.

dependencies {
    angular project( ':product-page' )
    angular 'com.palawanframe.sample:components:1.0.0'
}

Before the project would be built, gradle resolves all dependencies and publish them into node_modules directory for angular build.

Angular lazy loading of library modules can also be supported without use of wrapper modules (aot build). Such approach requires library source code to be part of the build. How to publish component source and depend on it for lazy loading build is show below (note for successful compilation the tsconfig paths and include must be updated).

import org.gradle.api.internal.artifacts.dsl.LazyPublishArtifact

task sourcesNg(type: Zip) {
    from project.angular.sources.main.directory
    archiveClassifier.set( 'sources' )
}

configurations {
    nodeSources {
        outgoing.artifacts.add(new LazyPublishArtifact(tasks.named('sourcesNg')))
    }
}

project( ':main-app' ) {
    dependencies {
        angular 'com.palawanframe.sample:components:1.0.0'
        angular 'com.palawanframe.sample:lazy-module:1.0.0:sources@zip'
        angular project( path: ':lazy-page', configuration: 'nodeSources' )
    }
}

The plugin works with source set container for each angular project, which is not managed as gradle project. This does not require to define gradle project for each angular project, but rather use source sets only. Those source sets are initialized automatically by the plugin. To define specific dependency for angular project called 'product-page' the following can be used:

dependencies {
    productPageAngular 'com.palawanframe.sample:first-product:1.0.0'
}

Distribution

Gradle distribution plugin is being used to wrap compiled angular code for publishing. As such the task <name>DistZip can be executed to generate zip file, where name is source set name (for main source set distZip task is registered).

Artifact Publishing

The plugin uses Distribution plugin to produce artifact output for each source set defined. The plugin works only with zip files therefore tar tasks are disabled to not produce any files. Example of maven publish configuration.

publishing {

    publications {
        maven(MavenPublication) {
            from components.angular
        }
    }
}

Java Resource Component

For some application may be required to manage angular resources inside dependent jar file or along side of java backend implementation. For this purpose the angular output can be redirected to java resource directory as shown on example below.

plugins {
    id 'java'
    id 'com.palawanframe.angular'
}

angular {
    output = "${buildDir}/resources/main/static/ng"
}

jar.dependsOn( compileAngular )

About

Gradle plugin enabling build of angular application/components along side with gradle backend build.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published