SPFx DEV Environment offline installation


This post is about how to create a Development Environment for SharePoint Framework (SPFx) if your box does not have access to the Internet.

Exposition

Microsoft recently published the Feature Pack 2 for SharePoint 2016. The biggest shot in this update is that it makes the long waited SharePoint Framework (SPFx) available for the on-prem customers, which was available for SharePoint Online users since 23rd February 2017. The installation of the framework is a relatively straightforward process, you just have to install Node.JS, Visual Code, Yeoman Generator, and the SharePoint Framework specific toolkit.

The only problem is, that the instructions available currently (like this one from Vesa Juvonen) shows only how to install that if your box has access to the Internet. Of course, since if you are working with SharePoint Online, you're not likely to work on a box without access to the net, but if you are a developer in a locked-down corporate environment, you might have a bit of issue. Let's see how to get around that.

If you want to skip the drama, just jump to the Falling Action section of this post.

Climax

Act 1

To expand the action plan of the SPFx Toolkit installation on a clean machine, this is what you have to do:

  1. Install the latest version of Node.JS.
  2. In a PowerShell window install the Yeoman Generator.
    • npm install -g yo
  3. Still in a PowerShell window install Gulp (for example) for previewing and testing your solution.
    • npm install -g gulp
  4. Still in the PowerShell install the Microsoft SharePoint Framework toolkit
    • npm install -g @microsoft/generator-sharepoint
  5. Finally install the Visual Studio Code (or whatever dev environment you want to use).

My first thought was that I'm just going to use Fiddler to see what is being downloaded when I run the npm installer. Oh, boy, was I wrong... While Fiddler is a great tool most of the times, certain modules are not using the INetProxy configuration, so obviously it won't be aware that there is something trying to sniff the wire, it will simply get around that, so I had to find something else.

Act 2

After a few hours of search I've found a nice little project by Glen R. Goodwin (co-authored by Dan Bornstein and a few others), called NPMBox, which is an "npm addon utility for creating and installing from an archive file of an npm install, including dependencies. This lets you create a "box" of an installable package and move it to an offline system that will only install from that box."

The tool really does work. It indeed is capable of fetching all the packages, and dependencies (almost, but let's not run that fast...), and put it into a nice little file that you can copy onto your locked-down environment and install them offline.

The installation of the Yeoman and Gulp packages went without problem, but the installation of the SharePoint Framework toolkit failed with a naughty error message:

Installing @microsoft/generator-sharepoint...
An error occurred while installing @microsoft/generator-sharepoint.
@microsoft/generator-sharepoint was not installed.

Act 3

This is where I had to come back to the original question, how can I sniff what npm is doing on the network? Fortunately Luke Brendt figured this out already. Well... Not exactly this, but how to use Node.JS behind a proxy.

npm config set strict-ssl false
npm config set registry "http://registry.npmjs.org/"
npm --proxy http://username:password@cacheaddress.com.br:80 install packagename

Given that Fiddler is nothing else, but a proxy, I could use the instructions in his blog entry to configure my machine to use Fiddler as a man in the middle. Awesome... Next installation attempt revealed that the NPMBox package is missing a single component. (http://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.1.0.tgz).

How to put this into the package. Well... That's not an easy job, but why would I bother with that, when Fiddler has a nice AutoResponder function? The only thing needed to be done is saving this file somewhere and creating a nice rule pointing to this file. Something like this:

 

Originally this was the point where I sat back and thought I was the king of the jungle. Until I saw an email from my colleague Koen Zomers highlighting the fact that the Yeoman template will always (or at least from time-to-time) try to connect to the Internet to validate the version of the cached packages. Which of course won't work in a locked down environment. So I pushed forward to pin this one to the ground as well.

I have to admit, the solution I describe here is even more crazy than the previous one. I can but hope that there is an easier solution, or at least something is in the works, because this is really clumsy. Should any of you smart people have an idea, please link it in the comment.

Act 4

Starting the new package creation, when you have a clean environment will give you some spooky error messages, like this:

npm ERR! registry error parsing json
..
npm ERR! Unexpected token F in JSON at position 1
...
npm ERR! The connection to 'registry.npmjs.org' failed. <br />Error: TimedOut (0x274c). <br />System.Net.Sockets.SocketException A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 151.101.36.162:80

 

Obviously this means (as Koen highlighted) that there's no access to the Internet, so certain packages cannot be downloaded.

If you look closely, you can see that the packages are attempted to be downloaded by npm, the same thing that we use for installing packages. This is the Node Package Manager after all. Tiny little problem that we cannot explain Yeoman that it should use the proxy directive, when kicking off npm.

Here came a little digging. Long story short, it seems npm is trying to connect to the Internet directly, and if it cannot, only then it starts looking around for proxy configuration, and attempts to do a second try. But where do we set the proxy configuration? There are two places:

  1. The system environment variables, where you specify it like this:
    • HTTP_PROXY    http://10.2.0.8:8888
    • HTTPS_PROXY  http://10.2.0.9:8888
  2. The WinHTTP configuration
    • NETSH WINHTTP SET PROXY 'http://10.2.0.8:8888'

But... And this is where I used woodoo... For the testing, I've used Azure Virtual Machines. Most of you should be familiar with the fact that by default Azure VMs have direct access to the Internet. So what I did, I configured two VMs.

  1. One that was acting as a proxy.
    • This has Fiddler installed, and
    • Configured to "Allow remote computers to connect"
  2. Another one that was creating the package.
    • This one is using the above mentioned proxy configurations (both the system variable and the WinHTTP), and
    • is creating the new SPFx package with the good old yo @microsoft/sharepoint command.

The result is a nice, currently 97MB trace on the first machine that contains all the calls that Yeoman does when creating a new SPFx package. This trace then can be fed to Fiddler on any machine on the AutoResponder tab as we have discussed it earlier.

I've tested it with two different machines and it works as expected. Even more, subsequent projects created on the same day won't even try to connect to the Internet, but at this point I do not know how often it checks for updates. (Daily maybe?)

If it looks stupid, but it works, it ain't stupid...

 

Falling Action

To summarize, you have two options to install the bits required on a SharePoint Framework DEV Environment:

 

Method 1: Capture the whole installation network traffic and play it back with Fiddler.

  • This is probably the easier way to do it, although it does not make it possible to automate the installation, should you need to create installation packages.
    1. Configure NPM to use HTTP traffic.
npm config set strict-ssl false
npm config set registry "http://registry.npmjs.org/"
    1. Start Fiddler and start capturing.
    2. Install your package using Fiddler as a proxy.
npm --proxy http://username:password@cacheaddress.com.br:80 install packagename
    1. Save all packets from Fiddler.
    2. Transfer the .SAZ file to your locked down box.
    3. Start Fiddler on the locked down box.
    4. Import the .SAZ file into the Autoresponse rules.
    5. Configure the locked down box as you did with the previous one (step 1 in this section).
    6. Run the installation using Fiddler as a proxy, just as you did with the previous one (step 3 in this section.)

 

Method 2: Use NPMBox to package most of the stuff and use Fiddler to replay only the single file that is missing from the package.

  • Personally, I favor this option as this is cleaner and could be packaged in the future, when the guys fix that tiny little problem of the missing file.
    1. Install NPMBox.
npm install -g npmbox
    1. Create an npmbox packate for Yeoman, Gulp and the SharePoint Framework Toolkit.
npmbox --proxy='http://127.0.0.1:8888' -t c:\Temp\NPMBox NPMBox
npmbox --proxy='http://127.0.0.1:8888' -t c:\Temp\Yo yo
npmbox --proxy='http://127.0.0.1:8888' -t c:\Temp\Gulp gulp
npmbox --proxy='http://127.0.0.1:8888' -t c:\Temp\SPFx @microsoft/generator-sharepoint
    1. Configure NPM to use HTTP traffic.
npm config set strict-ssl false
npm config set registry "http://registry.npmjs.org/"
    1. Re-install the SharePoint Framework toolkit using the NPMBox package.
npmunbox --proxy='http://127.0.0.1:8888' -g SPFx
    1. Take note of the URL of the extra package that is loaded by the installer. It's going to be a version of the postcss-modules-extract-imports-1.1.0.tgz module. (Note: this step is required only until the NPMBox guys fix the issue with the missing packet.)
    2. Save the module as a file.
    3. Copy the NPMBox packages and the extra file to the locked down box.
    4. Unpack the NPMBox file. For this you will need to rename the NPMBox.npmbox file to NPMBox.tar. On Windows machines, you'll need to use something like 7ZIP.
    5. Change to the folder where you unpacked the NPMBox package, then install the NPMBox offline on the locked down box
npm install --global --cache .\.npmbox.cache --optional --cache-min 99999999999 --shrinkwrap false npmbox
    1. Install Fiddler and configure an AutoResponder rule for the missing packet with the URL in step 5. (Note: this step is required only until the NPMBox guys fix the issue with the missing packet.)
    2. Use NPMUnbox to install the offline packages.
npmunbox --proxy='http://127.0.0.1:8888' -g Yo
npmunbox --proxy='http://127.0.0.1:8888' -g Gulp
npmunbox --proxy='http://127.0.0.1:8888' -g SPFx

 

Don't forget that you'll need to have a Fiddler trace available with the packages that are required for Yeoman when creating a new SPFx package. See Act 4 for the details.

 

Dénouement

Now that you have a way to deploy a SharePoint Framework (SPFx) environment in any locked down environment, you can test, try, use and spread the word that this is really some good stuff for SharePoint let it be Online or On-prem installation.

Once again, I admit this is hacky. If you have a better solution, I'm open to suggestion. Hopefully someone will implement offline functionality for Yo. Also, this whole thing is only required if you have a locked down environment. But maybe your company will go to the cloud sooner or later and you won't need this hacking. Future is the Cloud, after all. 😉

 

Comments (2)

  1. bdani says:

    I never would have thought this can be so challenging. Nice post:)

  2. Zsolt Illés says:

    Updated the blog entry with some more hacking in Act 4. This contains the workaround for the new package creation. Any simpler solution is more than welcome.

Skip to main content