Visual Studio comes with the NuGet 3.1 client preinstalled. This new version enforces a few major changes concerning NuGet package design, which trigger some unexpected (yet barely documented or discussed) side effects that may even affect existing (published) packages.
The project.json format:
The major difference in architecture is documented on the NuGet Team Blog: NuGet package references are now stored in a file called project.json instead of the well-known packages.config. Apart from the content type (JSON instead of XML), this file only contains those pachage IDs a project references directly (while the old version even listed those packages’ dependencies). In addition, the NuGet package content of any referenced package is stored not within the solution directory, but globally in the %userprofile%\.nuget\packages folder to avoid redundancy.
In addition, the NuGet installation workflow has significantly changed: In earlier version, library references were included into the .vsproj project file during package installation. When using the new format, NuGet dependencies are only stored within the project.json file and the referenced libraries are resolved and linked first during build – one of the reasons for this approach is to not pollute project files with NuGet-specific artifacts.
Does this affect my package?
The good thing (from the point of view of a developer who doesn’t like to rewrite all his packages) is that the new format and workflow are only applied to UWP App projects and certain types of Portable Class Libraries that target the UWP platform – if you’re maintaining a NuGet package that targets, for example, only WPF applications, there’s nothing to do for you here (yet – of course, this might change in the future and other platforms might be migrated to the new structure).
On the other hand, if your package targets Windows Store Apps / the WinRT framework, there might be a need to change its structure, even if it has been publically available for some time and everything worked fine when installing it to Windows 8 Apps!
Things that don’t work with UWP:
Please note that the following enumeration may not be complete and list all features that have been changed and/or removed in NuGet 3 – I only refer to one common use case, in order to show how packages need to be re-structured to support this use case:
Libraries placed directly within the lib folder are ignored (in earlier versions, these libraries would have been used on all platforms for which no specific subfolder was present, this is not the case any more!). The same applies to the build folder, but I’ll go into detail about this one in a few moments.
In older versions it was possible to place two PowerShell script files install.ps1 and uninstall.ps1 in the package’s tools folder, which were executed during package installation / de-installation. Since with the project.json format there is no real package installation phase (package contents are not copied to the project folder and are not referenced in the project file any more, only the file project.json is adapted), these PowerShell scripts will not be executed in UWP Apps! (You can, however, keep those scripts within the package as they will still be used for non-UWP projects and just ignored by the UWP platform.)
If the install script’s purpose was to add certain items or tasks to the project, an alternative approach is the use of .props or .targets files – if following this approach, be sure to read on as there are more potential pitfalls coming!
In contrast to install.ps1 and uninstall.ps1, the PowerShell file init.ps1 will still be invoked when the package is added to a Visual Studio solution for the first time, but only if you place the file init.ps1 within a platform-specific subfolder (e.g., /build/uap/init.ps1), as all files located directly within the build folder will be ignored.
.props and .targets files can still be used for adding project items and build tasks, but the subfolder-pattern also applies here: Files located directly within the build folder will be ignored, instead they must be placed in a platform-specific subfolder.
If re-writing an existing package to comply with NuGet 3.x structure, you’ll probably not want to provide different .props and .targets files for all supported platforms, so a quick and easy solution for you might be to keep the existing /build/*.props and /build/*.targets files, and in addition create a new folder /build/uap/ and copy all .props and .targets files into this new folder. This way, those files will be applied to UWP App projects, and all other platforms will still use the old files in the parent folder.
Wile the files /tools/install.ps1 and /tools/uninstall.ps1 are ignored (as mentioned above), the tools folder can still be useful, as this folder’s contents will still be copied to %userprofile%\.nuget\packages\[packagename]\[packageversion]\tools. Since your .props and .targets files will also be placed within %userprofile%\.nuget\packages, the contents can be referenced, for example, by build tasks, using relative paths: ../../tools/somecontentfile