From 62f84bb1ea2ad79cad7af959fa82037fa9c2e52a Mon Sep 17 00:00:00 2001 From: Peter Kellner Date: Wed, 27 Feb 2019 03:18:04 -0800 Subject: [PATCH] Create example for adding env variables from next.js.config / Final (#6318) * This is a non-working example of using PHASE_DEVELOPMENT_SERVER and PHASE_PRODUCTION_SERVER in production. I followed @timneutkens gist but was unable to make it work so I've boiled it down into this non-working example which I believe is the same. The README is not updated. Once it is figured out why this is not working, I'll clean up the project and update the pull request to be complete but for now just want to make it work. * added .eslintrc so that ` eslint . --fix` would work (not sure if that was really necessary). I assume that is same as `yarn lint-fix`. * fixes for standard style * fixes for standard style * Fix example and add some comments * Updated documentation and small change to logic of prod,dev,staging to work as expected. Added significantly more doc then I normally would in the hopes that it helps someone avoid the mis-understanding I went through. If it's too much, LMK and I'll reduce. * removed eslint and updated package.json to get rid of eslint and standardjs --- .../with-env-from-next-config-js/README.md | 70 +++++++++++++++++++ .../next.config.js | 36 ++++++++++ .../with-env-from-next-config-js/package.json | 15 ++++ .../pages/index.js | 9 +++ 4 files changed, 130 insertions(+) create mode 100644 examples/with-env-from-next-config-js/README.md create mode 100644 examples/with-env-from-next-config-js/next.config.js create mode 100644 examples/with-env-from-next-config-js/package.json create mode 100644 examples/with-env-from-next-config-js/pages/index.js diff --git a/examples/with-env-from-next-config-js/README.md b/examples/with-env-from-next-config-js/README.md new file mode 100644 index 0000000000..be42c79cc9 --- /dev/null +++ b/examples/with-env-from-next-config-js/README.md @@ -0,0 +1,70 @@ +[![Deploy to now](https://deploy.now.sh/static/button.svg)](https://deploy.now.sh/?repo=https://github.com/zeit/next.js/tree/master/examples/with-dotenv) + +# With env From next.js.config + +## How to use + +### Using `create-next-app` + +Execute [`create-next-app`](https://github.com/segmentio/create-next-app) with [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) or [npx](https://github.com/zkat/npx#readme) to bootstrap the example: + +```bash +npx create-next-app --example with-env-from-next-config-app +# or +yarn create next-app --example with-env-from-next-config-app +``` + +### Download manually + +Download the example: + +```bash +curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/with-dotenv +cd with-env-from-next-config +``` + +Install it and run: + +```bash +npm install +npm run dev +# or +yarn +yarn dev +``` + +Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download)) + +```bash +now +``` + +## The idea behind this example + +This example demonstrates setting parameters that will be used by your application and set at build time (not run time). +More specifically, what that means, is that environmental variables are programmed into the special configuration file `next.js.config` and then +returned to your react components (including `getInitialProps`) when the program is built with `next build`. + +As the build process (`next build`) is proceeding, `next.config.js` is processed and passed in as a parameter is the variable `phase`. +`phase` can have the values `PHASE_DEVELOPMENT_SERVER` or `PHASE_PRODUCTION_BUILD` (as defined in `next\constants`). Based on the variable +`phase`, different environmental variables can be set for use in your react app. That is, if you reference `process.env.RESTURL_SPEAKERS` +in your react app, whatever is returned by `next.config.js` as the variable `env`, (or `env.RESTURL_SPEAKERS`) will be accessible in your +app as `process.env.RESTURL_SPEAKERS`. + +> ## Special note +> +> `next build` does a hard coded variable substitution into your JavaScript before the final bundle is created. This means +> that if you change your environmental variables outside of your running app, such as in windows with `set` or lunix with `setenv` +> those changes will not be reflected in your running application until a build happens again (with `next build`). + +## Discussion regarding this example + +This example is not meant to be a reference standard for how to do development, staging and +production builds with Next. This is just one possible scenario that could be used if you want the +following behavior while you are doing development. + +* When your run `next dev` or `npm run dev`, you will always use the environmental variables assigned when `isDev` is true in the example. +* When you run `next build` then `next start`, assuming you set externally the environmental variable STAGING to anything but 1, you will get the results assuming `isProd` is true. +* When your run `next build` or `npm run build` in production, if the environmental variable `STAGING` is set to `1`, `isStaging` will be set and you will get those values returned. + +You can read more about this feature in thie blog post Next.js 5.1: Faster Page Resolution, Environment Config and More (under Environment Config). \ No newline at end of file diff --git a/examples/with-env-from-next-config-js/next.config.js b/examples/with-env-from-next-config-js/next.config.js new file mode 100644 index 0000000000..0c4365ff34 --- /dev/null +++ b/examples/with-env-from-next-config-js/next.config.js @@ -0,0 +1,36 @@ +const { + PHASE_DEVELOPMENT_SERVER, + PHASE_PRODUCTION_BUILD +} = require('next/constants') + +// This uses phases as outlined here: https://nextjs.org/docs/#custom-configuration +module.exports = phase => { + // when started in development mode `next dev` or `npm run dev` regardless of the value of STAGING environmental variable + const isDev = phase === PHASE_DEVELOPMENT_SERVER + // when `next build` or `npm run build` is used + const isProd = phase === PHASE_PRODUCTION_BUILD && process.env.STAGING !== '1' + // when `next build` or `npm run build` is used + const isStaging = PHASE_PRODUCTION_BUILD && process.env.STAGING === '1' + + console.log(`isDev:${isDev} isProd:${isProd} isStaging:${isStaging}`) + + const env = { + RESTURL_SPEAKERS: (() => { + if (isDev) return 'http://localhost:4000/speakers' + if (isProd) { return 'https://www.siliconvalley-codecamp.com/rest/speakers/ps' } + if (isStaging) return 'http://localhost:11639' + return 'RESTURL_SPEAKERS:not (isDev,isProd && !isStaging,isProd && isStaging)' + })(), + RESTURL_SESSIONS: (() => { + if (isDev) return 'http://localhost:4000/sessions' + if (isProd) return 'https://www.siliconvalley-codecamp.com/rest/sessions' + if (isStaging) return 'http://localhost:11639' + return 'RESTURL_SESSIONS:not (isDev,isProd && !isStaging,isProd && isStaging)' + })() + } + + // next.config.js object + return { + env + } +} diff --git a/examples/with-env-from-next-config-js/package.json b/examples/with-env-from-next-config-js/package.json new file mode 100644 index 0000000000..4c8db2fafe --- /dev/null +++ b/examples/with-env-from-next-config-js/package.json @@ -0,0 +1,15 @@ +{ + "name": "with-env-from-next-config", + "version": "1.0.0", + "scripts": { + "dev": "next", + "build": "next build", + "start": "next start" + }, + "dependencies": { + "next": "latest", + "react": "^16.7.0", + "react-dom": "^16.7.0" + }, + "license": "ISC" +} diff --git a/examples/with-env-from-next-config-js/pages/index.js b/examples/with-env-from-next-config-js/pages/index.js new file mode 100644 index 0000000000..07ba678586 --- /dev/null +++ b/examples/with-env-from-next-config-js/pages/index.js @@ -0,0 +1,9 @@ +export default () => { + return ( +
+ RESTURL_SPEAKERS {process.env.RESTURL_SPEAKERS} +
+ RESTURL_SESSIONS {process.env.RESTURL_SESSIONS} +
+ ) +} -- GitLab