1

I want to create a hash on build and set is as environment variable. It should be accessible by node.

Firstly I wrote a bash script, exported the environment variable in the script and sourced it in the package.json. Problem is node doesn't know the source command. Now I rewrote the script in Typescript (due to the whole project using TS not JS). In the script I set the variable as follows:

process.env.VARIABLE = hashFunction(path);

The function is called through a script in package.json

"hash": "ts-node path/to/script.ts"

The function works as it should, but the environment variable is not set. Can someone help me to resolve this? Is it possible to return the string outside of the script and set it from there?

If possible i'd like to not use an external package.

Thank you :)

Update:

I used a bash script, but with a typescript script it'd work the same way. For bash the console.log is replaced with echo.

script.ts

console.log("2301293232") // The hash created by the script

package.json

"scripts": {
    "build": "yarn run hash react-scripts build", // omit &&
    "hash": "ENV_VAR=$(ts-node script.ts)"
}

So I did the following: The script returns the checksum to the console/standard output. But I'll capture it before and set the printed value as environment variable in the package.json file. This will work as long as its the same process which starts the build. That is why neither

"scripts": {
    "build": "yarn run hash && react-scripts build"
}

nor

"scripts": {
    "build": "react-scripts build",
    "prebuild": "ENV_VAR=$(ts-node script.ts)"
}

will work. In both examples a new process will be started and the environment variable will be lost.

CronJorian
  • 13
  • 1
  • 4
  • Does this answer your question? [Node.js - how to set environment variables in code](https://stackoverflow.com/questions/29560844/node-js-how-to-set-environment-variables-in-code) – Wyck Mar 25 '22 at 16:39
  • @Wyck sadly no because I want to call a script on build which creates the variable. This variable should then be available while the project is running. But thanks anyway :) – CronJorian Mar 25 '22 at 17:26
  • It may be important to call out explicitly in your question the scope in which you want the environment variable to be set. Typically it's set for the calling process and its children. But to have the change affect the calling shell requires a different technique. And to have the call affect only one other particular process created by the calling shell, but not every process is different again. Perhaps you should give us the bigger picture about what you're doing with your npm scripts. (Also, this has very little to do with typescript, I think) – Wyck Mar 25 '22 at 17:39

1 Answers1

1

Can't (easily) change environment variables for parent process

You can change/set the environment for the currently running process. That means that when ts-node runs your program, you are changing the environment variables for your script and for ts-node.

After your script is finished running, ts-node stops, and the environment changes are lost. They don't get passed back to the shell.

Changing another process's environment

Changing the environment variables for the parent process (the shell) is a much more complicated process and depends on your OS and upon having the correct permissions. For linux, one such technique is listed here. In Windows, you can find some hints by looking at this question.

Other options

Your other option might be to just return a string that your shell understands, and run that.

Codebling
  • 10,764
  • 2
  • 38
  • 66
  • @SebastianSchwarzer it doesn't directly answer your question, really, but I guess that's because it's not really possible to do in Typescript. Let me know if you have any other questions. – Codebling Mar 25 '22 at 17:11
  • So I guess the bash script would be a better option, but instead of setting the environment variable inside the script I return the string and set it via node? Is there a way to return in bash other than to echo? – CronJorian Mar 25 '22 at 17:14
  • @SebastianSchwarzer sorry, I think I meant the opposite - if you already have Typescript that sets your environment variables, `console.log()` each key=value pair and then eval that in your bash script. If you already have a bash script that sets the environment variables, then you don't have a problem - bash scripts are run by bash, which *is* your running shell. – Codebling Mar 25 '22 at 17:17
  • I have in fact a bash script which is working. But the problem is that I use `export VARIABLE=$hash` in the script and in node I call it by using `source script.sh` so set the variables. The problem is that yarn which runs the project doesn't know the `source` command :/ – CronJorian Mar 25 '22 at 17:23
  • Ok, I initially thought you wanted to set Bash environment variables. It sounds like you want to set the environment variables for your node script, and you're trying to do it inside one of the `scripts` in `package.json`? Just to be clear, you *can* use Typescript to set environment variables, but you'd have to do it in the same process where you consume them (not the same file, just the same run of `ts-node`). – Codebling Mar 25 '22 at 17:37
  • If you want to use your bash script to set the environment variables, you'll need to run it before you run `yarn`, e.g. `source script.sh && yarn`. The reason the bash script won't work in the `scripts` section of `package.json` is that `yarn` runs a new bash to interpret the script command. When that bash dies, so do your env changes. If you want to use your Typescript to set the env, just `require()` or `import` it at the beginning of your entrypoint, e.g. in `index.js`. – Codebling Mar 25 '22 at 17:40
  • @SebastianSchwarzer if this is not clear I can write it a bit more clearly in the answer, where there's a little more room – Codebling Mar 25 '22 at 17:41
  • You *can* make the bash script work inside a `package.json` script if you make the bash script also launch node. You should also checkout [dotenv](https://github.com/motdotla/dotenv), which is a common pattern in Node to load environment variables – Codebling Mar 25 '22 at 17:42
  • Sorry for the late answer. I want to set environment variables for the node application I built and want to set it through calling a script in the `package.json`. So I want to run it by calling `yarn run hash` to run the hash script, so that I can use that to call it while building with `yarn run build` which then calls the hash script before the build (maybe even through `prebuild`). But I think it might be too overcomplicated, so I'll look through the npm packages to maybe find a package which can hash folders through cli. I really appreciate your answers though, thank you very much :) – CronJorian Mar 28 '22 at 07:12
  • Not sure if you're interested in how I did it, but i solved it now. I dumped the ts script and used the bash script, echoed the hash and catched it in the package.json, where I set it as environment variable on build. I'll update the question with further information, in case others will have the same problem :D Thank you very much for your help! – CronJorian Mar 28 '22 at 13:41
  • @SebastianSchwarzer nice, glad you got it! – Codebling Mar 28 '22 at 15:54