README.md

# embeds

[![Package Version](https://img.shields.io/hexpm/v/embeds)](https://hex.pm/packages/embeds)
[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/embeds/)

A Gleam code generator, allowing you to generate constants and zero-argument functions based on files, environment variables, or any other source you'd like.

It provides simple command-line tools for basic use cases, but allows you to hook into most parts of the generation process. This can be used to [Automatically generate Lustre code](./examples/lustre-icons.html) for SVG icons, for example.

## Getting started

Install `embeds` as a dev dependency:

```sh
gleam add --dev embeds
```

Run the generators:

```sh
gleam run -m embeds/files -- --help
gleam run -m embeds/env -- --help
```

## Why?

Please keep in mind that embedding files into Gleam is often not necessary when running on the Erlang platform.

Erlang provides `priv` directory, which will be bundled with your application code when building an Erlang shipment. When using [wisp](https://hexdocs.pm/wisp/index.html), the [wisp.priv_directory](https://hexdocs.pm/wisp/wisp.html#priv_directory) function can be used to reliably get a path to this directory, allowing easy access to all files using [simplifile](https://hexdocs.pm/simplifile/index.html) or [wisp.serve_static](https://hexdocs.pm/wisp/wisp.html#serve_static), for example.

In general, a similar approach should be preferred when building for Javascript. But it is sometimes more useful to improve load times, and embed other resources directly into the generated bundle. Embedding certain build-time constants can also be used by bundlers to improve dead code elimintation/tree shaking. Please keep in mind that you may also be able to use [vite](https://vitejs.dev/guide/assets.html) or [esbuild](https://esbuild.github.io/content-types/#data-url) directly for this, which are both highly tested and extensible options.

I personally use this package to embed build-time constants from Netlify into my Javascript bundle. Another good use case might be to apply additional pre-processing to you source files to generate more interesting source code (see the examples on how to do that).

## Using the Gleam API

Since you're likely going to depend on the generated modules, you cannot put code that uses `embeds` into the same project that you're trying to use the generated files in, not even in `test`! If you exclude the generated modules in `.gitignore`, or just want to delete and regenerate them all, your project will stop to build entirely, leaving you unable to run your code generator as well.

The common solution to this problem is to add another Gleam project to your repository for your build and codegen tools, and reference that new project using path dev dependencies in your main project(s).

Let's assume you currently have a repository structure already looking like this:

```text
.
├── server
│   ├── gleam.toml
│   ├── README.md
│   ├── src
│   └── test
└── client
    ├── gleam.toml
    ├── README.md
    ├── src
    └── test
```

You can add another project called `build`, and then add it as a dev dependency to all required projects by adding it to their `gleam.toml`:

```toml
[dev-dependencies]
build = { path = "../build" }
```

> **Hint:** Make sure to also run `gleam deps update` after modifying your `gleam.toml` manually, or adding dependencies to your `build` project!

This new `build` project does not require any codegen itself, and therefore can be built and cached without affecting any of your other projects.

Overall your new structure should now look like this:

```text
.
├── build
├── server
└── client
```

where you can now run

```sh
gleam run -m build
```

in the projects with the dev dependency added.