node.js - používanie process.env v TypeScripte


Ako čítam premenné prostredia Node v TypeScripte?

Ak použijem process.env.NODE_ENV, dostanem túto chybu :

Property 'NODE_ENV' does not exist on type 'ProcessEnv'

Nainštaloval som @types/node, ale nepomohlo to.

Odpoveď č. 1

Akonáhle nainštalujete @types/node vo vašom projekte, môžete TypeScript presne povedať, aké premenné sa nachádzajú vo vašom process.env:

environment.d.ts

declare global {
  namespace NodeJS {
    interface ProcessEnv {
      GITHUB_AUTH_TOKEN: string;
      NODE_ENV: 'development' | 'production';
      PORT?: string;
      PWD: string;
    }
  }
}

// If this file has no import/export statements (i.e. is a script)
// convert it into a module by adding an empty export statement.
export {}

Použitie :

process.env.GITHUB_AUTH_TOKEN; // $ExpectType string

Táto metóda vám poskytne IntelliSense a zároveň využíva typy reťazcových literálov.

Poznámka: vyššie uvedený úryvok je rozšírenie modulu. Súbory obsahujúce rozšírenie modulu musia byť moduly (na rozdiel od skriptov). Rozdiel medzi modulmi a skriptmi je v tom, že moduly obsahujú aspoň jeden príkaz import/export.

Aby TypeScript považoval váš súbor za modul, stačí do neho pridať jeden import. Môže to byť čokoľvek. Dokonca aj export {} stačí.

Odpoveď č. 2

Neexistuje žiadna záruka, aké (ak vôbec nejaké) premenné prostredia budú k dispozícii v procese Node - premenná NODE_ENV je len konvencia, ktorú popularizoval Express, a nie niečo vstavané priamo do Node. Preto by nedávalo príliš zmysel, aby bola zahrnutá v definíciách typov. Namiesto toho definujú process.env takto:

export interface ProcessEnv {
    [key: string]: string | undefined
}

Čo znamená, že process.env môže byť indexovaný pomocou reťazca, aby sa získal reťazec späť (alebo undefined, ak premenná nie je nastavená). Ak chcete opraviť svoju chybu, budete musieť použiť syntax indexu:

let env = process.env["NODE_ENV"];

Alternatívne, ako poznamenal jcalz v komentároch, ak používate TypeScript 2.2 alebo novší, môžete pristupovať k indexovateľným typom, ako je ten definovaný vyššie, pomocou bodkovej syntaxe - v takom prípade by váš kód mal fungovať tak, ako je.

Odpoveď č. 3

len pridajte pred použitím process.env.NODE_ENV nasledujúce riadky:

declare var process : {
  env: {
    NODE_ENV: string
  }
}

Odpoveď č. 4

Na toto môžete použiť typové tvrdenie

Niekedy sa ocitnete v situácii, keď budete o hodnote vedieť viac ako TypeScript. Zvyčajne sa to stane, keď viete, že typ niektorej entity môže byť konkrétnejší ako jej aktuálny typ.

Typové tvrdenia sú spôsob, ako povedať kompilátoru „dôveruj mi, viem, čo robím.“ Typové tvrdenie je ako typové pretypovanie v iných jazykoch, ale nevykonáva žiadne špeciálne kontrolovanie ani prestavbu dát. Nemá žiaden dopad počas behu programu a používa sa čisto kompilátorom. TypeScript predpokladá, že vy, programátor, ste vykonali všetky špeciálne kontroly, ktoré potrebujete.

Príklad

const nodeEnv: string = (process.env.NODE_ENV as string);
console.log(nodeEnv);

Alternatívne môžete zistiť, že knižnica ako env-var je pre tento konkrétny účel vhodnejšia --

riešenie pre načítanie a čistenie environmentálnych premenných v node.js so správnymi typmi

Odpoveď č. 5

1. Vytvorte súbor .env

Contents of .env file
AUTHENTICATION_API_URL="http://localhost:4000/login"
GRAPHQL_API_URL="http://localhost:4000/graphql"

2. Načítajte svoj súbor .env do process.env pomocou dotenv

Môžeme využiť dotenv na nastavenie špecifických premenných prostredia process.env. Vytvorte súbor s názvom config.ts vo vašom adresári src/ a vyplňte ho nasledovne:

// Contents of src/config.ts

import {config as configDotenv} from 'dotenv'
import {resolve} from 'path'

