-
Notifications
You must be signed in to change notification settings - Fork 2
/
npm
executable file
·140 lines (113 loc) · 5.59 KB
/
npm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#!/usr/bin/env bash
# Фейковый npm
# Нужен для кэширования папки node_modules
# Кэш находится в папке ~/.cache/npm-inject/[версия node]-[окружение node]/[sha1 хэш файла package.json]/node_modules
#
# В PATH надо добавить путь папки с фейковым npm, таким образом при выполнении команды `npm install`
# bash вызовет фейковый npm c параметром `install`.
# Фейк проверяет наличие папки [sha1 хэш файла package.json] в кэше. При наличии `package-lock.json` или `npm-shrinkwrap.json` хэш будет вычислен от этого файла, вместо `package.json`.
# Если она в кэше, создаем на неё симлинк node_modules
# Иначе вызываем оригинальный npm (вторая позиция в `which -a npm`), копируем node_modules в кэш
#
# Если указать переменную окружения NPM_INJECT_COPY=1, то вместо симлинка кэш будет скопирован.
#
# Важно: при использовании мягких зависимостей в `package.json` и `package-lock.json` файла команда `npm install` может изменить `package-lock.json` файл, указав более свежие зависимости.
# В этом случае кэш будет записан для обновлённого `package-lock.json`. Это означает, что при исходном `package-lock.json` файле с устаревшими зависимостями кэш не будет использован.
# Из-за такого поведения `npm install` рекомендуем указывать точные зависимости `package.json` файле.
#
# При указании времени жизни кэша в переменную окружения $NPM_CACHE_EXPIRE_DAYS
# кэш будет удаляться после истечения срока жизни.
# Время жизни кэша указывается в днях.
#
# @author Shuhrat Shadmonkulov <[email protected]>
function file_sha() {
echo $(openssl sha1 $1 | awk '{print $2}')
}
function cache_dir() {
echo "${NPM_INJECT_CACHE_DIR}/${NODE_VERSION}-${NODE_ENV}/$1"
}
set -e
[[ -n ${DEBUG} ]] && set -x
INSTALL="false"
ARGUMENTS=$@
NPM=$(which -a npm | sed -n 2p) # Ищем оригинальный npm
: ${NPM_INJECT_CACHE_DIR:=${HOME}/.cache/npm-inject}
: ${NODE_VERSION:=$(node --version)}
# Если NODE_ENV=production, npm не установит модули из devDependencies.
# https://docs.npmjs.com/cli/install
: ${NODE_ENV:=development}
while [ "$#" -gt "0" ]; do
case $1 in
i|install)
INSTALL="true"
;;
esac
shift
done
# Если в параметрах нет i или install, вызываем оригинальный npm
if [[ ${INSTALL} == "false" ]]; then
${NPM} ${ARGUMENTS}
exit $?
fi
echo "==> Running npm wrapper script with node_modules caching"
# Если существует переменная времени жизни кэша, то ищем просроченные кэши
if [[ -n ${NPM_CACHE_EXPIRE_DAYS} ]]; then
echo "Looking for expired cache"
EXPIRED_DIRS=$(find ${NPM_INJECT_CACHE_DIR} -maxdepth 1 -mtime +${NPM_CACHE_EXPIRE_DAYS} ! -path ${NPM_INJECT_CACHE_DIR} -type d)
if [[ -n ${EXPIRED_DIRS} ]]; then
for EXPIRED_DIR in ${EXPIRED_DIRS}; do
echo "Clear expired cache: ${EXPIRED_DIR}"
rm -rf "${EXPIRED_DIR}"
done
else
echo "No expired cache found"
fi
fi
PACKAGE_LOCK="${PWD}/package-lock.json"
SHRINKWRAP="${PWD}/npm-shrinkwrap.json"
PACKAGE_DEPS="${PWD}/package.json"
if [[ -f ${SHRINKWRAP} ]]; then
PACKAGE_DEPS=${SHRINKWRAP}
fi
if [[ -f ${PACKAGE_LOCK} ]]; then
PACKAGE_DEPS=${PACKAGE_LOCK}
fi
PACKAGES_HASH=$(file_sha ${PACKAGE_DEPS})
echo "sha1 of ${PACKAGE_DEPS} is ${PACKAGES_HASH}"
NODE_MODULES="${PWD}/node_modules"
PACKAGES_CACHE_DIR=$(cache_dir ${PACKAGES_HASH})
# Удаляем существующие модули, могли протухнуть
echo "Removing existing node_modules if any"
rm -rf "${NODE_MODULES}"
# Если существует кэш, слинковать его в $NODE_MODULES
if [[ -d ${PACKAGES_CACHE_DIR} ]]; then
echo "Cache found: ${PACKAGES_CACHE_DIR}"
else
echo "Cache not found"
# Вызываем оригинальный npm
echo "==> Executing: ${NPM} ${ARGUMENTS}"
${NPM} ${ARGUMENTS}
NPM_EXIT_CODE=$?
if [[ ${NPM_EXIT_CODE} -ne 0 ]]; then
echo "Something went wrong!"
exit ${NPM_EXIT_CODE}
fi
# npm i может изменить файл package-lock.json во время установки из-за мягких зависимостей
INSTALLED_PACKAGES_HASH=$(file_sha ${PACKAGE_DEPS})
if [[ ${PACKAGES_HASH} != ${INSTALLED_PACKAGES_HASH} ]]; then
echo "${PACKAGE_DEPS} was changed during installation"
echo "changed sha1 of ${PACKAGE_DEPS} is ${INSTALLED_PACKAGES_HASH}"
PACKAGES_CACHE_DIR=$(cache_dir ${INSTALLED_PACKAGES_HASH})
fi
echo "==> Creating ${PACKAGES_CACHE_DIR}"
mkdir -p "${PACKAGES_CACHE_DIR}"
echo "Caching ${NODE_MODULES}"
mv "${NODE_MODULES}" "${PACKAGES_CACHE_DIR}"
fi
if [[ -n ${NPM_INJECT_COPY} ]]; then
echo "Copying ${PACKAGES_CACHE_DIR}/node_modules to ${NODE_MODULES}"
cp -RP "${PACKAGES_CACHE_DIR}/node_modules" "${NODE_MODULES}"
else
echo "Linking ${PACKAGES_CACHE_DIR}/node_modules to ${NODE_MODULES}"
ln -s "${PACKAGES_CACHE_DIR}/node_modules" "${NODE_MODULES}"
fi