Next.js: The test NODE_ENV isn't being set properly

Created on 12 Sep 2020  路  6Comments  路  Source: vercel/next.js

Bug report

Describe the bug

Currently, Next.js only supports three different values for process.env.NODE_ENV (as documented here): development, production, and test.

When running NODE_ENV='test' next build, Next.js loads the right .env.test files but fails to properly replace process.env.NODE_ENV references with test (instead of production).

Previous issues (e.g. #9123, #12772) have requested support for more environment variables. This is not what this issue is about. This is an issue with behaviour that Next.js has already documented as supported (e.g. @Timer says that test is supported in this comment).

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. Clone this repository:
$ git clone https://github.com/nicholaschiang/env-demo && cd env-demo
  1. Install dependencies:
$ yarn install
  1. Build the app using the test environment:
$ yarn test:build
  1. Start the app using the test environment:
$ yarn test:start
  1. Visit the API route at http://localhost:3000/api/env and notice that the JSON response contains production instead of test. This is because Next.js hardcodes (i.e. replaces) the process.env.NODE_ENV variable to production when running next build. This is not ideal when you want to use the NODE_ENV variable to trigger certain behavior during tests (e.g. accessing different Algolia search indexes).

Expected behavior

When running next build with the NODE_ENV set to test, Next.js should properly replace process.env.NODE_ENV references with test instead of production.

System information

  • OS: PopOS 20.x
  • Version of Next.js: 9.5.3
  • Version of Node.js: 12.18.3

Additional context

This can be used to switch between outside resources (e.g. using a different set of Algolia indexes than the ones used in production) during tests. While this might not be ideal, it's required when running integration tests for me (because I can't easily stub out Algolia's search capabilities).

bug

Most helpful comment

@timneutkens that makes sense. Thus, Next.js enforces production during next build to avoid any of those performance de-optimizations. But then why does Next.js even support NODE_ENV='test'? What is it's intended use case?

Right now, I've got my Cypress integration tests working by:

  1. Setting NODE_ENV='test' during next build and next start. This enables me to load .env.test and .env.test.local files which include different API keys (e.g. for Firebase Authentication which doesn't have a local emulator) than production and development (e.g. so that development changes don't effect tests).
  2. Setting an APP_ENV='test' variable (within the .env.test file) to reference within back-end code and switch between different Algolia indexes (i.e. using test-users instead of production-users or development-users).

By "fixing" this issue, would Next.js no longer load the .env.test files during next build and next start? Because that would break my current use case.

All 6 comments

Current workaround is to just use an APP_ENV variable as recommended here.

Running NODE_ENV='test' next build should still load the production env, not test. This seems to be the bug! We'll fix this in Next.js 10.

@Timer you know that's not what I'm saying, right?

I want Next.js to load the .env.test files, not the .env.production files. I just want it to maintain consistency and also replace process.env.NODE_ENV with test instead of production.

Using the development server (i.e. NODE_ENV='test' next dev) during tests is problematic because:

  1. During development, React error overlays prevent Cypress from focusing and interacting with the app. Admittedly, there shouldn't be any errors to show, but that isn't what integration tests are supposed to be testing.
  2. The development server is much slower than using a combo of next build and next start (e.g. statically optimized pages aren't statically optimized and take a long time to load).
  3. IMO integration tests should run on an as-close-to production app as possible.

Also, doesn't Next.js enforce NODE_ENV='development' when running next dev too (just like how it enforces NODE_ENV='production' when running next start or next build)? If so, when are we supposed to use NODE_ENV='test'?

process.env.NODE_ENV only has 2 possible values development and production. If this is not set to that value you'll run into all kinds of library edge cases (especially in node_modules) where you get severely de-optimized results. E.g. if you run a performance test you'll get significantly worse results if process.env.NODE_ENV is not set to production

@timneutkens that makes sense. Thus, Next.js enforces production during next build to avoid any of those performance de-optimizations. But then why does Next.js even support NODE_ENV='test'? What is it's intended use case?

Right now, I've got my Cypress integration tests working by:

  1. Setting NODE_ENV='test' during next build and next start. This enables me to load .env.test and .env.test.local files which include different API keys (e.g. for Firebase Authentication which doesn't have a local emulator) than production and development (e.g. so that development changes don't effect tests).
  2. Setting an APP_ENV='test' variable (within the .env.test file) to reference within back-end code and switch between different Algolia indexes (i.e. using test-users instead of production-users or development-users).

By "fixing" this issue, would Next.js no longer load the .env.test files during next build and next start? Because that would break my current use case.

The env loading behavior should definitely stay as it is currently.

Initially I wasn't that happy about using APP_ENV, but I think APP_ENV is truly better for most switching logic in your app. But NODE_ENV is still perfect for loading env vars.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

baldurh picture baldurh  路  74Comments

nvartolomei picture nvartolomei  路  78Comments

matthewmueller picture matthewmueller  路  102Comments

robinvdvleuten picture robinvdvleuten  路  74Comments

poyiding picture poyiding  路  73Comments