<!-- This file was generated by @travetto/doc and should not be modified directly -->
<!-- Please modify https://github.com/travetto/travetto/tree/main/module/pack/DOC.tsx and execute "npx trv doc" to rebuild -->
# Pack

## Code packing utilities

**Install: @travetto/pack**
```bash
npm install @travetto/pack

# or

yarn add @travetto/pack
```

This module provides the necessary tools to produce deliverable output for [Travetto](https://travetto.dev) based projects.  The main interaction with this module is through the command line interface, and the operations it provides.  Under the covers, the code bundling is performed by [Rollup](https://rollupjs.org/), with specific configuration to support the frameworks runtime expectations. 

There are three primary cli commands for packing your code:
   *  pack
   *  pack:zip
   *  pack:docker

## CLI - pack

**Terminal: Pack usage**
```bash
$ trv pack --help

Usage: pack [options]

Options:
  -b, --build-dir <string>             Workspace for building (default: "/tmp/<temp-folder>")
  --clean, --no-clean                  Clean workspace (default: true)
  -o, --output <string>                Output location
  --main-scripts, --no-main-scripts    Create entry scripts (default: true)
  -f, --main-name <string>             Main name for build artifact
  -e, --entry-point <string>           Entry point (default: "@travetto/cli/support/entry.trv.ts")
  --minify, --no-minify                Minify output (default: true)
  -sm, --sourcemap                     Bundle source maps (default: false)
  -is, --include-sources               Include source with source maps (default: false)
  -x, --eject-file <string>            Eject commands to file
  -r, --rollup-configuration <string>  Rollup configuration file (default: "@travetto/pack/support/rollup/build.ts")
  --env-file <string>                  Env Flag File Name (default: ".env")
  --manifest-file <string>             Manifest File Name (default: "manifest.json")
  -wr, --include-workspace-resources   Include workspace resources (default: false)
  -np, --npm-package <string>          External NPM Packages (default: [])
  -m, --module <module>                Module to run for
  -h, --help                           display help for command
```

This command line operation will compile your project, and produce a ready to use workspace as a deliverable. Additionally, you can pass in a file to the `eject-file` flag that will allow for a script to be produced (base on the host operating system). 

Specific to this CLI command, the `output` field determines where the final folder is written that contains all the compiled source.

### Entry Point Configuration
Every application requires an entry point to determine execution flow (and in [Rollup](https://rollupjs.org/)'s case, tree-shaking as well.).  By default the [Command Line Interface](https://github.com/travetto/travetto/tree/main/module/cli#readme "CLI infrastructure for Travetto framework") acts as the entry point.  This bypasses the [Compiler](https://github.com/travetto/travetto/tree/main/module/compiler#readme "The compiler infrastructure for the Travetto framework") intentionally, as the compiler is not available at runtime. 

Within the command line, the `args` are positional arguments that will be passed to the entry point on application run.

**Code: Packing an application run**
```typescript
$ npx trv pack run myapp
```

Would then produce an executable script, in the output folder, that would look like:

**Code: Entry script for Packed application**
```typescript

#!/bin/sh
cd $(dirname "$0")
node cli run myapp
```

And this entry point would be what is executed by [docker](https://www.docker.com/community-edition), or whatever deployment mechanism is being used.

### General Packing Operations
Every [Pack](https://github.com/travetto/travetto/tree/main/module/pack#readme "Code packing utilities") operation extends from the base command, and that provides some consistent operations that run on every packing command.
   *  `clean` - Empties workspace before beginning, controlled by the `--clean` flag, defaults to on
   *  `writeEnv` - Writes the .env.js files that includes the necessary details to start the application.  This is primarily to identify the location of the manifest file needed to run.
   *  `writePackageJson` - Generates the [Package JSON](https://docs.npmjs.com/cli/v9/configuring-npm/package-json) with the appropriate module type ([CommonJS](https://nodejs.org/api/modules.html) or [Ecmascript Module](https://nodejs.org/api/esm.html)) for interpreting plain `.js` files
   *  `writeEntryScript` - Create the entry script based on the `--entry-command`, `args`
   *  `copyResources` - Will pull in local `resources/**` files into the final output
   *  `primeAppCache` - Runs `trv run` to ensure the appropriate files are generated to allow for running the application.  This only applies if the entry point is equivalent to `trv run`
   *  `writeManifest` - Produces the `prod`-ready manifest that is used at runtime.  Removes all devDependencies from the manifest.json
   *  `bundle` - Invokes [Rollup](https://rollupjs.org/) with the appropriate file set to produce a single output .js file.  Depending on the module type ([CommonJS](https://nodejs.org/api/modules.html) or [Ecmascript Module](https://nodejs.org/api/esm.html)) the build process differs to handle the dynamic loading that application does at runtime.

## CLI - pack:zip
This command is nearly identical to the standard `pack` operation, except for the `output` flag.  In this scenario, the `output` flag determines the location and name of the final zip file.

**Terminal: Pack:zip usage**
```bash
$ trv pack:zip --help

Usage: pack:zip [options]

Options:
  -b, --build-dir <string>             Workspace for building (default: "/tmp/<temp-folder>")
  --clean, --no-clean                  Clean workspace (default: true)
  -o, --output <string>                Output location (default: "travetto_pack.zip")
  --main-scripts, --no-main-scripts    Create entry scripts (default: true)
  -f, --main-name <string>             Main name for build artifact
  -e, --entry-point <string>           Entry point (default: "@travetto/cli/support/entry.trv.ts")
  --minify, --no-minify                Minify output (default: true)
  -sm, --sourcemap                     Bundle source maps (default: false)
  -is, --include-sources               Include source with source maps (default: false)
  -x, --eject-file <string>            Eject commands to file
  -r, --rollup-configuration <string>  Rollup configuration file (default: "@travetto/pack/support/rollup/build.ts")
  --env-file <string>                  Env Flag File Name (default: ".env")
  --manifest-file <string>             Manifest File Name (default: "manifest.json")
  -wr, --include-workspace-resources   Include workspace resources (default: false)
  -np, --npm-package <string>          External NPM Packages (default: [])
  -m, --module <module>                Module to run for
  -h, --help                           display help for command
```

## CLI - pack:docker
This command starts off identical to the standard `pack` operation, but it contains a few additional flags, and ultimately a few additional operations to support creating of the final [docker](https://www.docker.com/community-edition) image.

**Terminal: Pack:docker usage**
```bash
$ trv pack:docker --help

Usage: pack:docker [options]

Options:
  -b, --build-dir <string>               Workspace for building (default: "/tmp/<temp-folder>")
  --clean, --no-clean                    Clean workspace (default: true)
  -o, --output <string>                  Output location
  --main-scripts, --no-main-scripts      Create entry scripts (default: true)
  -f, --main-name <string>               Main name for build artifact
  -e, --entry-point <string>             Entry point (default: "@travetto/cli/support/entry.trv.ts")
  --minify, --no-minify                  Minify output (default: true)
  -sm, --sourcemap                       Bundle source maps (default: false)
  -is, --include-sources                 Include source with source maps (default: false)
  -x, --eject-file <string>              Eject commands to file
  -r, --rollup-configuration <string>    Rollup configuration file (default: "@travetto/pack/support/rollup/build.ts")
  --env-file <string>                    Env Flag File Name (default: ".env")
  --manifest-file <string>               Manifest File Name (default: "manifest.json")
  -wr, --include-workspace-resources     Include workspace resources (default: false)
  -np, --npm-package <string>            External NPM Packages (default: [])
  -df, --docker-factory <string>         Docker Factory source (default: "@travetto/pack/support/pack.dockerfile.ts")
  -di, --docker-image <string>           Docker Image to extend (default: "node:23-alpine")
  -dn, --docker-name <string>            Docker Image Name (default: "travetto_pack")
  -ru, --runtime-user <string>           Docker Runtime user
  -rp, --runtime-package <string>        Docker Runtime Packages (default: [])
  -dp, --docker-port <number>            Docker Image Port (default: [])
  -ds, --docker-stage-only               Docker Stage Only (default: false)
  -dt, --docker-tag <string>             Docker Image Tag (default: ["latest"])
  -dx, --docker-push                     Docker Push Tags (default: false)
  -db, --docker-build-platform <string>  Docker Build Platform
  -dr, --docker-registry <string>        Docker Registry
  -m, --module <module>                  Module to run for
  -h, --help                             display help for command
```

The additional flags provided are allow for specifying the base image, the final docker image name (and tags), and which registry to push to (if  any).  Additionally, there are flags for exposing which ports the image should expect to open as well.   When using the `--eject-file`  flag, the output script will produce the entire Dockerfile output inline, so that it can be easily modified as needed. 

In addition to the standard operations, this command adds the following steps:
   *  `writeDockerFile` - Generate the docker file contents
   *  `pullDockerBaseImage` - Pull base image, to ensure its available and primed
   *  `buildDockerContainer` - Build final container
   *  `pushDockerContainer` - Push container with appropriate tags.  Only applies if `--docker-push` is specified

## Ejected File
As indicated, any of the pack operations can be ejected, and produce an output that can be run independent of the pack command.  This is helpful when integrating with more complicated build processes.

**Terminal: Sample Ejected File**
```bash
$ trv pack:docker -x /dev/stdout web:http

#!/bin/sh
export DIST=/tmp/<temp-folder>
export TRV_OUT=<workspace-root>/.trv/output
export ROOT=<workspace-root>/related/todo-app
export MOD=@travetto/todo-app

# Cleaning Output $DIST 

echo "Cleaning Output $DIST"

rm -rf $DIST
mkdir -p $DIST

# Writing $DIST/.env 

echo "Writing $DIST/.env"

echo "NODE_ENV=production" > $DIST/.env
echo "TRV_MANIFEST=manifest.json" >> $DIST/.env
echo "TRV_MODULE=$MOD" >> $DIST/.env
echo "TRV_CLI_IPC=" >> $DIST/.env
echo "TRV_RESOURCE_OVERRIDES=@#resources=@@#resources" >> $DIST/.env

# Writing package.json 

echo "Writing package.json"

echo "{\"type\":\"commonjs\",\"main\":\"todo-app.js\"}" > $DIST/package.json

# Writing entry scripts todo-app.sh args=(web:http) 

echo "Writing entry scripts todo-app.sh args=(web:http)"

echo "#!/bin/sh" > $DIST/todo-app.sh
echo "cd \$(dirname \"\$0\")" >> $DIST/todo-app.sh
echo "node todo-app.js web:http \$@" >> $DIST/todo-app.sh
chmod 755 $DIST/todo-app.sh

# Writing entry scripts todo-app.cmd args=(web:http) 

echo "Writing entry scripts todo-app.cmd args=(web:http)"

echo "cd %~p0" > $DIST/todo-app.cmd
echo "node todo-app.js web:http %*" >> $DIST/todo-app.cmd
chmod 755 $DIST/todo-app.cmd

# Copying over module resources 

echo "Copying over module resources"

cp -r -p $ROOT/resources/* $DIST/resources

# Writing Manifest manifest.json 

echo "Writing Manifest manifest.json"

TRV_MODULE=$MOD npx trvc manifest --prod $DIST/manifest.json

# Bundling Output minify=true sourcemap=false entryPoint=@travetto/cli/support/entry.trv.ts 

echo "Bundling Output minify=true sourcemap=false entryPoint=@travetto/cli/support/entry.trv.ts"

export BUNDLE_ENTRY=node_modules/@travetto/cli/support/entry.trv.js
export BUNDLE_MAIN_FILE=todo-app.js
export BUNDLE_COMPRESS=true
export BUNDLE_SOURCEMAP=false
export BUNDLE_SOURCES=false
export BUNDLE_OUTPUT=$DIST
export BUNDLE_FORMAT=commonjs
export BUNDLE_ENV_FILE=.env
export TRV_MANIFEST=$TRV_OUT/node_modules/$MOD
cd $TRV_OUT
npx rollup -c $TRV_OUT/node_modules/@travetto/pack/support/rollup/build.js
cd $ROOT

# Pulling Docker Base Image node:23-alpine 

echo "Pulling Docker Base Image node:23-alpine"

docker pull node:23-alpine

# Detected Image OS node:23-alpine as alpine 

echo "Detected Image OS node:23-alpine as alpine"

# Generating Docker File $DIST/Dockerfile @travetto/pack/support/pack.dockerfile.ts 

echo "Generating Docker File $DIST/Dockerfile @travetto/pack/support/pack.dockerfile.ts"

echo "FROM node:23-alpine" > $DIST/Dockerfile
echo "RUN addgroup -g 2000 app && adduser -D -G app -u 2000 app" >> $DIST/Dockerfile
echo "RUN mkdir /app && chown app:app /app" >> $DIST/Dockerfile
echo "COPY --chown=\"app:app\" . /app" >> $DIST/Dockerfile
echo "ENV NODE_OPTIONS=\"\"" >> $DIST/Dockerfile
echo "" >> $DIST/Dockerfile
echo "USER app" >> $DIST/Dockerfile
echo "WORKDIR /app" >> $DIST/Dockerfile
echo "ENTRYPOINT [\"/app/todo-app.sh\"]" >> $DIST/Dockerfile

# Building Docker Container latest 

echo "Building Docker Container latest"

cd $DIST
docker build -t travetto_todo-app:latest .
cd $ROOT
```
