Hello, newcomer here. I’m learning KotlinJS, and I have a problem setting environment variables.
1. My requirement
Basically, I want to set different variables such as the backend url depending on the environment (PROD, DEV, but also TEST and so on.)
2. The advice I found
I tried following the advice here :
https://discuss.kotlinlang.org/t/kotlin-js-react-accessing-configuring-environment-variables/16906/9
and here :
https://gist.github.com/CameronProbert/85b7d60fa9572d93566f5c5ee62441e0
However, this does not seem to work anymore with the latest versions of Kotlin JS and webpack.
I’ll start with a summary of the recommended method from those topics, so you do not have to read them.
I have to use Webpack. I can send the environment as a command line parameter to webpack (adapted to Webpack 5) :
val envTargetWebpackArgs = listOf("--env", "envTarget=$env")
webpackTask { args.plusAssign(envTargetWebpackArgs) }
runTask { args.plusAssign(envTargetWebpackArgs) }
Then I can read it in webpack.config.js. As mentionned in the documentation here : https://webpack.js.org/guides/environment-variables/ this is done by replacing the module.exports = config line to export a function instead :
module.exports = (env) => {
// ...
return config;
}
Finally, with KotlinJS I do not make a webpack.config.js myself beacuse KotlinJS will generate it. Instead I have to create a directory called webpack.config.d at the root of the project, and any js file I put there will be added to webpack.config.js .
3. What I did
I created a file, webpack.config.d/env.js (sorry about the length, I abbreviated it but removing more might make you think the problem is simpler than it is) :
module.exports = env => {
const webpack = require("webpack");
let appConfig;
switch(env.envTarget) {
case 'PROD':
appConfig = {
'appConfig': {
envName: JSON.stringify(env.envTarget),
serverRootUrl: JSON.stringify("backend.url.com")
}
};
break;
// Many more cases.
default:
appConfig = {
'appConfig': {
envName: JSON.stringify(env.envTarget),
serverRootUrl: JSON.stringify("localhost:8080")
}
};
break;
}
config.plugins.push(new webpack.DefinePlugin(appConfig));
return config;
}
4. The problem
When I tried it it did not work. I looked around, and found the problem in the generated webpack.config.js file. Here is the relevant part :
module.exports = env => {
const webpack = require("webpack");
let appConfig;
switch(env.envTarget) {
case 'PROD':
appConfig = {
'appConfig': {
envName: JSON.stringify(env.envTarget),
serverRootUrl: JSON.stringify("backend.url.com")
}
};
break;
// Many more cases.
default:
appConfig = {
'appConfig': {
envName: JSON.stringify(env.envTarget),
serverRootUrl: JSON.stringify("localhost:8080")
}
};
break;
}
config.plugins.push(new webpack.DefinePlugin(appConfig));
return config;
}
module.exports = config
As you can see, KotlinJS properly copied my code from env.js, but since it adds the line module.exports = config at the end, all my changes are ignored ! I tried to find a workaround, to no avail. Exporting a function instead of the config is the only way to access the variables from the webpack config file, and the way KotlinJs generates it, it’s not an option.
5. My questions
Do you know of a workaround that would let me use environment variables in Webpack ? Or is there another way entirely to set environment variables such as the backend url ?