I’m trying to use command line arguments with the gradle build task to set some behaviours in the build process. My project is React in Kotlin/JS (Legacy compiler, with some Kotlin multi-platform libraries), using build.gradle.kts
, and a JS file under the webpack.config.d/
directory for adding a webpack.EnvironmentPlugin
to the webpack config
Currently, I use ./gradlew browserProductionWebpack -Pmode=PROD
to set Webpack’s mode
to production, and also to set some Webpack Environment Plugin variables to production values, instead of prod. (https://discuss.kotlinlang.org/t/kotlin-js-react-accessing-configuring-environment-variables/16906)
This is fine if I am either developing locally (dev DB target, source maps enabled, minification disabled), or deploying to prod (prod db target, source maps disabled, minification enabled). But I want to be able to deploy to our UAT site which should be prod-like but targeting the dev DB. I also want to be able to enable or disable analytics for a build, so I can have it disabled with some run configurations, but not others.
Essentially my problem is that the only way I know how to change behaviours in the build process is through the use of the Webpack mode, which means I get only 2 options - production or development.
If I was running Webpack directly from the command line I would be able to set environment variables that I could then use to build different configurations (i.e., using Webpack’s --env
command line parameter) to set the DB target separate from the build type separate from e.g. analytics enabled/disabled.
So, is there a way to use more gradle command line parameters to set build variables (the 3 I am thinking of would be -PbundleMode
(for setting Webpack mode), -PenvTarget
for setting the DB target and -Panalytics
for enabling or disabling analytics. Or, is there an alternative way to achieve my goals?
// build.gradle.kts
import ...
val isProdBundle = project.hasProperty("bundleMode") && (project.property("bundleMode") as String).toUpperCase() == "PROD"
val isProdEnv = project.hasProperty("envTarget") && (project.property("envTarget") as String).toUpperCase() == "PROD"
val isAnalyticsEnabled = project.hasProperty("analytics") && (project.property("analytics") as String).toUpperCase() == "true"
buildscript {
...
}
plugins {
...
}
repositories {
...
}
kotlin {
js {
browser {
commonWebpackConfig {
cssSupport.enabled = true
mode = if (isProdBundle) PRODUCTION else DEVELOPMENT
}
// I tried using this to add env variables to the webpack config task
// webpackTask {
// this.args.addAll(listOf(
// "--env ENV_TARGETS=${if (isProdEnv) "prod" else "dev"}",
// "--env production=$isProdBundle",
// "--env ENABLE_ANALYTICS=$isAnalyticsEnabled"
// ))
//}
}
...
}
...
}
dependencies {
...
}
And JS config file file:
// webpack.config.d/firebaseConfig.js
const webpack = require("webpack")
var apiKey;
var projectId;
var appId;
var authDomain;
var databaseUrl;
var storageBucket;
var messagingSenderId;
var measurementId;
var locationApiKey;
var gtmId;
if (config.mode.toLowerCase() === "production") { // the build process makes the config object available
apiKey = ... // Set all above variables to prod values
} else {
apiKey = ... // Set all above variables to dev values
}
const environmentPlugin = new webpack.EnvironmentPlugin(
{
FIREBASE_API_KEY: apiKey,
FIREBASE_PROJECT_ID: projectId,
FIREBASE_APP_ID: appId,
FIREBASE_AUTH_DOMAIN: authDomain,
FIREBASE_DATABASE_URL: databaseUrl,
FIREBASE_STORAGE_BUCKET: storageBucket,
FIREBASE_MESSAGING_SENDER_ID: messagingSenderId,
FIREBASE_MEASUREMENT_ID: measurementId,
LOCATION_API_KEY: locationApiKey,
GTM_ID: gtmId,
}
)
config.plugins.push(environmentPlugin)
Thanks,
Cam