Understanding the Build System
Our build system combines Gradle for Java compilation and module packaging with npm/webpack for frontend assets.
Build Architecture
Project Structure
example-component-library/
├── build.gradle.kts # Root build configuration
├── settings.gradle.kts # Project structure
├── common/ # Shared code
├── designer/ # Designer-specific code
├── gateway/ # Gateway-specific code
└── web/ # Frontend assets
Gradle Configuration
Root Build File
build.gradle.kts
plugins {
id("io.ia.sdk.modl") version "0.3.0"
}
ignitionModule {
// Module definition
name.set("Example Component Library")
fileName.set("Example-Component-Library.modl")
id.set("dev.kgamble.perspective.examples")
// Project scope mapping
projectScopes.putAll(
mapOf(
":gateway" to "G",
":designer" to "D",
":common" to "GD"
)
)
}
Understanding Scopes
- G: Gateway-only code
- D: Designer-only code
- GD: Shared between Gateway and Designer
Version Management
We use Gradle's version catalog for dependency management:
gradle/libs.versions.toml
[versions]
ignition = "8.1.44"
[libraries]
ignition-common = { module = "com.inductiveautomation.ignitionsdk:ignition-common", version.ref = "ignition" }
ignition-designer-api = { module = "com.inductiveautomation.ignitionsdk:designer-api", version.ref = "ignition" }
Frontend Build Configuration
Webpack Setup
web/webpack.config.js
module.exports = {
entry: "./src/index.ts",
output: {
filename: "ExampleComponents.js",
path: resolve("build/generated-resources"),
},
module: {
rules: [
{
test: /\.(ts|tsx)$/,
use: "ts-loader",
},
],
},
};
NPM Scripts
web/package.json
{
"scripts": {
"build": "webpack --mode production",
"watch": "webpack --mode development --watch",
"lint": "eslint src/**/*.{ts,tsx}"
}
}
Build Process Explained
1. Frontend Build
The frontend build process:
- Compiles TypeScript
- Bundles components
- Generates resource files
cd web
npm run build
2. Backend Build
Java compilation and resource processing:
- Compiles Java sources
- Processes resources
- Creates JARs
./gradlew build
3. Module Assembly
Final steps:
- Collects all artifacts
- Signs module (if enabled)
- Creates
.modl
file
Resource Handling
Web Resources
gateway/build.gradle.kts
tasks.processResources {
from(project(":web").projectDir.resolve("build/generated-resources"))
}
Static Resources
tasks.processResources {
from("src/main/resources") {
include("images/**")
include("props/**")
}
}
Development Workflow
Hot Reload Setup
-
Start webpack in watch mode:
cd web
npm run watch -
Mount resources in Docker:
docker-compose.ymlvolumes:
- ../web:/web-resources
Module Deployment
Deploy to local gateway:
./gradlew build deployModl
Common Issues
Build Failures
-
Missing Dependencies
Could not resolve: com.inductiveautomation.ignitionsdk:ignition-common
Solution: Check Maven repositories and credentials
-
TypeScript Errors
TS2307: Cannot find module '@inductiveautomation/perspective-client'
Solution: Verify npm dependencies and TypeScript configuration
Resource Issues
-
Resources Not Found
- Check resource paths
- Verify resource mounting
- Check Docker volume mounts
-
Hot Reload Not Working
- Verify webpack watch mode
- Check resource mounting
- Clear browser cache
Best Practices
-
Dependency Management
- Use version catalog
- Keep dependencies updated
- Document version requirements
-
Resource Organization
- Follow consistent structure
- Use clear naming
- Document resource locations
-
Build Performance
- Enable Gradle daemon
- Use build caching
- Optimize webpack configuration
Next Steps
- Learn about adding components
- Understand naming conventions
- Set up local development