A webpack plugin injecting a runtime configuration module based on provided configuration parameters.
Can be used to ensure that a built app contains placeholder variables in the built bundle which can be changed prior to runtime to allow for multi-environment configurations where the configuration parameters are not yet known at build time.
To begin, you'll need to install runtime-configuration-module-webpack-plugin
:
npm install runtime-configuration-module-webpack-plugin --save-dev
Also, make sure that you're using babel and are having a polyfill for Object.fromEntries
and Object.entries
, e.g. by using
@babel/preset-env
with the useBuiltIns
option:
.babelrc.json
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": 3
}
]
]
Then add the plugin to your webpack
config. For example:
index.js
import config from 'runtime-config';
webpack.config.js
module.exports = {
plugins: [new RuntimeConfigurationModulePlugin(options)],
};
And run webpack
via your preferred method.
Type: string
Default: runtime-config.js
The name of the module that will export the configuration parameters.
This name must end with .js
.
Type: array
Default: []
List of configuration parameters that should be supported. By default, values for these parameters are searched for as environment variables.
webpack.config.js
Configure the plugin by defining all parameters you wish to have configurable at runtime.
module.exports = {
plugins: [
new RuntimeConfigurationModulePlugin({
parameters: ['MY_SERVICE_URL', 'SECOND_PARAMETER'],
moduleName: 'another-module-name.js',
}),
],
};
webpack.config.js
import RuntimeConfigurationModulePlugin from 'runtime-configuration-module-webpack-plugin';
module.exports = {
plugins: [
new `RuntimeConfigurationModulePlugin`Plugin({
parameters: ['MY_SERVICE_URL', 'SECOND_PARAMETER'],
})
]
};
index.js
import config from 'runtime-config';
console.log(config.MY_SERVICE_URL);
bundle.js
When building and MY_SERVICE_URL
is set as an environment variable like
export MY_SERVICE_URL=https://example.org/api
console.log(config.MY_SERVICE_URL);
// --> will output https://example.org/api
console.log(SECOND_PARAMETER);
// --> will be undefined as not set as an environment variable
bundle.js
will contain a placeholder for SECOND_PARAMETER
that looks
like this ${SECOND_PARAMETER}
and can be replaced with any regex tool
or envsubst or simple plain sed like the following:
export SECOND_PARAMETER="Hello World!"
# use indirect parameter expansion (providing variable name as string and still expanding it)
# use ; as delimiter for sed expression as / maybe contained in urls
sed -i -e "s;\${SECOND_PARAMETER};${!SECOND_PARAMETER};g" bundle.js
# --> will set config.SECOND_PARAMETER to "Hello World!"
Since the configuration module injected by this plugin will be virtual, it will not actually exist on disk and will thus not work in code that is not running through webpack, like e.g. tests. This is why you will need to mock the runtime configuration module in your test as virtual.
E.g. when using [jest], mocking a virtual module can be done using the third parameter
of the jest.mock
function, like:
jest.mock(
'../runtime-config',
() => ({
MY_SERVICE_URL: 'http://mocked.org',
SECOND_PARAMETER: 'some test value',
}),
{ virtual: true } // <-- this is the relevant third parameter
);