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
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")
}
}
}
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=.
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.
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:
- Compilation using
compile<Name>Angular
task - Dependency management using
<name>Angular
configuration
Where name is camel case angular project name as defined in angular.json.
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.
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'
}
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).
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
}
}
}
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 )