Accessing Custom Flags from Terminal
Tags: react, webdev, webpack, terminal
Published: 2022-12-21 16:17:21

### Prerequisites:
- React app setup with webpack which can be found [here](https://github.com/aydotvin/react/tree/main/accessing_terminal_flags).

#### Two pathways:
1. Terminal -> webpack -> application logic
1. One terminal command to another

---

### 1. Terminal -> webpack -> application logic
#### Overview:
> Terminal flag is passed from terminal to webpack file using `cross-env` and is set as env variable using `webpack.DefinePlugin()` which is accessible via `process.env.variableName` while writing logic.

#### Syntax:
##### - Script command
```
"start": "cross-env variable_name_1=$npm_config_<flag_name_1> variable_name_2=$npm_config_<flag_name_2> webpack serve --config ./webpack/webpack.dev.js"
```
  - `variable_name_1` - this is the variable that is accessible in the webpack config via `process.env.variable_name_1`. Same with `variable_name_2`. 
  - `flag_name_1` - this is the flag name that has to be entered in the terminal.

##### - Terminal command
```
npm run start --flag_name_1=flagvalue1 --flag_name_2=flagvalue2
```

#### Steps:
- Install `cross-env` npm.
- Add the following script under the `package.json` scripts. 
```
"start": "cross-env clientVariable=$npm_config_client themeVariable=$npm_config_theme webpack serve --config ./webpack/webpack.dev.js"
```
- In the webpack config file (`webpack.common.js`), the flag values will be accessible with `process.env.clientVariable` and `process.env.themeVariable`
```
const client = process.env.clientVariable;
const theme = process.env.themeVariable;
console.log("client in common webpack", client);
console.log("theme in common webpack", theme);
```
- Now under the plugins, define the variables to be accessed in the application.
```
new webpack.DefinePlugin({
	"process.env.client": JSON.stringify(client),
	"process.env.theme": JSON.stringify(client),
}),
```
- These flags can be accessed in the requried components using `process.env.client` and `process.env.theme`
```
const App = () => {
	return (
		<div className={styles.app}>
			<h2>App Component.</h2>
			<p>
				Environment value terminal flag, Client - <span className={styles.envValue}>{process.env.client}</span>
			</p>
			<p>
				Environment value terminal flag, Theme - <span className={styles.envValue}>{process.env.theme}</span>
			</p>
		</div>
	);
};
```
- Now enter the following command in terminal and the values will be available.
`npm run start --client=clientA --theme=light`

---

### 2. One terminal command to another
#### Overview:
> Terminal flag is passed from one terminal command to another script call using `cross-env-shell`.

#### Steps:
- With the `cross-env` npm package installed.
- Add the following scripts under the `package.json` scripts.
```
"echoMessage": "cross-env-shell clientVariable=$npm_config_client themeVariable=$npm_config_theme echo \"Hello $clientVariable, theme is $themeVariable\""
```
```
"greet": "cross-env clientVariable=$npm_config_client themeVariable=$npm_config_theme npm run echoMessage"
```
- The only difference would be the usage of `cross-env-shell` instead of `cross-env` to access the entered flag value from the parent command.
- Now enter the following command in terminal.
`npm run greet --client=clientA --theme=light`
- You would see the following output in the terminal.
> Hello clientA, theme is light

- Once `greet` script is run, npm configs - `client` and `theme` will be set and those values can be accessed in other scripts.
- When `echoMessage` is called from `greet` script, npm configs - `client` and `theme` will be assigned to the variables listed for them in the `echoMessage` script, i.e, `clientVariable` and `themeVariable`. These variables can be accessed in the script using `$clientVariable` and `$themeVariable`.
- This can be used when certain actions needs to be taken based on the client name or anything similar.

---

### Repo link: [Github](https://github.com/aydotvin/react/tree/main/accessing_terminal_flags)

### Reference: [cross-env](https://www.npmjs.com/package/cross-env)