2

I work in a corporate environment where everything must be proxied (or air gapped). We have Artifactory Pro in place to mirror Maven Central, NPM Registry and DockerHub. We have been using Maven for years and it works wonders. We have recently started tackling front-end development with Angular through Node.js and npm. Security requirement remains the same.

When creating a new Angular project using Angular CLI (ng new my-app), several hundreds of npm dependencies are fetched from our corporate Artifactory instance, which is expected. However, the process fails after a few minutes with the following message:

[...]

CREATE my-app5/e2e/src/app.e2e-spec.ts (299 bytes)
CREATE my-app5/e2e/src/app.po.ts (204 bytes)
npm WARN deprecated circular-json@0.5.9: CircularJSON is in maintenance only, flatted is its successor.
                                                                                                                                                                                                    ms)
> node-sass@4.10.0 install C:\dev\angular\my-app5\node_modules\node-sass
> node scripts/install.js

Downloading binary from https://github.com/sass/node-sass/releases/download/v4.10.0/win32-x64-64_binding.node
Cannot download "https://github.com/sass/node-sass/releases/download/v4.10.0/win32-x64-64_binding.node":

getaddrinfo ENOTFOUND github.com github.com:443

Hint: If github.com is not accessible in your location
      try setting a proxy via HTTP_PROXY, e.g.

      export HTTP_PROXY=http://example.com:1234

or configure npm proxy via

      npm config set proxy http://example.com:8080

> node-sass@4.10.0 postinstall C:\dev\angular\my-app5\node_modules\node-sass
> node scripts/build.js

