Gatsby: Custom environment variables set in onCreateWebpackConfig do not get set

Created on 11 Dec 2018  路  7Comments  路  Source: gatsbyjs/gatsby

Description

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.

Steps to reproduce

  1. Open up or create a gatsby-node.js.

  2. Create and export a onCreateWebpackConfig function.

  3. Utilize actions.setWebpackConfig to modify the Webpack config Gatsby uses.

  4. 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"
      })
    ]
  });
};

Expected result

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".

Actual result

When calling process.env.THING the value returned is undefined.

Environment

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
needs reproduction question or discussion

Most helpful comment

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)

All 7 comments

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!

Was this page helpful?
0 / 5 - 0 ratings