Compare commits
10 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
39d9a42c35 | |
|
|
2c0c34f10e | |
|
|
c2f740ab38 | |
|
|
6cfaede5a0 | |
|
|
1875fe8b40 | |
|
|
81f0f3ec19 | |
|
|
fb4538b360 | |
|
|
d004c6b064 | |
|
|
79ad72d116 | |
|
|
ccd442d833 |
109
README.md
109
README.md
|
|
@ -203,7 +203,7 @@ If you're running a system without prepackaged binary available, which means you
|
|||
|
||||
**Note:** On OS X, if you do not have Xcode installed and you do not wish to download the ~4.3GB file, you can install the `Command Line Tools`. You can check out this blog post on how to just that:
|
||||
|
||||
- [How to Install Command Line Tools in OS X Mavericks & Yosemite (Without Xcode)](http://osxdaily.com/2014/02/12/install-command-line-tools-mac-os-x/)
|
||||
- [How to Install Command Line Tools in OS X Mavericks & Yosemite (Without Xcode)](https://osxdaily.com/2014/02/12/install-command-line-tools-mac-os-x/)
|
||||
|
||||
**Note:** On OS X, if you have/had a "system" node installed and want to install modules globally, keep in mind that:
|
||||
|
||||
|
|
@ -890,7 +890,7 @@ To change the user directory and/or account name follow the instructions [here](
|
|||
[3]: https://travis-ci.org/nvm-sh/nvm
|
||||
[4]: https://github.com/nvm-sh/nvm/releases/tag/v0.39.1
|
||||
[Urchin]: https://github.com/scraperwiki/urchin
|
||||
[Fish]: http://fishshell.com
|
||||
[Fish]: https://fishshell.com
|
||||
|
||||
**Homebrew makes zsh directories unsecure**
|
||||
|
||||
|
|
@ -903,57 +903,70 @@ Homebrew causes insecure directories like `/usr/local/share/zsh/site-functions`
|
|||
|
||||
**Macs with M1 chip**
|
||||
|
||||
_January 2021:_ there are no pre-compiled NodeJS binaries for versions prior to 15.x for Apple's new M1 chip (arm64 architecture).
|
||||
Experimental support for the M1 architecture was added in node.js v15.3 and full support was added in v16.0.
|
||||
Because of this, if you try to install older versions of node as usual, you will probably experience either compilation errors when installing node or out-of-memory errors while running your code.
|
||||
|
||||
Some issues you may encounter:
|
||||
So, if you want to run a version prior to v16.0 on an M1 Mac, it may be best to compile node targeting the x86_64 Intel architecture so that Rosetta 2 can translate the x86_64 processor instructions to ARM-based Apple Silicon instructions.
|
||||
Here's what you will need to do:
|
||||
|
||||
- using `nvm` to install, say, `v14.15.4`:
|
||||
- the C code compiles successfully
|
||||
- but crashes with an out of memory error when used
|
||||
- increasing the memory available to node still produces the out of memory errors:
|
||||
```sh
|
||||
$ NODE_OPTIONS="--max-old-space-size=4096" ./node_modules/.bin/your_node_package
|
||||
```
|
||||
- when using `nvm` to install some versions, the compilation fails
|
||||
- after `nvm` successfully compiles some versions, `yarn` or `npm` may later fail to install packages with an `incorrect data check` error.
|
||||
- Install Rosetta, if you haven't already done so
|
||||
|
||||
One solution to this issue is to change the architecture of your shell from arm64 to x86.
|
||||
```sh
|
||||
$ softwareupdate --install-rosetta
|
||||
```
|
||||
|
||||
Let's assume that:
|
||||
- you already have versions `12.20.1` and `14.15.4` installed using `nvm`
|
||||
- the current version in use is `14.15.4`
|
||||
- you are using the `zsh` shell
|
||||
- you have Rosetta 2 installed (macOS prompts you to install Rosetta 2 the first time you open a Intel-only non-command-line application, or you may install Rosetta 2 from the command line with `softwareupdate --install-rosetta`)
|
||||
You might wonder, "how will my M1 Mac know to use Rosetta for a version of node compiled for an Intel chip?".
|
||||
If an executable contains only Intel instructions, macOS will automatically use Rosetta to translate the instructions.
|
||||
|
||||
```sh
|
||||
# Check what version you're running:
|
||||
$ node --version
|
||||
v14.15.4
|
||||
# Check architecture of the `node` binary:
|
||||
$ node -p process.arch
|
||||
arm64
|
||||
# This confirms that the arch is for the M1 chip, which is causing the problems.
|
||||
# So we need to uninstall it.
|
||||
# We can't uninstall the version we are currently using, so switch to another version:
|
||||
$ nvm install v12.20.1
|
||||
# Now uninstall the version we want to replace:
|
||||
$ nvm uninstall v14.15.4
|
||||
# Launch a new zsh process under the 64-bit X86 architecture:
|
||||
$ arch -x86_64 zsh
|
||||
# Install node using nvm. This should download the precompiled x64 binary:
|
||||
$ nvm install v14.15.4
|
||||
# Now check that the architecture is correct:
|
||||
$ node -p process.arch
|
||||
x64
|
||||
# It is now safe to return to the arm64 zsh process:
|
||||
$ exit
|
||||
# We're back to a native shell:
|
||||
$ arch
|
||||
arm64
|
||||
# And the new version is now available to use:
|
||||
$ nvm use v14.15.4
|
||||
Now using node v14.15.4 (npm v6.14.10)
|
||||
```
|
||||
- Open a shell that's running using Rosetta
|
||||
|
||||
```sh
|
||||
$ arch -x86_64 zsh
|
||||
```
|
||||
|
||||
Note: This same thing can also be accomplished by finding the Terminal or iTerm App in Finder, right clicking, selecting "Get Info", and then checking the box labeled "Open using Rosetta".
|
||||
|
||||
Note: This terminal session is now running in `zsh`.
|
||||
If `zsh` is not the shell you typically use, `nvm` may not be `source`'d automatically like it probably is for your usual shell through your dotfiles.
|
||||
If that's the case, make sure to source `nvm`.
|
||||
|
||||
```sh
|
||||
$ source "${NVM_DIR}/.nvm/nvm.sh"
|
||||
```
|
||||
|
||||
- Install whatever older version of node you are interested in. Let's use 12.22.1 as an example.
|
||||
This will fetch the node source code and compile it, which will take several minutes.
|
||||
|
||||
```sh
|
||||
$ nvm install v12.22.1 --shared-zlib
|
||||
```
|
||||
|
||||
Note: You're probably curious why `--shared-zlib` is included.
|
||||
There's a bug in recent versions of Apple's system `clang` compiler.
|
||||
If one of these broken versions is installed on your system, the above step will likely still succeed even if you didn't include the `--shared-zlib` flag.
|
||||
However, later, when you attempt to `npm install` something using your old version of node.js, you will see `incorrect data check` errors.
|
||||
If you want to avoid the possible hassle of dealing with this, include that flag.
|
||||
For more details, see [this issue](https://github.com/nodejs/node/issues/39313) and [this comment](https://github.com/nodejs/node/issues/39313#issuecomment-902395576)
|
||||
|
||||
- Exit back to your native shell.
|
||||
|
||||
```sh
|
||||
$ exit
|
||||
$ arch
|
||||
arm64
|
||||
```
|
||||
|
||||
Note: If you selected the box labeled "Open using Rosetta" rather than running the CLI command in the second step, you will see `i386` here.
|
||||
Unless you have another reason to have that box selected, you can deselect it now.
|
||||
|
||||
- Check to make sure the architecture is correct. `x64` is the abbreviation for x86_64, which is what you want to see.
|
||||
|
||||
```sh
|
||||
$ node -p process.arch
|
||||
x64
|
||||
```
|
||||
|
||||
Now you should be able to use node as usual.
|
||||
|
||||
## Maintainers
|
||||
|
||||
|
|
|
|||
12
install.sh
12
install.sh
|
|
@ -10,6 +10,12 @@ nvm_echo() {
|
|||
command printf %s\\n "$*" 2>/dev/null
|
||||
}
|
||||
|
||||
if [ -z "${BASH_VERSION}" ] || [ -n "${ZSH_VERSION}" ]; then
|
||||
# shellcheck disable=SC2016
|
||||
nvm_echo >&2 'Error: the install instructions explicitly say to pipe the install script to `bash`; please follow them'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
nvm_grep() {
|
||||
GREP_OPTIONS='' command grep "$@"
|
||||
}
|
||||
|
|
@ -356,6 +362,12 @@ nvm_do_install() {
|
|||
exit 1
|
||||
fi
|
||||
fi
|
||||
if nvm_has xcode-select && [ "$(xcode-select -p >/dev/null 2>/dev/null ; echo $?)" = '2' ] && [ "$(which git)" = '/usr/bin/git' ] && [ "$(which curl)" = '/usr/bin/curl' ]; then
|
||||
nvm_echo >&2 'You may be on a Mac, and need to install the Xcode Command Line Developer Tools.'
|
||||
# shellcheck disable=SC2016
|
||||
nvm_echo >&2 'If so, run `xcode-select --install` and try again. If not, please report this!'
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${METHOD}" ]; then
|
||||
# Autodetect install method
|
||||
if nvm_has git; then
|
||||
|
|
|
|||
96
nvm.sh
96
nvm.sh
|
|
@ -101,15 +101,15 @@ nvm_get_latest() {
|
|||
if nvm_curl_use_compression; then
|
||||
CURL_COMPRESSED_FLAG="--compressed"
|
||||
fi
|
||||
NVM_LATEST_URL="$(curl ${CURL_COMPRESSED_FLAG:-} -q -w "%{url_effective}\\n" -L -s -S http://latest.nvm.sh -o /dev/null)"
|
||||
NVM_LATEST_URL="$(curl ${CURL_COMPRESSED_FLAG:-} -q -w "%{url_effective}\\n" -L -s -S https://latest.nvm.sh -o /dev/null)"
|
||||
elif nvm_has "wget"; then
|
||||
NVM_LATEST_URL="$(wget -q http://latest.nvm.sh --server-response -O /dev/null 2>&1 | command awk '/^ Location: /{DEST=$2} END{ print DEST }')"
|
||||
NVM_LATEST_URL="$(wget -q https://latest.nvm.sh --server-response -O /dev/null 2>&1 | command awk '/^ Location: /{DEST=$2} END{ print DEST }')"
|
||||
else
|
||||
nvm_err 'nvm needs curl or wget to proceed.'
|
||||
return 1
|
||||
fi
|
||||
if [ -z "${NVM_LATEST_URL}" ]; then
|
||||
nvm_err "http://latest.nvm.sh did not redirect to the latest release on GitHub"
|
||||
nvm_err "https://latest.nvm.sh did not redirect to the latest release on GitHub"
|
||||
return 2
|
||||
fi
|
||||
nvm_echo "${NVM_LATEST_URL##*/}"
|
||||
|
|
@ -1870,9 +1870,12 @@ nvm_get_arch() {
|
|||
*) NVM_ARCH="${HOST_ARCH}" ;;
|
||||
esac
|
||||
|
||||
# If running a 64bit ARM kernel but a 32bit ARM userland, change ARCH to 32bit ARM (armv7l)
|
||||
L=$(ls -dl /sbin/init 2>/dev/null) # if /sbin/init is 32bit executable
|
||||
if [ "$(uname)" = "Linux" ] && [ "${NVM_ARCH}" = arm64 ] && [ "$(od -An -t x1 -j 4 -N 1 "${L#*-> }")" = ' 01' ]; then
|
||||
# If running a 64bit ARM kernel but a 32bit ARM userland,
|
||||
# change ARCH to 32bit ARM (armv7l) if /sbin/init is 32bit executable
|
||||
local L
|
||||
if [ "$(uname)" = "Linux" ] && [ "${NVM_ARCH}" = arm64 ] &&
|
||||
L="$(ls -dl /sbin/init 2>/dev/null)" &&
|
||||
[ "$(od -An -t x1 -j 4 -N 1 "${L#*-> }")" = ' 01' ]; then
|
||||
NVM_ARCH=armv7l
|
||||
HOST_ARCH=armv7l
|
||||
fi
|
||||
|
|
@ -1971,19 +1974,7 @@ nvm_install_binary_extract() {
|
|||
command unzip -q "${TARBALL}" -d "${TMPDIR}" || return 1
|
||||
# For non Windows system (including WSL running on Windows)
|
||||
else
|
||||
local tar_compression_flag
|
||||
tar_compression_flag='z'
|
||||
if nvm_supports_xz "${VERSION}"; then
|
||||
tar_compression_flag='J'
|
||||
fi
|
||||
|
||||
local tar
|
||||
if [ "${NVM_OS}" = 'aix' ]; then
|
||||
tar='gtar'
|
||||
else
|
||||
tar='tar'
|
||||
fi
|
||||
command "${tar}" -x${tar_compression_flag}f "${TARBALL}" -C "${TMPDIR}" --strip-components 1 || return 1
|
||||
nvm_extract_tarball "${NVM_OS}" "${VERSION}" "${TARBALL}" "${TMPDIR}"
|
||||
fi
|
||||
|
||||
command mkdir -p "${VERSION_PATH}" || return 1
|
||||
|
|
@ -2251,6 +2242,48 @@ nvm_download_artifact() {
|
|||
nvm_echo "${TARBALL}"
|
||||
}
|
||||
|
||||
# args: nvm_os, version, tarball, tmpdir
|
||||
nvm_extract_tarball() {
|
||||
if [ "$#" -ne 4 ]; then
|
||||
nvm_err 'nvm_extract_tarball requires exactly 4 arguments'
|
||||
return 5
|
||||
fi
|
||||
|
||||
local NVM_OS
|
||||
NVM_OS="${1-}"
|
||||
|
||||
local VERSION
|
||||
VERSION="${2-}"
|
||||
|
||||
local TARBALL
|
||||
TARBALL="${3-}"
|
||||
|
||||
local TMPDIR
|
||||
TMPDIR="${4-}"
|
||||
|
||||
local tar_compression_flag
|
||||
tar_compression_flag='z'
|
||||
if nvm_supports_xz "${VERSION}"; then
|
||||
tar_compression_flag='J'
|
||||
fi
|
||||
|
||||
local tar
|
||||
tar='tar'
|
||||
if [ "${NVM_OS}" = 'aix' ]; then
|
||||
tar='gtar'
|
||||
fi
|
||||
|
||||
if [ "${NVM_OS}" = 'openbsd' ]; then
|
||||
if [ "${tar_compression_flag}" = 'J' ]; then
|
||||
command xzcat "${TARBALL}" | "${tar}" -xf - -C "${TMPDIR}" -s '/[^\/]*\///' || return 1
|
||||
else
|
||||
command "${tar}" -x${tar_compression_flag}f "${TARBALL}" -C "${TMPDIR}" -s '/[^\/]*\///' || return 1
|
||||
fi
|
||||
else
|
||||
command "${tar}" -x${tar_compression_flag}f "${TARBALL}" -C "${TMPDIR}" --strip-components 1 || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
nvm_get_make_jobs() {
|
||||
if nvm_is_natural_num "${1-}"; then
|
||||
NVM_MAKE_JOBS="$1"
|
||||
|
|
@ -2362,18 +2395,6 @@ nvm_install_source() {
|
|||
fi
|
||||
fi
|
||||
|
||||
local tar_compression_flag
|
||||
tar_compression_flag='z'
|
||||
if nvm_supports_xz "${VERSION}"; then
|
||||
tar_compression_flag='J'
|
||||
fi
|
||||
|
||||
local tar
|
||||
tar='tar'
|
||||
if [ "${NVM_OS}" = 'aix' ]; then
|
||||
tar='gtar'
|
||||
fi
|
||||
|
||||
local TARBALL
|
||||
local TMPDIR
|
||||
local VERSION_PATH
|
||||
|
|
@ -2393,7 +2414,7 @@ nvm_install_source() {
|
|||
if ! (
|
||||
# shellcheck disable=SC2086
|
||||
command mkdir -p "${TMPDIR}" && \
|
||||
command "${tar}" -x${tar_compression_flag}f "${TARBALL}" -C "${TMPDIR}" --strip-components 1 && \
|
||||
nvm_extract_tarball "${NVM_OS}" "${VERSION}" "${TARBALL}" "${TMPDIR}" && \
|
||||
VERSION_PATH="$(nvm_version_path "${PREFIXED_VERSION}")" && \
|
||||
nvm_cd "${TMPDIR}" && \
|
||||
nvm_echo '$>'./configure --prefix="${VERSION_PATH}" $ADDITIONAL_PARAMETERS'<' && \
|
||||
|
|
@ -2723,6 +2744,15 @@ nvm() {
|
|||
EXIT_CODE="$?"
|
||||
set -a
|
||||
return "$EXIT_CODE"
|
||||
elif [ -n "${BASH-}" ] && [ "${-#*E}" != "$-" ]; then
|
||||
# shellcheck disable=SC3041
|
||||
set +E
|
||||
local EXIT_CODE
|
||||
IFS="${DEFAULT_IFS}" nvm "$@"
|
||||
EXIT_CODE="$?"
|
||||
# shellcheck disable=SC3041
|
||||
set -E
|
||||
return "$EXIT_CODE"
|
||||
elif [ "${IFS}" != "${DEFAULT_IFS}" ]; then
|
||||
IFS="${DEFAULT_IFS}" nvm "$@"
|
||||
return "$?"
|
||||
|
|
@ -4151,7 +4181,7 @@ nvm() {
|
|||
nvm_npmrc_bad_news_bears \
|
||||
nvm_get_colors nvm_set_colors nvm_print_color_code nvm_format_help_message_colors \
|
||||
nvm_echo_with_colors nvm_err_with_colors \
|
||||
nvm_get_artifact_compression nvm_install_binary_extract \
|
||||
nvm_get_artifact_compression nvm_install_binary_extract nvm_extract_tarball \
|
||||
>/dev/null 2>&1
|
||||
unset NVM_RC_VERSION NVM_NODEJS_ORG_MIRROR NVM_IOJS_ORG_MIRROR NVM_DIR \
|
||||
NVM_CD_FLAGS NVM_BIN NVM_INC NVM_MAKE_JOBS \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
#!/bin/sh
|
||||
|
||||
die () { echo "$@" ; exit 1; }
|
||||
|
||||
\. ../../../nvm.sh
|
||||
|
||||
[ "$(nvm_extract_tarball 2>&1)" = "nvm_extract_tarball requires exactly 4 arguments" ] || die 'incorrect error message with no args'
|
||||
[ "$(nvm_extract_tarball > /dev/null 2>&1 ; echo $?)" = "5" ] || die 'incorrect error code with no args'
|
||||
[ "$(nvm_extract_tarball one two three 2>&1)" = "nvm_extract_tarball requires exactly 4 arguments" ] || die 'incorrect error message with three args'
|
||||
[ "$(nvm_extract_tarball one two three > /dev/null 2>&1 ; echo $?)" = "5" ] || die 'incorrect error code with three args'
|
||||
[ "$(nvm_extract_tarball one two three four five 2>&1)" = "nvm_extract_tarball requires exactly 4 arguments" ] || die 'incorrect error message with five args'
|
||||
[ "$(nvm_extract_tarball one two three four five > /dev/null 2>&1 ; echo $?)" = "5" ] || die 'incorrect error code with five args'
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
cleanup() {
|
||||
nvm cache clear
|
||||
nvm deactivate
|
||||
rm -rf "${NVM_DIR}"/v*
|
||||
nvm unalias default
|
||||
}
|
||||
|
||||
die() {
|
||||
echo "$@"
|
||||
cleanup || true
|
||||
exit 1
|
||||
}
|
||||
|
||||
\. ../../nvm.sh
|
||||
|
||||
if [ -z "${BASH-}" ]; then
|
||||
echo "This test only applies to Bash; skipping"
|
||||
exit
|
||||
fi
|
||||
|
||||
cleanup || true
|
||||
trap 'echo "==> EXIT signal received (status: $?)"; cleanup' EXIT
|
||||
|
||||
# shellcheck disable=SC3047
|
||||
trap 'echo "==> ERR signal received"; exit 1' ERR
|
||||
# shellcheck disable=SC3041
|
||||
set -E
|
||||
|
||||
# shellcheck disable=SC3045,SC3047
|
||||
ERR_TRAP_EXPECTED="$(trap -p ERR)"
|
||||
|
||||
# Adding ` || die 'install failed'` implicitly disables error handling and
|
||||
# prevents ERR trap execution, so for the purposes of this test, `nvm install`
|
||||
# can't be part of another command or statement
|
||||
nvm install node
|
||||
|
||||
case "$-" in
|
||||
*E*)
|
||||
# shellcheck disable=SC3045,SC3047
|
||||
[ "$(trap -p ERR)" = "$ERR_TRAP_EXPECTED" ] ||
|
||||
die "ERR trap not restored after \"nvm install $VERSION\""
|
||||
;;
|
||||
*)
|
||||
die "errtrace not restored after \"nvm install $VERSION\""
|
||||
;;
|
||||
esac
|
||||
|
|
@ -10,8 +10,8 @@ cleanup() {
|
|||
|
||||
EXPECTED_VERSION="v12.3.456"
|
||||
URL="https://github.com/nvm-sh/nvm/releases/tag/$EXPECTED_VERSION"
|
||||
EXPECTED_CURL_ARGS="--compressed -q -w %{url_effective}\n -L -s -S http://latest.nvm.sh -o /dev/null"
|
||||
EXPECTED_WGET_ARGS="-q http://latest.nvm.sh --server-response -O /dev/null"
|
||||
EXPECTED_CURL_ARGS="--compressed -q -w %{url_effective}\n -L -s -S https://latest.nvm.sh -o /dev/null"
|
||||
EXPECTED_WGET_ARGS="-q https://latest.nvm.sh --server-response -O /dev/null"
|
||||
|
||||
curl() {
|
||||
if [ $# -eq 1 ] && [ "$1" = "-V" ]; then
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ wget() {
|
|||
|
||||
OUTPUT="$(nvm_get_latest 2>&1)"
|
||||
EXIT_CODE="$(nvm_get_latest >/dev/null 2>&1 ; echo $?)"
|
||||
[ "_$OUTPUT" = "_http://latest.nvm.sh did not redirect to the latest release on GitHub" ] \
|
||||
[ "_$OUTPUT" = "_https://latest.nvm.sh did not redirect to the latest release on GitHub" ] \
|
||||
|| die "failed redirect did not report correct error message, got '$OUTPUT'"
|
||||
[ "_$EXIT_CODE" = "_2" ] \
|
||||
|| die "failed redirect did not exit with code 2, got $EXIT_CODE"
|
||||
|
|
|
|||
Loading…
Reference in New Issue