Building: C:\Program Files\nodejs\node.exe C:\dev\angular\my-app5\node_modules\node-gyp\bin\node-gyp.js rebuild --verbose --libsass_ext= --libsass_cflags= --libsass_ldflags= --libsass_library=
gyp info it worked if it ends with ok
gyp verb cli [ 'C:\\Program Files\\nodejs\\node.exe',
gyp verb cli   'C:\\dev\\angular\\my-app5\\node_modules\\node-gyp\\bin\\node-gyp.js',
gyp verb cli   'rebuild',
gyp verb cli   '--verbose',
gyp verb cli   '--libsass_ext=',
gyp verb cli   '--libsass_cflags=',
gyp verb cli   '--libsass_ldflags=',
gyp verb cli   '--libsass_library=' ]
gyp info using node-gyp@3.8.0
gyp info using node@10.13.0 | win32 | x64
gyp verb command rebuild []
gyp verb command clean []
gyp verb clean removing "build" directory
gyp verb command configure []
gyp verb check python checking for Python executable "python2" in the PATH
gyp verb `which` failed Error: not found: python2
gyp verb `which` failed     at getNotFoundError (C:\dev\angular\my-app5\node_modules\which\which.js:13:12)
gyp verb `which` failed     at F (C:\dev\angular\my-app5\node_modules\which\which.js:68:19)
gyp verb `which` failed     at E (C:\dev\angular\my-app5\node_modules\which\which.js:80:29)
gyp verb `which` failed     at C:\dev\angular\my-app5\node_modules\which\which.js:89:16
gyp verb `which` failed     at C:\dev\angular\my-app5\node_modules\isexe\index.js:42:5
gyp verb `which` failed     at C:\dev\angular\my-app5\node_modules\isexe\windows.js:36:5
gyp verb `which` failed     at FSReqWrap.oncomplete (fs.js:154:21)
gyp verb `which` failed  python2 { Error: not found: python2
gyp verb `which` failed     at getNotFoundError (C:\dev\angular\my-app5\node_modules\which\which.js:13:12)
gyp verb `which` failed     at F (C:\dev\angular\my-app5\node_modules\which\which.js:68:19)
gyp verb `which` failed     at E (C:\dev\angular\my-app5\node_modules\which\which.js:80:29)
gyp verb `which` failed     at C:\dev\angular\my-app5\node_modules\which\which.js:89:16
gyp verb `which` failed     at C:\dev\angular\my-app5\node_modules\isexe\index.js:42:5
gyp verb `which` failed     at C:\dev\angular\my-app5\node_modules\isexe\windows.js:36:5
gyp verb `which` failed     at FSReqWrap.oncomplete (fs.js:154:21)
gyp verb `which` failed   stack:
gyp verb `which` failed    'Error: not found: python2\n    at getNotFoundError (C:\\dev\\angular\\my-app5\\node_modules\\which\\which.js:13:12)\n    at F (C:\\dev\\angular\\my-app5\\node_modules\\which\\which.js:68:19)\n    at E (C:\\dev\\angular\\my-app5\\node_modules\\which\\which.js:80:29)\n    at C:\\dev\\angular\\my-app5\\node_modules\\which\\which.js:89:16\n    at C:\\dev\\angular\\my-app5\\node_modules\\isexe\\index.js:42:5\n    at C:\\dev\\angular\\my-app5\\node_modules\\isexe\\windows.js:36:5\n    at FSReqWrap.oncomplete (fs.js:154:21)',
gyp verb `which` failed   code: 'ENOENT' }
gyp verb check python checking for Python executable "python" in the PATH
gyp verb `which` failed Error: not found: python
gyp verb `which` failed     at getNotFoundError (C:\dev\angular\my-app5\node_modules\which\which.js:13:12)
gyp verb `which` failed     at F (C:\dev\angular\my-app5\node_modules\which\which.js:68:19)
gyp verb `which` failed     at E (C:\dev\angular\my-app5\node_modules\which\which.js:80:29)
gyp verb `which` failed     at C:\dev\angular\my-app5\node_modules\which\which.js:89:16
gyp verb `which` failed     at C:\dev\angular\my-app5\node_modules\isexe\index.js:42:5
gyp verb `which` failed     at C:\dev\angular\my-app5\node_modules\isexe\windows.js:36:5
gyp verb `which` failed     at FSReqWrap.oncomplete (fs.js:154:21)
gyp verb `which` failed  python { Error: not found: python
gyp verb `which` failed     at getNotFoundError (C:\dev\angular\my-app5\node_modules\which\which.js:13:12)
gyp verb `which` failed     at F (C:\dev\angular\my-app5\node_modules\which\which.js:68:19)
gyp verb `which` failed     at E (C:\dev\angular\my-app5\node_modules\which\which.js:80:29)
gyp verb `which` failed     at C:\dev\angular\my-app5\node_modules\which\which.js:89:16
gyp verb `which` failed     at C:\dev\angular\my-app5\node_modules\isexe\index.js:42:5
gyp verb `which` failed     at C:\dev\angular\my-app5\node_modules\isexe\windows.js:36:5
gyp verb `which` failed     at FSReqWrap.oncomplete (fs.js:154:21)
gyp verb `which` failed   stack:
gyp verb `which` failed    'Error: not found: python\n    at getNotFoundError (C:\\dev\\angular\\my-app5\\node_modules\\which\\which.js:13:12)\n    at F (C:\\dev\\angular\\my-app5\\node_modules\\which\\which.js:68:19)\n    at E (C:\\dev\\angular\\my-app5\\node_modules\\which\\which.js:80:29)\n    at C:\\dev\\angular\\my-app5\\node_modules\\which\\which.js:89:16\n    at C:\\dev\\angular\\my-app5\\node_modules\\isexe\\index.js:42:5\n    at C:\\dev\\angular\\my-app5\\node_modules\\isexe\\windows.js:36:5\n    at FSReqWrap.oncomplete (fs.js:154:21)',
gyp verb `which` failed   code: 'ENOENT' }
gyp verb could not find "python". checking python launcher
gyp verb could not find "python". guessing location
gyp verb ensuring that file exists: C:\Python27\python.exe
gyp ERR! configure error
gyp ERR! stack Error: Can't find Python executable "python", you can set the PYTHON env variable.
gyp ERR! stack     at PythonFinder.failNoPython (C:\dev\angular\my-app5\node_modules\node-gyp\lib\configure.js:484:19)
gyp ERR! stack     at PythonFinder.<anonymous> (C:\dev\angular\my-app5\node_modules\node-gyp\lib\configure.js:509:16)
gyp ERR! stack     at C:\dev\angular\my-app5\node_modules\graceful-fs\polyfills.js:282:31
gyp ERR! stack     at FSReqWrap.oncomplete (fs.js:154:21)
gyp ERR! System Windows_NT 10.0.15063
gyp ERR! command "C:\\Program Files\\nodejs\\node.exe" "C:\\dev\\angular\\my-app5\\node_modules\\node-gyp\\bin\\node-gyp.js" "rebuild" "--verbose" "--libsass_ext=" "--libsass_cflags=" "--libsass_ldflags=" "--libsass_library="
gyp ERR! cwd C:\dev\angular\my-app5\node_modules\node-sass
gyp ERR! node -v v10.13.0
gyp ERR! node-gyp -v v3.8.0
gyp ERR! not ok
Build failed with error code: 1
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.2.2 (node_modules\chokidar\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.4: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: abbrev@1.1.1 (node_modules\fsevents\node_modules\abbrev):
npm WARN enoent SKIPPING OPTIONAL DEPENDENCY: ENOENT: no such file or directory, rename 'C:\dev\angular\my-app5\node_modules\fsevents\node_modules\abbrev' -> 'C:\dev\angular\my-app5\node_modules\fsevents\node_modules\.abbrev.DELETE'

[...]

Additional details

  • Angular CLI: 7.1.2
  • Node: 10.13.0
  • OS: win32 x64
  • @angular-devkit/architect: 0.11.2
  • @angular-devkit/core: 7.1.2
  • @angular-devkit/schematics: 7.1.2
  • @schematics/angular: 7.1.2
  • @schematics/update: 0.11.2
  • rxjs: 6.3.3
  • typescript: 3.1.6
  • %USERPROFILE%/.npmrc has our Artifactory instance configured

Bottom line is: I would expect ng new to go through our Artifactory from A to Z, not fetching stuffs from the Internet. Error log mentions setting the proxy, but that URL is blocked in our corporate environment.

Any thoughts?

Charles Morin
  • 1,449
  • 4
  • 32
  • 50
  • Are you working on windows ? If so, you could use cntlm : https://stackoverflow.com/questions/18569054/npm-behind-ntlm-proxy/18570201#18570201 this is what I'm using at work. – Florian Dec 12 '18 at 16:22
  • Which URL is blocked? You have to put your proxy url, which cannot be blocked... – Gustavo Lopes Dec 12 '18 at 16:23
  • `"try setting a proxy via HTTP_PROXY"` Have you tried that? Node-sass downloads pre-built binaries from github, which must also be accessible (proxied). Sorry if the answer for that is obvious given you use Artifactory -- I'm not familiar with it. Ian made a good suggestion below, but note my comment there, as well. – msanford Dec 12 '18 at 16:41
  • GitHub is available in its vast majority, but the following URL (as an example) is blocked: https://github.com/sass/node-sass/releases/download/v4.10.0/win32-x64-64_binding.node ... Setting the proxy doesn't help. Same behavior. – Charles Morin Dec 12 '18 at 21:00

1 Answers1

3

I see the problem. The node-sass install script is hard-coded to fetch from github.

$ npm i --verbose node-sass
   ...
> node scripts/install.js

Downloading binary from https://github.com/sass/node-sass/releases/download/v4.11.0/darwin-x64-64_binding.node

After inspecting the script that it's trying to run (node_modules/node-sass/scripts/install.js), I determined that this extra download can be skipped. It will require the machine to build it locally (once, on initial install), but it should help.

$ SKIP_SASS_BINARY_DOWNLOAD_FOR_CI=true npm i --verbose node-sass

old answer

You can do this with your .npmrc file. Put this in your user home directory if you want it to apply to all your projects (it sounds like you would want this).

registry=<your registry url>
always-auth=true
_auth=<your auth string>
Ian MacDonald
  • 13,472
  • 2
  • 30
  • 51
  • 1
    +1 for a good investigation. Note however that building node-sass locally requires [windows-build-tools](https://www.npmjs.com/package/windows-build-tools), which pulls npms, pips and gems from all over the place, and _might itself_ more be difficult to install than the pre-built in OP's scenario. – msanford Dec 12 '18 at 16:43
  • 2
    Oh. I didn't anticipate that on Windows. It built without needing any extra tooling for me on Mac. :( – Ian MacDonald Dec 12 '18 at 16:55
  • Benefits of being on a *nix-based system. I, too, assumed OP uses my own system, which might not be the case either, but given the corporate air-gapping, I can only assume. – msanford Dec 12 '18 at 17:52
  • That's an interesting workaround. Could we make use of Artifactory VCS Repositories to mirror GitHub and use it as a whitelist of GitHub repositories? Would we be able to have Angular CLI bootstrap script to use that source of truth instead of the hardcoded one? My goal is to keep things as simple as possible for the developers. – Charles Morin Dec 12 '18 at 21:02
  • It sounds to me like you're describing the `HTTP_PROXY` listed in the original message, yes. Your other alternative is to fork `node-sass`, modify its publish registry to your own, then push a change that updates the URL for the binary to a location within your network. – Ian MacDonald Dec 12 '18 at 21:05
  • Just for the record. Artifactory supports a github passthrough method. So you can then say ```export SASS_BINARY_SITE="https://artifactory.yoursite.com/artifactory/github/sass/node-sass/releases/download/"``` and then it will download it from there instead. Nodejs binary files can also be mirrored with artifactory and can work with npm_config_dist_url. (this does mean your admins on artifactory need to create that) – Erik-Jan Riemers Sep 19 '19 at 16:52