Unlocking Multiple Build Environments in Next.js

Unlocking Multiple Build Environments in Next.js

Next.js is a robust framework for creating front-end applications. Nonetheless, support for multiple-build environments is one of its main drawbacks.

Next.js build environments are powered by environment variables, which allow us to configure various settings without hardcoding them. This is particularly helpful for activities like maintaining distinct APIs for development, staging, and production or configuring multiple API endpoints depending on the build type. Next.js uses .env files to differentiate development builds from production builds, which simplifies but also limits configuration.


Why It Matters

Environment variables are essential for configuring settings without hardcoding, especially when dealing with different API endpoints for different stages of your application. Yet, the limitation of just two build environments can create challenges for teams looking to streamline their workflows across multiple deployment scenarios.


Next.js environment loading script

The first step to configuring environment variables is to understand how environment variables can be loaded. It turns out that Next.js has a built-in way to set environment variables at build time through the next.config.js file. Specifically, if a property called env is exported, all of the keys specified will be available in the build as environment variables. This is similar (but not identical) to2 how environment variables are loaded from a .env.development or .env.production file. For example, if we wanted to configure an API_ENDPOINT environment variable, it might look something like the following:

// next.config.js
module.exports = {
  env: {
    API_ENDPOINT: 'https://localhost:1234'
  }
};        
// src/get-weather.ts
export function getWeather() {
  return fetch(`${process.env.API_ENDPOINT}/weather`);
}        

Now, if we wanted a different value API_ENDPOINT based on something like the target environment, we could modify our next.config.js script to include this behavior:

// next.config.js
function getAPIEndpoint() {
  if (process.env.TARGET_ENVIRONMENT === 'production') {
    return 'https://api.example.com';
  }

  if (process.env.TARGET_ENVIRONMENT === 'staging') {
    return 'https://api.staging.example.com';
  }

  return 'https://localhost:1234'
}

module.exports = {
  env: {
    API_ENDPOINT: getAPIEndpoint()
  }
};        


The above example is a good illustration of how we might set different environment variable values based on the environment, but the syntax is a bit verbose and cumbersome. We can improve on this by mimicking the existing environment variable patterns. We would do this by:

  1. Specifying an env/.env.{environment} file for each environment (env/.env.development, env/.env.staging, etc…)3
  2. Reading the appropriate file based on the environment using the Node.js fs package.
  3. Parsing the file using the dotenv package
  4. Exporting the results through the env key in next.config.js

The result will look something like this:

.
├── env
│?? ├── .env.demo
│?? ├── .env.development
│?? ├── .env.production
│?? └── .env.staging
├── src
│   └── ...
│
├── next.config.js
└── package.json        
// next.config.js
const dotenv = require('dotenv');
const fs = require('fs');
const path = require('path');

function loadTargetEnv(target) {
  // Constructs a path such as env/.env.development
  const envPath = path.join(__dirname, 'env', `.env.${target}`);
  return dotenv.parse(fs.readFileSync(envPath));
}

module.exports = {
  env: loadTargetEnv(process.env.TARGET_ENVIRONMENT)
};        

Conclusion

While Next.js doesn’t provide default support for multiple environments, it’s possible to emulate the exact desired behavior by leveraging its configurable build process. Here, we’ve outlined a very basic script to load environment variables, but this process can be as customizable as your application needs!

  1. Next.js also supports a third build type specifically for automated test environments. See the documentation for .env.test.???
  2. See the documentation for the env property to see how it differs from loading variables via .env files???
  3. The .env files are being placed in an env/ directory so that the default Next.js behavior for .env files are avoided.???

要查看或添加评论,请登录

Satya Ranjan Sharma的更多文章

  • Introduction

    Introduction

    As TypeScript continues to grow in popularity and strength, becoming an indispensable part of improving the library…

社区洞察

其他会员也浏览了