I am trying to modify Gatsby's internal Webpack config to add some custom environment variables by leveraging DefinePlugin, which is a Webpack plugin that Gatsby uses to make environment variables available to the application after the Webpack build. I followed the docs on adding custom Webpack configuration which has an example of doing this sort of thing, specifically the first example that involves less-loader. I followed the docs carefully but haven't been able to get it to work. I briefly took a look at the code Gatsby uses to create the Webpack config and could not see a place where this behaviour is taken care of, I could not be looking in the right place.
Open up or create a gatsby-node.js.
Create and export a onCreateWebpackConfig function.
Utilize actions.setWebpackConfig to modify the Webpack config Gatsby uses.
Use plugins.define to add some custom environment variables.
The hook function should look like this:
exports.onCreateWebpackConfig = ({
plugins,
actions
}) => {
const { setWebpackConfig } = actions;
setWebpackConfig({
plugins: [
plugins.define({
THING: "BOB"
})
]
});
};
Inside any source code you should be able to access the custom environment variable you set via process.env. In the example above you should be able to do process.env.THING which would return a value of "BOB".
When calling process.env.THING the value returned is undefined.
System:
OS: macOS 10.14
CPU: (8) x64 Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz
Shell: 5.3 - /bin/zsh
Binaries:
Node: 8.11.2 - /usr/local/bin/node
Yarn: 1.7.0 - /usr/local/bin/yarn
npm: 6.4.1 - /usr/local/bin/npm
Browsers:
Chrome: 70.0.3538.110
Firefox: 63.0.3
Safari: 12.0
npmPackages:
gatsby: ^2.0.64 => 2.0.64
gatsby-plugin-glamor: ^2.0.5 => 2.0.5
gatsby-plugin-google-analytics: ^2.0.7 => 2.0.7
gatsby-plugin-manifest: ^2.0.6 => 2.0.6
gatsby-plugin-netlify: ^2.0.1 => 2.0.1
gatsby-plugin-offline: ^2.0.9 => 2.0.9
gatsby-plugin-react-helmet: ^3.0.0 => 3.0.0
gatsby-plugin-robots-txt: ^1.3.0 => 1.3.0
npmGlobalPackages:
gatsby-cli: 2.0.0-rc.5
gatsby: 2.0.64
According to https://webpack.js.org/plugins/environment-plugin/#usage it probably should be:
'process.env.THING': JSON.stringify('BOB')
Thanks @LekoArts! I'll give that a try, nonetheless the example in the docs should work out of the box? Maybe we should consider updating the docs if your solution is indeed correct.
You don't define env variables with DefinePlugin - see https://webpack.js.org/plugins/define-plugin/
If you define THING then you need to use THING (not process.env.THING)
Ah thanks @pieh! Will close this issue!
Also you should use double quotes or JSON.stringify there for value if your definition:
Note that because the plugin does a direct text replacement, the value given to it must include actual quotes inside of the string itself. Typically, this is done either with alternate quotes, such as '"production"', or by using JSON.stringify('production').
@LekoArts @RobertWSaunders the document is correct!
That plugin doesn't define "environment variables" but rather it exposes string replacement based on the key you give, e.g. THING.
In the example you give up front
exports.onCreateWebpackConfig = ({
plugins,
actions
}) => {
const { setWebpackConfig } = actions;
setWebpackConfig({
plugins: [
plugins.define({
THING: "BOB"
})
]
});
};
that will expose "THING" that will be replaced by "BOB" (although note you'll want to JSON.stringify('BOB') to avoid an undefined error.
Wiring it all up, here's gatsby-config.js
exports.onCreateWebpackConfig = ({
plugins,
actions
}) => {
const { setWebpackConfig } = actions;
setWebpackConfig({
plugins: [
plugins.define({
THING: JSON.stringify("BOB") // otherwise you're replacing THING with literal value BOB, which will be undefined
})
]
});
};
Thank you @DSchau, @pieh, and @LekoArts!
Most helpful comment
You don't define env variables with
DefinePlugin- see https://webpack.js.org/plugins/define-plugin/If you define
THINGthen you need to useTHING(notprocess.env.THING)