npm package: @grund/babel-preset
Description: The purpose of this package is quite obvious. But there are a lot of settings that you can use to customize the transpiling of your code.
Latest version: 0.0.85

# @grund/babel-preset

The purpose of this package is quite obvious. But there are a lot of settings that you can use to customize the transpiling of your code.

## Define / Inlining / Environment variables

In most (all?) projects we want to be able to inline some values into the bundled code. This could be database credentials, third party api keys, production/development flags etc. Since we want to build a sustainable solution for as many platforms as possible, the babel preset seemed like the best way of handling this (since we can use it for both Node, Web, ReactNative and - often missed - Testing).

There are a few cases that needs to be supported:

-   Being able to define your own key/values that will be inlined into the bundle.
-   Being able to define what keys that will be picked directly from `process.env`.
-   Being able to define what keys that will be picked directly from `@grund/env`.
-   Being able to define what keys should be overridable in runtime by `process.env` (only in node).
-   Helper: Flag if we want to inline all values from `@grund/env`.
-   Helper: Flag if we want all pure `process.env` expressions to be replaced by `@grund/env` values.

If one uses `@grund/env` to the fullest, one will not use any instance of `process.env` in this process - but rely only on the values parsed and provided by `@grund/env`. In the code, however, `process.env.X` will be exclusive in order to use the environment variables.

### Only process.env and import.meta.env

I would love to be debunked on this for better ways, but it seems like the best way of handling and inlining environment variables in a modern JS application (that uses babel) is to make use of either `process.env.X` or `import.meta.env`. There should be little to no use of custom global variables such as a pure `NODE_ENV` or `X_API_KEY` - they should all be accessed by `process.env.NODE_ENV` or `import.meta.env.X_API_KEY`.

Due to this, and in order to simplify things, the options made available for env configuration will only regard keys that are prefixed with `process.env.` or `import.meta.env.`. This means that if you set your babel config to inline the following object:

```ts
{
    API_PORT: 5000,
}
```

babel will try to find `process.env.API_PORT` or `import.meta.env.API_PORT` and replace it with `5000`.

In other words, every key you define in the babel config will be prefixed with either `process.env` or `import.meta.env`. This also means that you cannot use different values for the same key but with different prefixes in your code (e.g. `process.env.VALUE === "foo"` and `import.meta.env.NODE_ENV === "bar`). But that seems like an improbable case.

If you want to be able to inline other (global) values, you can add `babel-plugin-transform-define` to your babel plugins. This is what `@grund/babel-preset` uses internally - so you don't have to add it to your dependencies.

## Extending vs. Creating

You may have noticed that in the default grund boilerplate code the babel config is not defined in a conventional way. It uses a factory function (`createBabelConfig`) to create the babel config instead of extending it as a preset. There is, of course, a reason for this.

We have found that sometimes (and also sometimes inconsistently) babel doesn't merge the presets in a way that you'd expect. Sometimes the plugin orders are messed up which gives errors in the code. But we also found out that it could be fixed by reading the concered plugins to the config file.

Hence, there was two ways of solving this:

1. Get into the nitty gritty of the babel source code and see what was wrong.
2. Create a factory function that helps in creating a babel config without relying on the babel helper functions.

We chose the latter (easier and faster) way for now since we value getting a functional platform rather than solving everything optimally. We will most certainly return to this later on.

With this said, there is also support for using this preset normally - i.e. extending the preset in your custom config file.