Skip to content

Instantly share code, notes, and snippets.

@igrek8
Last active March 5, 2022 20:49
Show Gist options
  • Save igrek8/3dab0f7e3e38bd1c4680cc1ee1eae892 to your computer and use it in GitHub Desktop.
Save igrek8/3dab0f7e3e38bd1c4680cc1ee1eae892 to your computer and use it in GitHub Desktop.
Bundle a package and dependencies in a monorepo (bundle is controlled by "files" and "npm pack")
#!/usr/bin/env bash
set -e
while (( $# > 0 )); do
case "${1}" in
-w | --workspace)
workspace="${2}"
shift 2
;;
-o | --output)
output="${2}"
shift 2
;;
*)
shift
;;
esac
done
function die () {
echo "error: $1"
exit 1
}
if [[ -z $workspace ]]; then
die "-w, --workspace is required"
fi
if [[ -z $output ]]; then
die "-o, --output is required"
fi
dependencies=($(
npm list --json -l -w $workspace \
| jq -r -c '.. | .dependencies? | objects | .[] | @base64'
))
for ((i = 0; i < ${#dependencies[@]}; i++)); do
package=$(echo "${dependencies[i]}" | base64 --decode)
name=$(echo $package | jq -r '.name')
path=$(echo $package | jq -r '.path')
uri=$(echo $package | jq -r '.resolved')
if [[ "$uri" == "file:"* ]]; then
echo "copy $name"
files=($(
npm pack --dry-run --json -w $name \
| jq -r '.[].files[].path | @base64'
))
for item in "${files[@]}"; do
file=$(echo $item | base64 --decode)
if (( $i == 0 )); then
echo "copy $output/$(dirname $file)"
mkdir -p $output/$(dirname $file)
cp -L $path/$file $output/$file
else
echo "copy $output/node_modules/$name/$(dirname $file)"
mkdir -p $output/node_modules/$name/$(dirname $file)
cp -L $path/$file $output/node_modules/$name/$file
fi
done
else
echo "copy $output/node_modules/$name"
mkdir -p $output/node_modules/$name
cp -L -R -T $path $output/node_modules/$name
fi
done
@igrek8
Copy link
Author

igrek8 commented Mar 5, 2022

Requires npm@^8

./pack.sh -w @scope/package -o bundle  
{
  "name": "@scope/package",
  "version": "1.0.0",
  "files": [ /* here are your files to bundle */ ]
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment