ASP.NET sass/scss compilation at run-time and at compile-time? - c#

I am searching for a solution for compiling my .scss files at run-time and at compile-time.
The reason I need both is that our designers work on Macs and prefer the ease of having their .scss files compiled dynamically at run-time (especially during a development phase). On the other hand, I need compile-time support to validate that the SCSS compiles successfully during my build process. My goal is to fail a build if the SCSS doesn't compile.
I have found several libraries available on NuGet, however, minor flaws in each of them are holding me back.
Is there a solution available for both of these scenarios?
Here's where my research has led me:
Run-time Support
BundleTransformer.SassAndScss via HttpHandler (works with Bourbon, albeit very slow)
Cassette.Sass (unable to compile Bourbon due to error)
Compile-time support:
Cassette.MSBuild (Does not appear to bundle SCSS files, only CSS)
Mindscape Web Workbench (Pro version apparently includes a command-line tool, however, documentation is very limited on the feature)
Others?

The Pro edition of the Mindscape Web Workbench includes a command-line tool for compiling at runtime. Currently, only the nightly build is capable of compiling Bourbon and Neat (one of my requirements).
Here is my pre-build event which is working great at the moment:
"C:\Program Files (x86)\Mindscape\Web Workbench\Command Line\wwcmd.exe"
"$(ProjectDir)scss\style.scss" /o:../css /style:compressed
UPDATE:
We decided to simply call SASS from a pre-build event as opposed to using Web Workbench.
call sass -C "$(ProjectDir)assets\scss\main.scss" "$(ProjectDir)assets\css\compiled\main.css" --style compressed

Check out SassAndCoffee. It's what Cassette is using and it embeds everything into a few assemblies.
Web Workbench on the other hand actually installs ruby and the sass gems to the file system in a very long folder path hidden beneath the current users directory, which is likely to be troublesome for a web application and with respect to security and permissions.

For ASP.NET Core you can use this package to compile scss at build time and it includes a watcher for debug-time and hot-reloading.
AspNetCore.SassCompiler
Sass Compiler Library for .NET Core 3.1/5.x./6.x without node.
https://github.com/koenvzeijl/AspNetCore.SassCompiler
# Package Manager
PM> Install-Package AspNetCore.SassCompiler
# .NET CLI
dotnet add package AspNetCore.SassCompiler

Related

How create a .net standard and .net framework self-contained build?

My goal is to create a build output that acts as portable version of my application, containing the non-framework dependencies (nuget + projects) directly as dlls.
This demonstrates the solution and the four projects contained:
You can see the libraries are .net standard 2.0 while a console app (to run / debug some code) is using .net framework 4.7.2 (because we have some .net framework apps in use around here). The arrows in the image show the references that have been set.
Parts of the the libraries (not console app) might be imported into MS sql server in the future; these imports usually pick up all dependencies from the same folder if available (which is the reason for a self-contained output).
Problem A: Running the code on linux/mono
Using jetbrains rider to open the solution, build + restore packages will work without problems.
Running the console app will work to some extend (e.g. loading data from SQL) until it fails when calling some code that makes use of BouncyCastle (dll not found exception).
Looking at the build output shows three .dll files of my lib-projects along with the .exe file of the console-app plus all the .pdb files AND additionally the System.Data.SqlClient.dll.
Seems that might be the reason my sql code worked.
Problem B: Running the code on win10, .net framework / core installed
Using VS / rider made no difference here, opened the solution, restored packages + build without problems. Running the console-app fails earlier than before: this time it was unable to find the Syste.Data.SqlClient.dll.
Checking the build folder shows my three lib-dlls and the .exe including the .pdb files, nothing else.
To my understanding, the files have to be either in GAC or inside the same folder for them to be found. It seems when a .net standard library dependency includes nuget-packages, something is having troubling either loading them into GAC or at least copying them to the build directory (which is outdated I guess).
So even if my approach (having a portable-ish / self-contained version of my app) might be uncommon or even stupid, I would have thought that just running this code on the dev-machine should work fine.
Problem C: Including dependencies in the build output
According to information I found here, the <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> property can be used to have dependencies being copied to the build directory.
And while this seems to copy too many files (tried excluding some according to docs) it does indeed copy the .dll files for a complete package when building the ExchangeIntegration project (.net standard 2.0).
Looking into accomplishing the same for .net framework .csproj projects yielded mixed results. I was playing around with the copy-local setting and stumbled across similar problems when creating nuget packages and using .targets files but had no success.
About the specific libraries used
I'm more interested in learning the right concept to handle this, it's not really about whether or not it makes sense to import Newtonsoft.Json into MS sql server.
I feel I'm fundamentally missing something; maybe the output type library is not correct for my goal or maybe I'm mixing problematic .net versions, although I did a quick check and it seems ok.
How can I get a .net framework (console-app) build that contains all non-framework dependencies (e.g. nuget) AND an separate .net standard (library) build, that also contains all non-framework dependencies?
EDIT: Adding all nuget packages to the top tier project (console-app in my example) seems to work around the problem, code executes without problems. I'm still waiting for a proper solution.
EDIT2: Added mono/msbuild version used under arch: 16.4

