26

I'd like to build my nextjs project as development mode.

and I tried like it

package.json

{
  ...
  "scripts": {
    "dev": "next",
    "build:dev": "set NODE_ENV=development & next build",
    "build:prod": "set NODE_ENV=production & next build",
    "start:dev": "set NODE_ENV=development & next start",
    "start:prod": "set NODE_ENV=production & next start"
  }
  ...
}

next.config.js

module.exports = withSass({
  env: {
    baseUrl: process.env.NODE_ENV === "development" ? "devServerURL": "prodServerURL"
  }
});

but I couldn't achieve what I want.

so, I tried with some change.

package.json

  "scripts": {
    "dev": "next",
    "build": "next build",
    "start:dev": "set NODE_ENV=development & next start",
    "start:prod": "set NODE_ENV=production & next start"
  }

but it also doesn't work.

How can I build the next with development mode?

Thanks in advance.

EDIT

My OS is Windows 10.

brc-dd
  • 10,788
  • 3
  • 47
  • 67
kyun
  • 9,710
  • 9
  • 31
  • 66
  • 2
    According to https://github.com/zeit/next.js/issues/3605, it's not possible in the moment. – StackedQ Aug 08 '19 at 08:21
  • In the contrary, it seems that you cannot set NODE_ENV = production within next dev command – Godev Oct 09 '20 at 13:08
  • Next.js provides the environment you are working on based on how you start it. Note that if you use next dev command it will start the service in development mode. If you next build && next start it will produce a production build. To achieve what you are trying to do use .env.development and .env.production. Those two files will be loaded based on the environment you started. You can use the same variable (SERVER_URL=server.depending.on.environment) and recall it with process.env.SERVER_URL in your code. – Giuseppe Salvatore Feb 11 '21 at 23:21
  • 3
    Wontfixed: https://github.com/vercel/next.js/issues/4022#issuecomment-374010365 ... I'm just gonna create a secondary `NODE_ENV_OVERRIDE` and check for that I think. – Ciro Santilli OurBigBook.com May 24 '21 at 16:46

3 Answers3

9

UPDATE 2022-11-23:

See how-to-set-environment-variables-from-within-package-json.

In short:
"start:dev": "NODE_ENV=development next start"

You might need cross-env (on Windows ? I don't know):
"start:dev": "cross-env NODE_ENV=development next start"

More specific documentation is now available (and maybe requirements also have changed, or maybe not):

environment-variable-load-order:

... Note: The allowed values for NODE_ENV are production, development and test.

non-standard-node-env:

... only permitting three (3) values:

  • production: When your application is built with next build
  • development: When your application is ran with next dev
  • test: When your application is being tested (e.g. jest)

ORIGINAL ANSWER:

See issue #9123, (Oct 18, 2019) :

NODE_ENV is a reserved environment variable that cannot be changed. The only valid values are production, development, and test.

If you need your app behavior to change in different production environments, please use a different variable like APP_ENV.

And issues #17032 (Sep 12, 2020):

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

kca
  • 4,856
  • 1
  • 20
  • 41
  • 1
    Also note that there is an open RFC for adding built-in `APP_ENV` support: https://github.com/vercel/next.js/discussions/25764 – Michael Hays Feb 11 '22 at 19:33
1

Short Answer

  1. Put your dev-env secrets in .env.dev
  2. Put your prod-env secrets in .env.prod
  3. Don't save secrets in .env.local. They will be brought there next.
  4. Add following to your package.json script.
"build-dev": "cp .env.dev .env.local && yarn build",
"build-prod": "cp .env.prod .env.local && yarn build"
  1. Upvote & Enjoy if it worked.

Additionally,

  1. You may want to add a variable APP_ENV.
  2. Set it to development and production based on file.
  3. Access process.env.APP_ENV based on your script invocation.

Keep in mind, process.env.NODE_ENV will always be production in all the 3 scripts above. And don't store your env files in standard format that nextjs's build command can detect. Perhaps use .env.dev, .env.stg, .env.prod

Long Answer

Well this is Mid-2023 and I wish there was a straightforward solution. Here's what works for me coming from React/vite to Nextjs with 2 different environments file.


Using Rodrigo's answer I first renamed

  • .env.development to .env.dev
  • .env.production to .env.prod

so that next.js doesn't pick them automatically during builds but they stay on local system.

If I don't do that then precedence kicks in and picks .env.production during deployment to my dev environment which I don't want.

Next I modified my scripts in package.json as

"build":"yarn build"

"predeploy": "cp .env.dev .env.local",
"deploy": "firebase use development && firebase hosting:channel:deploy dev",

"predeployprod": "cp .env.prod .env.local",
"deployprod": "firebase use production && firebase deploy -P production"

Read about Next JS Precedence Order briefly.

What this does is based on my "invocation" whether I want to deploy to dev/prod env it supplies the right secrets to the .env.local file.

For example, Say I want to deploy to dev. I run yarn deploy -> automatically runs yarn predeploy first setting my dev-secrets to .env.local. Secondly it runs the build.

You might wonder where's nextjs's build command? firebase deploy takes care of that and runs it behind the scene.

If you aren't using firebase following could suffice.

"build-dev": "cp .env.dev .env.local && yarn build",
"build-prod": "cp .env.prod .env.local && yarn build"
KeshavDulal
  • 3,060
  • 29
  • 30
0

We solve it from our pipeline. Basically, when we build the image:

copy ".env.%ENVIROMENT%" to "./.env"

Then, if it finds a .env file, it always uses that.

You need to configure the value of %ENVIROMENT% in each pipeline you use for production or development (or make it recognize which pipeline it is).

If you have different steps during the image build, you could even use different environments for building and running.

Dockerfile example (this is not the best Dockerfile):

FROM node:16.17.3-buster-slim as build

WORKDIR /app
COPY package.json yarn.lock ./
COPY . ./
COPY .env.%ENVFILE_NEXT% ./.env
RUN yarn
RUN yarn build

FROM node:16.17.3-buster-slim as dst

WORKDIR /app

COPY --from=builder /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/public ./public
COPY --from=builder /app/next.config.js ./next.config.js
COPY --from=builder /app/next-i18next.config.js ./next-i18next.config.js
#
COPY .env.%ENVFILE_NEXT% ./.env

EXPOSE 3000
CMD ["yarn", "start"]