0

I am reading a microservice NodeJS project that has some files like below:

index.ts:

import mongoose from "mongoose";
import { app } from "./app";
import { natsWrapper } from "./nats-wrapper";
import { OrderCreatedListener } from "./events/listeners/order-created-listener";
import { OrderCancelledListener } from "./events/listeners/order-cancelled-listener";

const start = async () => {
  if (!process.env.JWT_KEY) {
    throw new Error("JWT_KEY must be defined");
  }
  if (!process.env.MONGO_URI) {
    throw new Error("MONGO_URI must be defined");
  }
  if (!process.env.NATS_CLIENT_ID) {
    throw new Error("NATS_CLIENT_ID must be defined");
  }
  if (!process.env.NATS_URL) {
    throw new Error("NATS_URL must be defined");
  }
  if (!process.env.NATS_CLUSTER_ID) {
    throw new Error("NATS_CLUSTER_ID must be defined");
  }

  try {
    await natsWrapper.connect(
      process.env.NATS_CLUSTER_ID,
      process.env.NATS_CLIENT_ID,
      process.env.NATS_URL
    );
    natsWrapper.client.on("close", () => {
      console.log("NATS connection closed!");
      process.exit();
    });
    process.on("SIGINT", () => natsWrapper.client.close());
    process.on("SIGTERM", () => natsWrapper.client.close());

    new OrderCreatedListener(natsWrapper.client).listen();
    new OrderCancelledListener(natsWrapper.client).listen();

    await mongoose.connect(process.env.MONGO_URI, {});
    console.log("Connected to MongoDb");
  } catch (err) {
    console.error(err);
  }

  app.listen(3000, () => {
    console.log("Listening on port 3000!!!!!!!!");
  });
};

start();

i searched all through the project to find any intialization for process.env.NATS_CLUSTER_ID , process.env.NATS_URL , process.env.MONGO_URI variables/properties, but I couldn't find anything. I only could find process.env.JWT_KEY = "some-secret-key"; .

I am wondering to know where do process.env properties get initialize and when the initialization happens and where do they store the values?

GoodMan
  • 542
  • 6
  • 19
  • They come from the OS environment. This is a common way of injecting environment-specific configuration into code – Joe Sep 27 '22 at 01:01

1 Answers1

1

Where are "process.env" properties defined?

process.env refers to an object that consists of name/values pairs that represent the current state of the environment variables within your nodejs process.

That object is initialized from the OS process environment that is present when the nodejs process is first started and that will be either the environment in the command shell you launched nodejs from or the environment that was passed into it when nodejs was launched programmatically. That initialization happens by calling a libuv function called uv_os_getenv() which you can see in the libuv source here for Unix or here for Windows. That data is then stored within nodejs as an object and can then be modified during the running of your nodejs process.

I am wondering to know where do process.env properties get initialize and when the initialization happens

This happens as part of the nodejs process initialization before it starts running your Javascript code.

where do they store the values

process.env is a normal Javascript property that contains a normal Javascript object that contains what nodejs read in initially from the os environment given to your nodejs process plus any environment variables that nodejs itself might set.

You can do console.log(process.env) and see such an object. I initially thought that maybe it would be a getter to get you a copy of the master object, but that's not the case. It is just an ordinary property that contains the actual object and it can be modified as such using Javascript during the running of your program.


In your specific nats programming example, it appears that the environment variables: NATS_CLUSTER_ID, NATS_CLIENT_ID and NATS_URL are either set programmatically by your nats-wrapper module or that module expects you to set these in the environment so they can be retrieved and used from there.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • I searched all the project code and couldn't find something like `NATS_CLUSTER_ID =` like what I found for `process.env.JWT_KEY = "some-secret-key";`. I also run the whole project by `skaffold dev` command and couldn't find anything about that inside the `skaffold.yaml` file as well. – GoodMan Sep 27 '22 at 03:04
  • But I found this ` spec: containers: - name: nats image: nats-streaming:0.17.0 args: [ '-p', '4222', '-m', '8222', '-hbi', '5s', '-hbt', '5s', '-hbf', '2', '-SD', '-cid', 'ticketing', ]` within the `nats-depl.yaml` file and I think those variables get initialized by these arguments here? – GoodMan Sep 27 '22 at 03:06
  • I also found something like this `const stan = nats.connect('ticketing', randomBytes(4).toString('hex'), { url: 'http://localhost:4222', });` inside the `listener.ts` file inside the `nats` folder. Maybe these are the arguments I am looking for? – GoodMan Sep 27 '22 at 03:25
  • @GoodMan - Can you provide a link to the nats-wrapper module/doc? I can't find it anywhere. The point of this code is that `nats.connect()` takes a number of arguments. Those arguments can come from anywhere. In one particular example, they come from the process environment, but they could come from a config file or they could be baked into your code as constants. – jfriend00 Sep 27 '22 at 03:38
  • Finally I found that inside the `Docker/Kubernetes` deployment files, the environment variables are defined under the `env` property like this: `containers: - name: payments image: mydockerID/payments env: - name: NATS_CLIENT_ID valueFrom: fieldRef: fieldPath: metadata.name - name: NATS_URL value: 'http://nats-srv:4222' - name: NATS_CLUSTER_ID value: ticketing - name: MONGO_URI value: 'mongodb://mongo-srv:27017/pay'` – GoodMan Sep 28 '22 at 17:40