💻
Building and hosting a WebApp
  • Getting started
  • Project setup
    • Requirements
    • Files organisation
    • Lerna
    • Linter
    • Prettier
    • GitHook
    • Testing
    • Conclusion
  • Backend
    • Files organisation
    • Environment config
    • Express API
    • Security
    • Database
    • GraphQL
    • User authentication
    • Conclusion
  • Frontend
    • Create React App
    • Files organisation
    • Styles
    • Apollo Hooks
    • Form management
    • User authentication
    • Writing tests
    • Types generation
    • Conclusion
  • DevOps
    • CI/CD
    • AWS
      • Managing secrets
      • Pricing
      • RDS
      • S3
      • Route53
      • CloudFront
      • Serverless
      • Security
      • CloudFormation
    • Conclusion
  • 🚧Stripe payment
  • 🚧File upload
Powered by GitBook
On this page
  • Config folder
  • Making it work on Windows
  • DotEnv file

Was this helpful?

  1. Backend

Environment config

It is common to have multiple environments. For this project, we will have:

  • Local to run on our machine for development.

  • CI for automated tests.

  • Staging to check if everything is working in the cloud. This can also be used to show a feature to someone before pushing it live.

  • Production where we host our app.

Try to keep all environments as similar as possible to each other.

Config folder

Let's create a folder that contains the configurations for each environment. We will also have a shared.tsfile for things common to all environment and index.ts to return the correct object.

.
└── config
    ├── ci.ts
    ├── index.ts
    ├── local.ts
    ├── production.ts
    ├── shared.ts
    └── staging.ts
import { SharedConfig } from "./shared";
import { local } from "./local";
import { ci } from "./ci";
import { staging } from "./staging";
import { production } from "./production";

export interface Config extends SharedConfig {
  env: "local" | "ci" | "staging" | "production";
}

export const config: Config = { local, ci, staging, production }[
  process.env.CONFIG_ENV || "local"
];
export interface SharedConfig {
  logLevel: string;
}

export const sharedConfig = {
  logLevel: process.env.LOG_LEVEL || "info" // we will come back to logs later
};
import { sharedConfig } from "./shared";
import { Config } from "./index";

export const local: Config = {
  ...sharedConfig,
  env: "local"
};
import { sharedConfig } from "./shared";
import { Config } from "./index";

export const ci: Config = {
  ...sharedConfig,
  env: "ci"
};
import { sharedConfig } from "./shared";
import { Config } from "./index";

export const staging: Config = {
  ...sharedConfig,
  env: "staging"
};
import { sharedConfig } from "./shared";
import { Config } from "./index";

export const production: Config = {
  ...sharedConfig,
  env: "production"
};

For now, there isn't much difference between our files. It will grow as we start adding features.

Note that we use CONFIG_ENV instead of NODE_ENV. This is because some libraries and node itself behave differently when you set NODE_ENV=production. We want our environment to be as close as possible to each other.

Let's try this out:

index.ts
import { config } from './config';

console.log(config);
$ cd packages/api
$ CONFIG_ENV=staging LOG_LEVEL=error ts-node src/index.ts
{ logLevel: 'error', env: 'staging' }
$ CONFIG_ENV=ci LOG_LEVEL=debug ts-node src/index.ts
{ logLevel: 'debug', env: 'ci' }

Never commit secrets to git. Always use environment variable.

Making it work on Windows

We want each member of the team to be able to work in the environment they are the most comfortable. Most developers in the industry are using MacOS but this doesn't mean we should ignore other operating system.

$ cd packages/api
$ yarn add cross-env

This should now work everywhere:

$ cross-env CONFIG_ENV=ci LOG_LEVEL=debug ts-node src/index.ts

DotEnv file

As our app growths, we will have to set more and more environment variables. To keep this clean, we will store them in a .env file.

packages/api/.env
CONFIG_ENV=local
LOG_LEVEL=debug
$ cd packages/api
$ yarn add dotenv
index.ts
require('dotenv').config();
import { config } from './config';

console.log(config);
$ ts-node src/index.ts
{ logLevel: 'debug', env: 'local' }

Don't forget to add .env to .gitignore as it will contain secrets.

PreviousFiles organisationNextExpress API

Last updated 5 years ago

Was this helpful?

The library allows us to run the same command on Unix and Windows.

branch available on GitHub.

cross-env
environment