Is there a way to make a console application run using only a single file in .NET Core?

In .NET framework, you can make a single .EXE file that will run from the command line without having any extra config files (and if using ILMerge, you can put all .DLL references into the 1 .EXE assembly).
I am taking a stab at using .NET Core to accomplish the same thing, but so far without success. Even the simplest Hello World application with no dependencies requires there to be a file named <MyApp>.runtimeconfig.json in order to run using dotnet.exe.
dotnet F:\temp\MyApp.dll
The contents of the <MyApp>.runtimeconfig.json are as follows:
{
"runtimeOptions": {
"framework": {
"name": "Microsoft.NETCore.App",
"version": "1.1.1"
}
}
}
Without this config file in the same folder as the .DLL, I get the following error:
A fatal error was encountered. The library 'hostpolicy.dll' required to
execute the application was not found in 'F:\temp'.
My question is: Is there some way to change the application so it doesn't require this config file to be present, so that the defaults of this information are compiled within the .DLL but can be overridden by adding the config file?
NOTE: I also want to ensure it "just works" regardless of the platform it is installed on it provided the platform has the right version of .NET Core.
Background
I am trying to get a smooth user experience for running some utilities that are useful sometimes, but are rarely ever needed. Since it doesn't appear to be possible to use the same .DLL that is referenced from a client application as a console application, the next best thing would be to have a single file that could be downloaded and run without any dependencies.
For example, in Java you can simply download a .jar file on any supported platform and run:
java <package>.jar <namespace>.SomeClass [args]
and it will "just work" without any extra files. How can I get a similar user experience using .NET Core?
In a nutshell, I want to try to avoid the extra step of "unzip to a directory first"...
Update 2018: .NET Core 3.0 aims to enable a new scenario: packing the .NET Core runtime and all application dependencies into a single executable.
At the moment, there are no fail-safe methods to create a single executable file. Since there are a lot of type-forwarding dll files involved, even ILMerge and similar tools might not produce correct results (though this might improve, the problem is that those scenarios haven't undergone extensive testing, esp. in production applications)
There are currently two ways to deploy a .NET Core application:
As a "portable application" / "framework-dependent application", requiring a dotnet executable and installed framework on the target machine. Here, the XYZ.runtimeconfig.json is used to determine the framework version to use and also specifies runtime parameters. This deployment model allows running the same code on various platforms (windows, linux, mac)
As a "self-contained application": Here the entire runtime is included in the published output and an executable is generated (e.g. yourapp.exe). This output is specific to a platform (set via a runtime identifier) and can only be run on the targeted operating system. However, the produced executable is only a small shim that boots the runtime and loads the app's main dll file. This also allows an XYZ.runtimeconfig.json to set additional runtime properties like garbage collection settings.(think of it as a "new" app.config file)
In the future, the CoreRT runtime – which is still under development at the time of writing – aims to allow creating a single pre-compiled native executable that is specific to a runtime and does not require any other files.
Tested with .NET Core 2.2 on a console app:
Reference Microsoft.DotNet.ILCompiler package in your output project. You'll need to add MyGet package repository in Visual Studio settings. *
Publish the project via command line,
dotnet publish C:\src\App\App.csproj -c release -r win-x64 -o output-win-x64. If there's no "Desktop Development for C++" component installed, do it in Visual Studio Installer, or the command will fail.
Go to the output folder (e.g. "C:\src\App\output-win-x64") and grab the native image (.exe file).
On Windows it produced a fully functional 5Mb .exe file (compared to original self-contained publish with folder size at ~60Mb). On macOS the ILComplier though produced output without any error, the app crashed with unhandled expection (on the line with LINQ expression).
*Go to "Tools -> Options -> Package Manager -> Package Sources" and add new source at https://dotnet.myget.org/F/dotnet-core/api/v3/index.json
It is possible in .NET Core 3.0+
The feature is enabled by the usage of the following property in your project file (.csproj):
<PropertyGroup>
<PublishSingleFile>true</PublishSingleFile>
</PropertyGroup>
There are other options as well, such as packaging the pdb into the bundle, or leaving certain files out.
Documentation can be found here: https://learn.microsoft.com/en-us/dotnet/core/deploying/#publish-self-contained
True it just works:
Combine this technique with the Self Contained Deployment workflow, you can get a true "it just works" experience for your user, they don't even have to install the .NET Core runtime for your app to run.
I am currently deploying applications to my clients as single .exe files.
Read more about that here: https://learn.microsoft.com/en-us/dotnet/core/deploying/#self-contained-deployments-scd

Sharing a DLL between projects

Microsoft says it's platform neutral these days, so I'm trying to build on Mac and Linux only with VS Code and deploy to Azure. Why? It's mainly to prove that I can.
Our project has several parts which include a couple of different websites, a Web API, er API and a few other bits. On my Mac I've built a .Net Core Class Library with a load of objects in. Command line, dotnet build, DLL out, no problem.
I want to put that DLL on the Linux machine where the MVC website is being built - the objects forming the models part of that site hopefully. I cannot figure out how to get the website project to reference my DLL and use the objects.
I had assumed I copy it to the other machine, place it in the bin folder of the site being developed and reference it in the Dependencies section of the site's project.json. Nope. I saw a few articles that said .Net Core only works with NuGet and it had to be a package. Is that really true?
I've found and read (if not entirely understood) everything you could imagine on sharing between .net core and .net framework. This is a core-only project so not applicable. Frankly I'm lost, and something called .Net Standard has just rolled into my field of vision.
So instead of copying the DLL, use dotnet pack to build a nuget package on your Mac, and copy that to your Linux machine instead. Put it in a directory that you configure as a local nuget repository (no server or anything required) and you're away.
I agree it's not as straightforward as a reference to a DLL, but it's not too bad. Note that you'll need to version the package appropriately, so that the tool system can detect when it's changed.

How can I configure OmniSharp to support intellisense for C# without the use of .NET Core or MSBuild configuration files?

I am referencing Gtk# and building using Mono, writing my code in VS Code (code.visualstudio.com). I'd like intellisense for C#. By "intellisense" I mean the correct functions, members, etc. come up with "." - this is separate from predictive suggestions based on other code in the file.
I have tried both the current Microsoft C# extension (https://marketplace.visualstudio.com/items?itemName=ms-vscode.csharp) as well as the Legacy Microsoft C# extension (https://marketplace.visualstudio.com/items?itemName=ms-vscode.omnisharp).
Both of these appear to use OmniSharp as the means for providing intellisense, and both either load MS Build files and/or "project.json" files.
The current Microsoft C# extension seems to use "project.json" files which appear to follow a schema specifically for .NET Core. I tried to leverage this anyway by creating a local GtkSharp NuGet package out of the Mono DLLs, but I could not then "dotnet restore" because these NuGet packages were incompatible with .NET Core. I followed: https://docs.nuget.org/ndocs/hosting-packages/local-feeds and https://docs.nuget.org/ndocs/create-packages/creating-a-package
The Legacy Microsoft C# extension works if I use Visual Studio to generate solution (.sln) and project (.csproj) files. VS Code then recognizes these files and uses intellisense properly. Trying to hand-roll solution and project files failed because there seem to be a lot of entries OmniSharp is looking for when setting up using this method.
Fundamentally, I want to provide a simple lightweight configuration which says: "Here is my code (.cs files), and here are the assemblies I reference (.dlls) as well as their comment files (.xml)" - and then have VS Code provide intellisense for those files and referenced assemblies. The .NET Core "project.json" files are simple enough, but are incompatible. The MS Build files are significantly more complicated than what I am looking for and require Visual Studio (or maybe a much deeper knowledge of MS Build) to generate OmniSharp compatible files. I'm looking for a separation between build configuration and intellisense configuration.
How can I configure VS code to support intellisense for C# without the use of .NET Core or MSBuild?
This has nothing to do with build systems, and strictly relates to providing intellisense support using one of the OmniSharp-based C# VS Code extensions provided by Microsoft without the use of "project.json" or MS Build configuration files.

How to use Xamarin without the IDE?

I want to write an iOS app in C# with Xamarin and MonoTouch. I want to use Vim and Z shell instead of Xamarin Studio. However, I can't find much documentation on how to build from the command-line.
The documentation for the mtouch command says you have to pass an assembly as an argument, but how do I create that assembly?
The command line compilers that Mono provides are mcs, gmcs, and dmcs. For Mono 2.10.x and earlier, these are for C# 1.0, C# 2.0, and C# 4.0, respectively; for Mono 3.0.x, mcs defaults to the most recent version, and you have to select earlier language/runtime versions with the -langversion and -sdk options. The dmcs and gmcs commands in 3.0.x are scripts that call mcs with the appropriate -sdk option.
I am not sufficiently familiar with Xamarin.iOS to know how the libraries are laid out, but the -lib option allows you to tell the compiler about additional directories containing .dll assemblies and -r allows you to reference a specific assembly. The compiler will build a .exe assembly by default; use -target:library or -t:library to build a .dll one instead. The -help option will give you a list of all options.
You can use whatever build system you prefer from the command line. If you need to process MSBuild project files, then xbuild can handle them, but make, cmake, scons work fine, too, and are probably preferable to editing .sln files in Vim. You may still have to figure out dependencies yourself if they aren't obvious and if you have a complex project with multiple assemblies (the compiler is fast enough that you can just recompile everything for small single-assembly projects).
Note that I am not using Mono for this myself, but primarily for command line projects on OS X/Linux, so the above may be missing some subtle details related to building mtouch-ready assemblies for iOS.

Categories