Skip to content

Instantly share code, notes, and snippets.

@trotzig
Last active June 4, 2017 11:00
Show Gist options
  • Save trotzig/40d06e9b60b766f66c3da9d05f9be791 to your computer and use it in GitHub Desktop.
Save trotzig/40d06e9b60b766f66c3da9d05f9be791 to your computer and use it in GitHub Desktop.
This script will find javascript modules that aren't currently used in your application.
#!/bin/bash
# Make the script fail on the first error encountered.
set -euo pipefail
# Create a temp folder that we can use to store files in.
if [ "$(uname -s)" = "Darwin" ]; then
tmp_dir=$(mktemp -d -t find-dead-modules.XXXXXXXX)
else
tmp_dir=$(mktemp -d --tmpdir find-dead-modules.XXXXXXXX)
fi
# Make sure that the temp folder is removed on exit.
trap 'rm -rf "$tmp_dir"' EXIT INT QUIT TERM
# Find all javascript modules.
#
# We do this by listing all files, stripping out stuff that isn't part of the
# module "name" ("/index.js*", file suffix, path, etc). We also exclude a few
# utility modules that would otherwise be incorrectly flagged as dead.
find app/assets -name "**.js" -o -name "**.jsx" \
| sed 's/\/index.*\.js.*//' \
| sed 's/.*\/\(.*\)/\1/' \
| sed 's/\(.*\)\.js.*/\1/' \
| sed '/GenericContainer/d' \
| sed '/StyleGuideExample/d' \
| sort -u \
> "${tmp_dir}/all_modules.txt"
# Find all modules currently being `require`d.
#
# We exclude certain folders and files from the grep. The most important ones to
# ignore are index-test.js*, index-diffux.js, etc. Otherwise we would treat
# modules that are required only by their tests as "alive".
grep -r "require('.*')" . \
--exclude-dir="node_modules" \
--exclude-dir=".git" \
--exclude="**/index-*.js*" \
--include="**.js*" \
--no-filename \
--only-matching \
| cut -d\' -f2 \
| sed 's/.*\/\(.*\)/\1/' \
> "${tmp_dir}/all_used_modules.txt"
# Add files listed in webpack config.
#
# Not all files are referenced through a `require` statement. We also have to
# grab a few modules referenced in webpack config.
grep -r "assets\/javascripts/.*\.js" . \
--include="webpack.*" \
--only-matching \
--no-filename \
| cut -d'/' -f3 \
| cut -d'.' -f1 \
>> "${tmp_dir}/all_used_modules.txt"
# Sorting needs to happen to make the `comm` call below work the way we want it
# to.
sort -u "${tmp_dir}/all_used_modules.txt" \
--output="${tmp_dir}/all_used_modules.txt"
# Use `comm` to give us a list of all modules that aren't used.
UNUSED_MODULES=$(comm -23 \
"${tmp_dir}/all_modules.txt" \
"${tmp_dir}/all_used_modules.txt")
if [ -z "$UNUSED_MODULES" ]; then
exit 0
else
echo "These modules are not in use:"
echo "$UNUSED_MODULES"
exit 1
fi
@trotzig
Copy link
Author

trotzig commented Jun 21, 2016

There are some brigade specific stuff in here, but in general this is generic enough to be used on any codebase.

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