In my project.json, I need to refer to a library that I'm using during development, but don't want included in the project output. This is common for things like static analyzers and other tools.
Before project.json, this was handled by a metadata tag in the package .nuspec file. But, this no longer works (as far as I know) for projects following the new JSON standard.
How do I declare a development-only dependency in the new standard?
As of 1.0.0-rc1, the correct syntax is:
"dependencies": {
"HelloShared": {
"version": "0.1-beta-*",
"type": "build"
}
},
This declares HelloShared as a build (development-only) dependency of the current project.
I found this example in dnx/samples/HelloWorld/project.json on Github.
Project.json has a publishOptions:exclude section.
Related
I've just created an ASP .Net Web Application using the dotnet new webapp command.
I wonder if I the wwwroot/lib folder should be committed?
It looks like it contains versioned libraries and the version is not mentioned anywhere else in the application, so I think I should commit them.
But I really don't want to have distributions of 3rd party libraries in my git repository.
If your team has negotiated which libraries to use and their versions are clear, you can write the list of libraries to the readme to remind other members.
If the referenced library is not large and you want to better ensure the integrity of the code, you can commit wwwroot/lib.
With recent changes in ASP.Net core web application. you can choose to ignore adding client side lib (content of wwwroot folder) in your version control such as git.
they need to be restored during build.
you can use LibMan to restore those libraries during build.
this article from microsoft will guide you how to enable restoring client side library during build so that you don't have to add them to your version control.
since it also contains the specific version so that there will not be any compatibility issues.
example libman.json file
{
"version": "1.0",
"defaultProvider": "cdnjs",
"libraries": [
{
"library": "jquery#3.3.1",
"files": [
"jquery.min.js",
"jquery.js",
"jquery.min.map"
],
"destination": "wwwroot/lib/jquery/"
},
{
"provider": "unpkg",
"library": "bootstrap#4.1.3",
"destination": "wwwroot/lib/bootstrap/"
},
{
"provider": "filesystem",
"library": "C:\\temp\\lodash\\",
"files": [
"lodash.js",
"lodash.min.js"
],
"destination": "wwwroot/lib/lodash/"
}
]
}
Hope this helpful.
The decision is a trade-off between build time vs having "restorable" files in a repo. In few projects, initially I ignored files under wwwroot/lib and used libman.json and restoring the client libraries at build time. This restore had an impact on the "free minutes" provided by CI (Github Actions, Azure DevOps), so I reverted my decision; and manually restored those files and pushed the wwwroot/lib files to repo.
If the free build minutes is not a constraint, I would recommend not to store the files in the source control
I disovered the hard way today that I need to split a library into two packages; lets call them CoreLib and TestCoreLib. The CoreLib package is a library, the TestCoreLib library is the bundle of utilities and actors needs to setup the test environment required to test the CoreLib library. The added benefit of splitting this into two packages is that apps built with CoreLib can also beneift from use of TestCoreLib as it also suffices as a mocking library.
As TestCoreLib uses some actors from CoreLib, I defined CoreLib as a peerDependency of TestCoreLib.
{
"name": "TestCoreLib",
"version": "1.0.0-rc.1",
"type": "module",
"peerDependencies": {
"CoreLib": "^1.0.0-rc.0"
}
}
Conversely, I defined TestCoreLib as a devDependency of CoreLib as CoreLib of course has the need of passing its tests before publish.
{
"name": "CoreLib",
"version": "1.0.0-rc.1",
"type": "module",
"devDependencies": {
"TestCoreLib": "^1.0.0-rc.0"
}
}
Both release candidate packages have been published to NPM successfully and I have setup a third project DemoApp that uses both CoreLib and TestCoreLib successfully.
{
"name": "DemoApp",
"version": "1.0.0-rc.1",
"type": "module",
"devDependencies": {
"CoreLib": "^1.0.0-rc.0",
"TestCoreLib": "^1.0.0-rc.0"
}
}
The problem is now in the development branch of the CoreLib project. Tests don't complete complete as the following error is thrown:
Uncaught Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'CoreLib' imported from /path/to/CoreLib/node_modules/CoreTestLib/lib/index.js
That tells me that CoreLib is not being picked up by TestCoreLib, even though TestCoreLib is in the node_modules directory of the CoreLib project. The first statement in TestCoreLib is an import from CoreLib, so I assume the error is being thrown as that import is not being resolved even though it should... right?
I always want the development version of CoreLib to be used by TestCoreLib, so I am concerned about adding CoreLib as a devDependency (instead of a peerDependency) of TestCoreLib as I worry that doing such will lock CoreLib into version conflict with its own prior release, but I am honestly confused about what would happen in that context.
The lazy boy moon shot of linking TestCoreLib to CoreLib does not solve the problem either, so I am obviously missing something fundamental that I would really appreciate your help with.
Do you know of any projects that successfully split their packages off into peerDependencies in such a way that you could refer me to?
Is there an elephant in the room sitting top of me and if so could you tell it to get off so that I can resolve this maddening issue and move on? LMAO
Be safe, well, calm, clear, happy fellow humans. Thanks for considerations.
The elephant in the room was... the lazy boy moonshot and my misuse of it. My automatic typing fingers told me five minutes ago by adding the scoped package name to it
$ npm link #emmington/CoreLib
npm link by itself is insufficient for a symlinking a scoped package folder.
Symlinking a package folder
Scoped Packaged
I want to:
Make a class library that defines some interfaces and simple generic helper classes. It'll rely on generic collections and IQueryable<T> but no third party dependencies (well, JetBrains.Annotations).
Be able to reference that class library from everywhere (specifically UWP, net46 and ASP.Net Core RC2)
Ideally, use the project.json system throughout, although I'm prepared to sacrifice that if need be.
Publish the finished library to a NuGet feed and from there use it in other apps
When creating my class library project in Visual Studio 2015.2, I found the Class Library (.NET Core) template, which states
A project template for creating a class library as a NuGet package that can target any platform
Any platform! Brilliant... But I can't get it to work. After a lot of fiddling, I currently have the following project.json (I've probably completely broken it by now):
{
"title": "My Really Useful Class Library",
"copyright": "Copyright © 2015-16 Tigra Astronomy, all rights reserved",
"description": "Really neat stuff",
"language": "en-GB",
"version": "1.0.0-*",
"dependencies": {
"JetBrains.Annotations": "10.1.4",
},
"frameworks": {
"netstandard1.5": {
"imports": "dnxcore50",
"dependencies": {
"NETStandard.Library": "1.5.0-rc2-24027",
"System.Linq.Expressions": "4.0.11-rc2-24027"
}
}
"net46": {
"frameworkAssemblies": {
"System.Collections": "4.0.*"
},
"dependencies": {}
}
},
"buildOptions": {
"xmlDoc": true
}
}
The next thing I did was create my .NET Framework 4.6 project in the same solution, and try to reference the class library. It lets me add the reference but I'm getting build errors, unresolved symbols, R# is unhappy, etc.
I guess I'm not doing it right (no surprise, really, as I'm fumbling in the dark).
I've read some of the docs about TFMs, frameworks and libraries but none of it really makes much sense.
What do I really need to put in my class library's project.json, so that I can reference it from my .net framework 4.6 app, and also from UWP and ASP.NET Core RC2 apps? Is this really the right approach or have I started out on the wrong foot?
Right now there are two ways of creating C# projects: xproj and csproj. Assuming we're using project.json for both of them, that still works differently for the project types -- for xproj, the project.json contains everything needed to build the project; for csproj, it only contains the nuget dependencies.
That said, some project types, like UWP, cannot be built with xproj due to needing a more complicated build pipeline than what xproj/project.json supports. (BTW, this was one key reason for moving back to msbuild.)
There are also two ways of creating a .NET Standard-based class library: you can use xproj with project.json, as you've done, or you can create a regular csproj "Portable Class Library" project. With VS 2015 Update 3 RC, you can change the PCL to target a .NET Standard version (netstandard1.x instead of a PCL profile, 259, etc).
If you use a csproj-based class library to target netstandard1.x, things should just work for you when adding project references. Note that UWP currently supports up to netstandard1.4 based on the platform map. The challenge is if you want to use an xproj/project.json-based project instead. One key reason for using xproj today is to enable cross-compiling between multiple target frameworks. That is to say, create more than one output from your project. That's different than creating a single output that can be referenced from any compatible project. Both have their uses, it depends on your needs.
If you decide to create an xproj-based class library, there's a workaround you can use to reference it from a UWP project or any other compatible project type if the "Add References" dialog doesn't work (which it doesn't as csproj->xproj is pretty much broken). Instead of using the dialog, edit your UWP csproj to point to the output of the xproj like this:
<Reference Include="System.Reactive.Interfaces">
<HintPath>..\System.Reactive.Interfaces\bin\$(Configuration)\netstandard1.0\System.Reactive.Interfaces.dll</HintPath>
</Reference>
The above snippet is taken from the Rx.NET UWP Test Runner here
If you do this, you'll also need to add build dependency from your UWP project to your xproj since MSBuild/Visual Studio won't know about it and build things in the wrong order. To do this, right click on your UWP project in the Solution Explorer, then select "Build Dependencies -> Project Dependencies". In that dialog, check the box for your xproj to ensure that VS/MSbuild knows to build that one first.
You can see the full Rx.NET solution here, which includes xproj->xproj references and the UWP -> xproj references I mention above.
The new project templates/.xproj works a bit differently. The new Class Libraries (and application templates) produce nuget packages, rather than plain assemblies.
Within that nuget package all targets are packed into it. That being said, you add the new project same way as you add any other nuget package: You put the nuget into a nuget feed, reference this in Visual Studio and then fetch it from there.
If you don't have a nuget server running (Visual Studio Team Services + NuGet package, myget, self-hosted) you can also put the packages into a folder (local or network share) and add this folder as a nuget source.
If that's "too" much work, you can also create two projects into one folder: A *.csproj and a *.xproj. The *.csproj targets the .NET 4.6 Framework and the *.xproj stays as you pointed above and has multiple targets. With this setup, you can normally reference the project the way you used before (if they are in the same solution), by simply adding an reference.
In order to convert some dynamic HTML to React's JSX, in my ASP.Net MVC based project I want to use htmltojsx, but can't figure out how to incorporate it in the project as it involves requireJS and probably some other JavaScript dependencies.
If someone can describe it in an easy/clear manner, would be of great help. Will salute you if some working example fiddle is also provided.
OK, posting answer to my own question after a long time. Here is a brief summary of what I found out during my research on this topic in past few weeks.
Actually it involved exploring various co-related topics before to getting onto the right point.
To understand how to incorporate packages (especially npm based) like htmltojsx into web apps, we need to understand first 'Modules'.
By 'Modules' we mean a composed set of highly decoupled, distinct pieces of functionality that we have also the ability to dynamically load, sort of something like 'Import' statements we have in C# and some other Server side Languages.
Most modules are either based on CommonJS or AMD formats. Here is a very nice Blog on these. Please do read it first for a through understanding.
Writing Modular JavaScript With AMD, CommonJS & ES Harmony
To make us enable to use these modules in any web application there are then Module bundlers like Webpack, Browserify etc.
In short, a Module bundler takes modules with dependencies and generates static assets (like .js/.css files etc.) representing those modules.
These static assets can then be used in any web page like we do with HTML script/link tags normally.
Also to mention here, for using Webpack/Browserify one must first understand node's npm package manager which has become heart and soul of all Javascript's module based applications. Basically npm is a package manager and makes it easy for JavaScript developers to share and reuse code. It has become the de-facto standard behind the creation of well managed module based applications.
For using this an understanding of package.json is primary and vital step.
A developer must have to define the dependencies in a file named as package.json that describes modules/packages that an application will depend upon.
There are mainly two kinds of dependencies. Normal dependencies, defined in "dependencies" option (which are packaged along with the output static asset(s)) and "devDependencies" (which take part in compilation of modules and/or their resources). A typical devDependency is Babel, which is used to compile ES6 aka ES2015, React etc. to ES5 syntax which all major Browsers can understand.
After defining these dependencies in package.json file, we can just use them using a simple require statement, example:
var webpack = require("webpack");
An example package.json file would look something like this:
{
"name": "my-sample-app",
"description": "My sample app",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "John",
"dependencies": {
"classnames": "^2.1.3",
"datejs": "0.0.2"
},
"devDependencies": {
"babel": "^6.3.26",
"babel-core": "^6.4.0",
"babel-loader": "^6.2.0",
"babel-preset-es2015": "^6.3.13",
"css-loader": "^0.23.1",
"style-loader": "^0.13.0",
"webpack": "^1.12.11"
}
}
Once we understand package.json and some npm commands, using webpack we can compile modules into static assets and then use them in any web page.
Here are also some links that can help us understand all this better:
Getting Started With React ES6 & Webpack
Setting up React for ES6 with Webpack and Babel
At the company I work at we do the following when we need references to third party dlls in our projects:
Use nuget to get package
Pull dll's out and create a "lib" folder and add the references here
this lib folder is added to git so other team members have all references when they do a pull from git
Reference dll's stored in lib folder in our project
We do this to have full control and know exactly what references we are using.
My question is how is this achieved when using vnext and can we continue to do it this way?
Have watched "INTRODUCING: The Future of .NET on the Server" and it seems you list all dependencies in project.json file and when you do k restore it will go and download all based on feeds in nuget config file
You'll make use of the project.json file. As you mentioned, you list all your dependencies in there and the K Package Manager will deal with resolving the missing packages for you.
You'll notice that in the json file you specify the package in somewhat of a key-value pair of package:version. Most examples show a version of * which means get me the latest. But there's nothing stopping you from specifying a specific version, or a specific part of a version. For instance, the project.json file in the Autofac container of the DI project specifies a specific version of Autofac:
"dependencies": {
"Autofac": "3.3.0",
"Microsoft.Framework.DependencyInjection": ""
},
The main DI project specifies a sort-of-specific version of Microsoft.Framework.ConfigurationModel:
"dependencies": {
"Microsoft.Framework.ConfigurationModel": "1.0.0-*"
},
That says get me the most recent build of 1.0.0
This system allows you to automatically get the latest and greatest if you want, but also specify a specific version for safety. There's no reason to copy DLL's into a custom lib folder.
EDIT: You inspired me to blog about it: http://davidzych.com/2014/08/13/specifying-package-dependency-versions-in-asp-net-vnext/
Just noting that "-*" does not necessarily return the latest version. It my simple testing, it always returns the lowest available version. Per this documentation the calculation is more complex and returns the lowest version that "works".
EDIT: added link to documentation