How to build Cordova Projects with VS offline
As part of improving our test automation, we decided it would be useful to enable Visual Studio to build Cordova projects without access to the internet. We’ve decided to share the fruits of that effort in the hopes it might be useful to others. The following is a guide on how to create an environment that allows limited offline development of Cordova projects in Visual Studio.
Build offline
In order to create an offline build environment, we need to take resources from an internet connected machine, pack them up, and deploy them to a target machine. There are a few things we need:
- The NPM cache
- The Cordova cache, with the platforms we intend to build against
- The sandboxed versions of Node/NPM that VS uses
At the end of the blog post, there’s a project with a few scripts that show how most of the process can be automated.
Gather resources from a source machine
First, we should ensure we have NPM installed on our source machine. And, to ensure we take only what we need, we should start with a clean NPM cache.
npm cache clean
Once we’ve done that, we should globally install Cordova, along with any plugins our project is using. We’ll also need the whitelist plugin.
npm install -g cordova
npm install -g cordova-plugin-whitelist
[install other Cordova plugins here]
There’s also an NPM package our team wrote to help with the build process. This plugin will already exist on our target machine. However, its dependencies will not. So, we should globally install it so our NPM cache contains its dependencies.
npm install -g C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\ApacheCordovaTools\Packages\vs-tac
Next, we should install the packages containing the platforms we want to build against. Each Cordova version has a specific set of pinned platform versions. We’ll need exactly these versions of the platform plugins, otherwise VS might try to access the internet to download it. Cordova CLI usually lists the pinned versions of the platforms in their update changelogs. However, if we have trouble finding these lists, we could instead create a Cordova project using the version of the Cordova CLI we want, then add the platforms we’re using. Doing so should give us the pinned version of those platforms.
npm install -g cordova-windows@4.3.1
The platform packages are actually used to create the Cordova cache on the target machine. We could try to copy our cordova cache manually, but this has almost always exceeded the Windows max path character limit. We’ll download this package and extract it to the Cordova cache on the target machine instead.
At this point, we should copy our entire NPM cache folder (usually %AppData%\npm-cache
) to a temporary directory. We should also copy %AppData%\npm\node_modules
to our temporary directory. With these, we have everything we need to populate our NPM and Cordova caches. However, we still need the sandboxed versions of NPM and Node that Visual Studio uses. If we’ve run a successful build, we should be able to find these files at %AppData%\Microsoft\VisualStudio\MDA\vs-npm\2.15.1
. We should copy this to our temporary directory.
In certain cases, this directory may also exceed the Windows max path character limit. If that happens, we can download the parts individually and copy them to our temporary directory.
- Node
- NPM
- Also copy nodevars.bat from the root of our Node installation, or from the sandboxed node/NPM installation.
Our temporary directory now contains everything a target machine needs to build offline. Archiving the files isn’t strictly necessary, though doing so aids in transferring the resources to a target machine.
Deploying to a target machine
This is mostly the opposite of what we’ve done, with a few exceptions if we hit max path issues.
First, extract the NPM cache to %AppData%\npm-cache
. Extract node_modules to %AppData%\npm\node_modules
Then, we need to un-tar the platform packages to the Cordova cache. The contents of that platform’s .\package.tgz\package.tar should be extracted to %HomePath%\.cordova\lib\[platform name]\cordova\[platform version]
. For example, the Cordova Windows platform we downloaded earlier would be extracted to %HomePath%\.cordova\lib\windows\cordova\4.3.1
.
Finally, we need to sandbox NPM and Node. If we were able to copy the entire sandboxed directory, we just extract it to the same directory we got it from. If we downloaded the parts individually, copy the files to %AppData%\Microsoft\VisualStudio\MDA\vs-npm\2.15.1
and establish this directory structure.
- .\node.exe
- .\nodevars.bat
- .\npm
- .\npm.cmd
- .\node_modules\npm[contents of v2.15.1.zip]
If everything is in place, VS shouldn’t need to access the internet during a build, unless we specifically invoke a feature that requires the internet (adding a new plugin, for example).
Automation
This is all pretty annoying to do every time. We wrote a couple scripts for our test automation that gather, archive, and extract these dependencies. Below is a somewhat simplified version of these scripts. With some tweaking, you may be able to get this to work for your project. But mostly, it should serve as an example of how you might accomplish automating the creation of these offline build archives.
If you want to use the scripts directly, you’ll need 7zip. We use it to handle a few cases where max path might be an issue, and also to un-tar the platforms package.
Building the project will output a zip file and script that can be run on a target machine. The script will install the contents of the archive to the correct places on the target machine. Feel free to modify it to fit your needs!
Caveats
Something to note: This setup will not work for remote build with iOS. Nothing we’ve done above prepares the remote build machine for offline build.
Let me know if you have any questions, or if you have more tips for preparing an offline build environment.
Anthony Bucyk
Software Engineer | Tools for Apache Cordova
anbucyk@microsoft.com