Search code examples
powershellnpmpsake

psake calling npm install with msys_version


I need to ensure some NPM dependencies are installed, and some of those use node_gyp to compile. That means I have to call "npm install --msvs_version=2013" so node_gyp will use my vs.net 2013 compiler. But for some reason, adding this to a psake task fails. It looks like it isn't passing the third argument properly.

task npmInstall {
  exec {npm install --msvs_version=2013}
}

Calling "./psake npmInstall" causes it to run, but node_gyp fails because it's not getting the third argument. The error seems pretty clear -- it's not using the 2013 CPP file. Where it says V110 it should say V120 (which is usually solved by calling --msvs_version2013):

C:\Projects\MyProject\app\SubProject\node_modules\browser-sync\node_modules\socket.io\node_modules\engine.io\node_modules\ws\build\bufferutil.vcxproj(18,3): error MSB4019: The imported project "C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\Microsoft.Cpp.Default.props" was not found. Confirm that the path in the declaration is correct, and that the file exists on disk.

Running the command directly in powershell works fine. Running the command as part of a script in powershell works fine. Even running "Import-Module path/to/psake.psm1; exec {npm install --msvs_version=2013}" directly in powershell works fine. It ONLY fails as part of a psake task.

What could be going on here?


Solution

  • Don't ask how I know this, but gyp is failing because you have the .NET Framework folder in your PATH environment variable.

    PSake, and only PSake, adds the .NET Framework folder to your PATH. This is usually a good thing, but today it's causing you problems.

    To fix the problem, do the following:

    task GypAngerIssues {
        if ($env:PATH -like "*C:\Windows\Microsoft.NET\Framework64\v4.0.30319\*") {
          $env:PATH = $env:PATH.Replace("C:\Windows\Microsoft.NET\Framework64\v4.0.30319\;", "")
        }
        exec { & npm install --msvs_version=2013}
    }
    

    A few notes for future-proofing:

    1. I've hardcoded a link to the .NET Framework which PSake determined by doing some pretty involved registry and folder spelunking--on your machine today, or on your machine some time in the future, this hardcoded framework will be wrong.
    2. My code assumes that PSake adds to the beginning of the PATH (which as of 2015-03-13, it does). This may change.