Search code examples
msbuildtypescriptwebdeploytypescript1.6

Can't deploy from VS2013 (or TeamCity) after TypeScript 1.6 upgrade


Today I updated to TypeScript 1.6, and now the CopyPipelineFiles task is failing when trying to deploy web applications.

I redirect TypeScript's compiled JavaScript output directory to scripts\compiled\ in the Web project's settings (via TypeScriptOutDir entry in the csproj file) and this has always worked fine up until now. Typescript files are being compiled correctly, and to the correct directory (ie scripts\compiled\ under the web project directory).

However, the CopyPipelineFiles task seems to be getting confused about the root directory of TypeScript files, and now always assumes that it is the root directory of the web project. As a result, it's adding folders to the path that don't exist, for example, after compiling scripts\foo.ts, instead of grabbing scripts\compiled\foo.js MSBuild is looking for \scripts\compiled\scripts\foo.js. I have tried using $(ProjectDir) in the output directory, and I've also tried setting the TypeScriptRootDir to the appropriate root directory (e.g. scripts\) but the problem persists.

The only way I've been able to remedy the situation is to remove the output directory and allow the compiled JavaScript files to be output to the same locations at their TypeScript counterparts.

The following is an example of a real error I've received, where the path of the TypeScript file would be scripts\account\app.ts:

Copying file scripts\compiled\scripts\account\app.js to obj\Release\AspnetCompileMerge\Source\scripts\compiled\scripts\account\app.js failed. Could not find a part of the path 'scripts\compiled\scripts\account\app.js'

This happens on all local machines with Typescript 1.6 installed, as well as our TeamCity build server with 1.6 installed.


Solution

  • Filed a bug report with the TypeScript team and they've confirmed it. Seems to be an issue with how the compiler is computing absolute paths. The workaround right now is to explicitly set relative paths for both the outDir and the rootDir, so something along the lines of this:

    <PropertyGroup Condition="'$(Configuration)' == 'Debug'">
      <TypeScriptOutDir>Scripts\compiled</TypeScriptOutDir>
    </PropertyGroup>
    <PropertyGroup Condition="'$(Configuration)' == 'Release'">
      <TypeScriptOutDir>Scripts\compiled</TypeScriptOutDir>
    </PropertyGroup>
    <PropertyGroup>
      <TypeScriptRootDir>Scripts\typescript</TypeScriptRootDir>
    </PropertyGroup>
    

    In my case I've just moved both the outDir and rootDir to the property group with no condition since I don't need to switch the outputDir between builds, something like so:

    <PropertyGroup>
      <TypeScriptRootDir>Scripts\typescript</TypeScriptRootDir>
      <TypeScriptOutDir>Scripts\compiled</TypeScriptOutDir>
    </PropertyGroup>