-
Notifications
You must be signed in to change notification settings - Fork 499
Webpack Usage
Right now node-config
doesn't work with webpack out of the box because it reads the config files at runtime, which can't be done when the code is running on a browser.
If you're using Webpack 4, it includes excellent handling for complex config objects with DefinePlugin
(as of 2018-05-07). Add the following to your webpack.config.js
:
...
plugins: [
new webpack.DefinePlugin({ CONFIG: JSON.stringify(require("config")) })
]
You can access all fields, including nested fields, under the CONFIG
object in your client-side scripts, without exposing your entire config object. Note that you won't have access to get()
.
This approach does work in Webpack 3, but it inserts your entire config object wherever it is referenced. This is not recommended.
Install the config-webpack package and put the following in webpack.config.js
:
const ConfigWebpackPlugin = require("config-webpack");
...
plugins: [
new ConfigWebpackPlugin()
]
This allows you to access your configuration on the client in the global namespace CONFIG
.
console.log(CONFIG.server.url)
You can also change the default namespace from CONFIG
to something else.
new ConfigWebpackPlugin("myConfigObject")
This method performs direct text replacement of config variables in your code with their values, and it doesn't expose any configs that aren't used.
Below is an example of how you can use NODE_ENV
at build time to have a static config built into your webpack bundle.
IMPORTANT NOTE
This will publish your entire config file into your front end application. If you have sensitive information you do not want downloaded, see the notes after the example.
// webpack-config.js
const config = require('config')
const fs = require('fs')
const path = require('path');
// This will take the config based on the current NODE_ENV and save it to 'build/client.json'
// Note: If '/build' does not exist, this command will error; alternatively, write to '/config'.
// The webpack alias below will then build that file into the client build.
fs.writeFileSync(path.resolve(__dirname, 'build/client.json'), JSON.stringify(config))
module.exports = {
// ... other webpack config
resolve: {
alias: {
config: path.resolve(__dirname, 'build/client.json')
}
}
}
Both server and client now can happily use import config from 'config'
.
If you have things in the config that you do not want to publish to the front end, you may consider making a specific client
section of the config, and only publishing that key to the static json file, e.g. import { client } from 'config';
Alternatively you could use lodash pick
or omit
to control what data is written to the file.
Important Notice for Users of Create-React-App The best option for CRA users is this option. The default webpack config for CRA is only allows you to alias files from '/src/' not '/build'. Make this change and it'll function properly.
Another solution is to take advantage of the NODE_CONFIG
environment variable with webpack.DefinePlugin
. With this method you CAN still use get()
.
const config = require('config');
const webpackConfig = {
//webpack plugins config
plugins: [
new webpack.DefinePlugin({
//double stringify because node-config expects this to be a string
'process.env.NODE_CONFIG': JSON.stringify(JSON.stringify(config)),
}),
],
};
If you're using node-config
for node.js backend application, you can simply add it to externals, and read the config at the runtime. This will also allow usage of environment variables or local configuration files, if bundling them is not an option for your app.
You will have to add the config files and node-config
package to the bundle though.
module.exports = {
// ...
externals: {
'config': 'config',
}
};
This plugin hooks into webpacks compilation to replace the config module with its environment equivalent. This eliminates the need to pull config in dynamically at runtime.
yarn add -D node-config-webpack
Your typical usage will replace the config module with an environment specific override. For this usage, just import the plugin and add it to webpack.
webpack.config.js
const NodeConfigWebpack = require('node-config-webpack');
module.exports = {
entry: [
'./src/index.js'
],
plugins: [
new NodeConfigWebpack()
]
}
This option will inject your configuration into process.env
automatically. However, it expects a root-level list of key-pair items, similar to an .env file. Additionally all keys will be coerced into uppercase to match process.env convention.
webpack.config.js
const NodeConfigWebpack = require('node-config-webpack');
module.exports = {
entry: [
'./src/index.js'
],
plugins: [
new NodeConfigWebpack({
env: true,
})
]
}
Example:
console.log('Configuration version is', process.env.VERSION);
If you want the config added to process.env
without any coercion you can use a string for the env
option:
webpack.config.js
const NodeConfigWebpack = require('node-config-webpack');
module.exports = {
entry: [
'./src/index.js'
],
plugins: [
new NodeConfigWebpack({
env: 'CONFIG',
})
]
}
You can then reference your config from process.env.<your_key>
.
Example:
console.log('Configuration is', process.env.CONFIG);
This option will replace any reference to the variable CONFIG
with the generated equivalent.
webpack.config.js
const NodeConfigWebpack = require('node-config-webpack');
module.exports = {
entry: [
'./src/index.js'
],
plugins: [
new NodeConfigWebpack({
constant: true,
})
]
}
Example:
console.log('Configuration version is', CONFIG.version);
You can use a custom constant variable by passing a string as the constant
value.
webpack.config.js
const NodeConfigWebpack = require('node-config-webpack');
module.exports = {
entry: [
'./src/index.js'
],
plugins: [
new NodeConfigWebpack({
constant: 'customValue',
})
]
}
Example:
console.log('Configuration version is', customValue.version);
Known Conflicts
If you are using webpack-node-externals in your webpack configuration, add config
to the allowlist. This will allow node-config-webpack
to work as expected.
Example:
const slsw = require('serverless-webpack');
const nodeExternals = require('webpack-node-externals');
const NodeConfigWebpack = require('node-config-webpack');
process.env.NODE_ENV = slsw.lib.serverless.service.provider.environment.NODE_ENV;
module.exports = {
entry: slsw.lib.entries,
target: 'node',
mode: slsw.lib.webpack.isLocal ? 'development' : 'production',
externals: [nodeExternals({
allowlist: ['config']
})],
plugins: [
new NodeConfigWebpack(),
]
};
Review this page
<>