switch(process.env.NODE_ENV) {
  case "development":
    console.log("Environment is 'development'")
    configDotenv({
      path: resolve(__dirname, "../.env.development")
    })
    break
  case "test":
    configDotenv({
      path: resolve(__dirname, "../.env.test")
    })
    break
  // Add 'staging' and 'production' cases here as well!
  default:
    throw new Error(`'NODE_ENV' ${process.env.NODE_ENV} is not handled!`)
}

Poznámka: Tento súbor je potrebné importovať do vášho najvyššieho súboru, pravdepodobne do src/index.ts pomocou import './config' (umiestnené pred všetkými ostatnými importmi)

3. Skontrolujte premenné prostredia a definujte IProcessEnv

Po kombinovaní niekoľkých vyššie uvedených metód môžeme pridať niekoľko kontrol počas behu programu na overenie správnosti, aby sme zaručili, že náš deklarovaný IProcessEnv rozhranie odráža, ktoré ENV premenné sú nastavené v našich .env.* súboroch. Nižšie uvedený obsah môže tiež byť umiestnený v src/config.ts

// More content in config.ts
const throwIfNot = function<T, K extends keyof T>(obj: Partial<T>, prop: K, msg?: string): T[K] {
  if(obj[prop] === undefined || obj[prop] === null){
    throw new Error(msg || `Environment is missing variable ${prop}`)
  } else {
    return obj[prop] as T[K]
  }
}
// Validate that we have our expected ENV variables defined!
['AUTHENTICATION_API_URL', 'GRAPHQL_API_URL'].forEach(v => {
  throwIfNot(process.env, v)
})

export interface IProcessEnv {
  AUTHENTICATION_API_URL: string
  GRAPHQL_API_URL: string
}

declare global {
  namespace NodeJS {
    interface ProcessEnv extends IProcessEnv { }
  }
}
   

Toto nám poskytne správne IntelliSense/tslint kontrolu typov, ako aj určitú rozvahu pri nasadzovaní do rôznych prostredí.

Poznámka, že toto funguje aj pre aplikáciu ReactJS (na rozdiel od aplikácie NodeJS servera). Môžete vynechať Krok (2), pretože toto je riešené create-react-app.

Odpoveď č. 6

Po vykonaní s najnovšou verziou TypeScriptu:

npm install -D --save @types/node

môžete použiť process.env priamo.

console.log(process.env["NODE_ENV"])

Uvidíte očakávaný výsledok, ak ste nastavili NODE_ENV.

Odpoveď č. 7

čo mi fungovalo je, že všade, kde chcem použiť process.env, najprv importujem dotenv a zavolám na ňom config(). Tiež si pamätajte pridať ! na konci a uistiť sa, že atribút je definovaný vo vašom .env súbore

import dotenv from 'dotenv';

dotenv.config();

export const YOUR_ATTRIBUTE = process.env.YOUR_ATTRIBUTE!;

Odpoveď č. 8

Tu je krátka funkcia, ktorá je zaručená, že získa hodnotu process.env ako reťazec - alebo inak vyhodí chybu.

Pre niečo výkonnejšie (ale aj väčšie), niektorí tu navrhli env-var.

/**
 * Returns value stored in environment variable with the given `name`.
 * Throws Error if no such variable or if variable undefined; thus ensuring type-safety.
 * @param name - name of variable to fetch from this process's environment.
 */
export function env(name: string): string {
  const value = process.env[name];

  if (!value) {
    throw new Error(`Missing: process.env['${name}'].`);
  }

  return value;
}

Potom by ste mali byť schopní písať kód ako:

let currentEnvironment: string;
currentEnvironment = env('NODE_ENV');

Odpoveď č. 9

Viem, že to pomôže niekomu, kto hľadá toto a nemôže nájsť jednoduchú odpoveď na to, prečo vaše premenné process.env spôsobujú problémy vášmu kompilátoru:

Nainštalujte @types/node:

npm i @types/node

Potom všade, kde zahrnuješ svoje prostredie ako reťazec, urob toto:

process.env.YOUR_ENV ?? ''

Dvojité otázniky vám umožňujú skontrolovať, či je hodnota null/undefined.

Odpoveď č. 10

vytvorte súbor ako global.d.ts

declare global {
  namespace NodeJS {
    interface ProcessEnv {
      SECRET: string;
    }
  }
}
export {};

návod od Christiana Höllera

Súvisiace články