Skip to content

Instantly share code, notes, and snippets.

@pospi
Last active October 22, 2016 01:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pospi/715a0c59eda382e7b9d79aa743676cf5 to your computer and use it in GitHub Desktop.
Save pospi/715a0c59eda382e7b9d79aa743676cf5 to your computer and use it in GitHub Desktop.
Sets up NPM module linkage when using private modules from your own registry (using Yarn instead of NPM)
#!/usr/bin/env bash
#
# Helper script to setup symlinks and modules for services integration during development
#
# @depends http://stedolan.github.io/jq/
# @depends https://yarnpkg.com/
#
# :WARNING:
# Your global npm packages must be installed for the current user in order for this script to work.
# If this is not the case, we recommend you nuke your global npm folder and replace with an nvm-managed
# node install in your homedir, which will have the correct permissions for `yarn link` to function.
#
BASEPATH="$1"
# By default, all found packages with `private: true` will be linked.
# To add additional dependency detection and linking based on your registry URL (`publishConfig.registry`
# in package.json), uncomment the below line and set as appropriate.
#PRIVATE_REGISTRY_URL="http://packages.yourdomain.com:4873"
# We have to force the registry URL globally while running `yarn link` so that dependencies come via our own registry
if [[ -n $PRIVATE_REGISTRY_URL ]]; then
set -e
function cleanup {
echo "Restoring default registry..."
yarn config delete registry # Note that if you DO use a custom registry in your daily work, you probably don't want this.
}
trap cleanup EXIT
echo "Forcing NPM registry to ${PRIVATE_REGISTRY_URL}..."
yarn config set registry "${PRIVATE_REGISTRY_URL}"
fi
#-------------------------------------------------------------------------------
get_toplevel_packagejson_files() {
local basedir=$1
find ${basedir} -type f -name package.json -not -path '*/node_modules/*'
}
get_packagejson_deps() {
local jsonfile=$1
cat ${jsonfile} | jq '.dependencies | keys []' | sed 's/^"\(.*\)"$/\1/'
}
privatelyRegisteredModuleIds=()
#-------------------------------------------------------------------------------
# First loop: locate and link private packages
while read file; do
moduleDir=`dirname ${file}`
registryUrl=`cat ${file} | jq '.publishConfig.registry' | sed 's/^"\(.*\)"$/\1/'`
packageId=`cat ${file} | jq '.name' | sed 's/^"\(.*\)"$/\1/'`
packagePrivate=`cat ${file} | jq '.private'`
pushd "${moduleDir}" > /dev/null
# If no private registry URL set then use `private` flag to test
if [[ -z $PRIVATE_REGISTRY_URL ]]; then
if [ "$packagePrivate" == "true" ]; then
echo "Linking private package ${moduleDir} for development..."
yarn link
# keep a list of all private packages so we can reference them into their dependencies later
privatelyRegisteredModuleIds+=("${packageId}")
fi
else
# link all private packages to our local npm registry
if [ "$registryUrl" == "$PRIVATE_REGISTRY_URL" ]; then
echo "Linking private package ${moduleDir} for development..."
yarn link
# keep a list of all private packages so we can reference them into their dependencies later
privatelyRegisteredModuleIds+=("${packageId}")
fi
fi
popd > /dev/null
done < <(get_toplevel_packagejson_files "$BASEPATH")
echo "Found private packages: ${privatelyRegisteredModuleIds[@]}"
#-------------------------------------------------------------------------------
# Second loop: link private package deps and install public package deps
while read file; do
moduleDir=`dirname ${file}`
pushd "${moduleDir}" > /dev/null
# check all module dependencies for privately registered modules
while read dep; do
# link dependant private modules
if [[ " ${privatelyRegisteredModuleIds[@]} " =~ " ${dep} " ]]; then
echo "Link private dependency ${dep} to ${moduleDir}..."
yarn link "${dep}"
fi
done < <(get_packagejson_deps './package.json')
# install public dependencies
# Uncomment this if it works for you, but in practise this often creates duplicate dependencies in submodules.
# npm install
popd > /dev/null
done < <(get_toplevel_packagejson_files "$BASEPATH")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment