Using the NativeScript CLI to build an Android app took around 6 minutes on a Windows system compared to around 1 minute on our old Mac.
Debugging showed that the process hangs for 3 minutes when trying to get the currently installed npm version in this script.
To get the npm version, NativeScript executes the command npm -v
in a child process and waits for the output.
It seemed strange that this alone took 3 minutes to complete. I wrote this script to test in isolation. The callback function is called just before the close event occurs. Without a timeout this happens after 3 minutes. When setting a timeout, the close event is fired after the timeout period.
Expected output:
2018-6-13 13:15:32 - START
2018-6-13 13:15:33 - DATA - npm version: 5.6.0
2018-6-13 13:15:33 - EXIT - 0
childProcess.exec: 934.978ms
2018-6-13 13:15:37 - CLOSE - 0
Actual output without an expicit timeout:
2018-6-13 13:15:32 - START
2018-6-13 13:15:33 - DATA - npm version: 5.6.0
2018-6-13 13:15:33 - EXIT - 0
childProcess.exec: 189416.095ms
2018-6-13 13:18:31 - CLOSE - 0
Actual output with an timeout of 10 seconds:
2018-6-13 10:32:34 - START
2018-6-13 10:32:35 - DATA - npm version: 5.6.0
2018-6-13 10:32:35 - EXIT - 0
childProcess.exec: 10019.768ms
2018-6-13 10:32:43 - CLOSE - 0
It seemed that something was preventing the child process from closing. I added the wtfnode module to see open handles. Testing different node/npm combinations revealed that this "error" started to occur with npm version 4.4.0 (the node version did not make a difference).
npm | Node 4.9.1 | Node 6.11.2 | Node 7.10.1 | Node 8.11.3 | Node 9.11.2 | Node 4.9.1 |
---|---|---|---|---|---|---|
2.15.12 | ok | ok | ok | ok | ok | ok |
3.10.10 | ok | ok | ok | ok | ok | ok |
4.2.0 | ok | ok | ok | ok | ok | ok |
4.3.0 | ok | ok | ok | ok | ok | ok |
4.4.0 | - | - | - | - | - | - |
4.6.1 | - | - | - | - | - | - |
5.6.0 | - | - | - | - | - | - |
5.10.0 | - | - | - | - | - | - |
6.1.0 | - | - | - | - | - | - |
npm 4.4.0 introduced an update notification feature. When behind a corporate proxy (like we are) the update check can't be completed and times out after 3 minutes. Only then the child process is closed and the script execution goes on.
The update check feature uses the update-notifier package that uses the latest-version package which in turn uses package-json. package-json currently does not support proxies and the author seems not to be willing to implement proxy support.
See https://github.com/yeoman/update-notifier#user-settings
- Set environment variable
NO_UPDATE_NOTIFIER=1
- Use
--no-update-notifier
flag - Set
"optOut": true
in~/.config/configstore/update-notifier-[your-module-name].json
- Skip update check if a proxy is used (check if proxy variables are set in npm config?)
- Implement a (short) timeout for the proxy check and kill the child process after that (would have to be implemented in update-notifier package
- Use another module for the update check that has proxy support
- Use another method to get the latest npm version from the registry that relies on the npm proxy configuration (
npm outdated
,npm view
)