statiqdev / Statiq.Framework

A flexible and extensible static content generation framework for .NET.
https://statiq.dev/framework
MIT License
421 stars 74 forks source link

Dart/JS Sass compiler (to enable ARM64 support) #232

Open withinfocus opened 2 years ago

withinfocus commented 2 years ago

Hello -- when trying to execute Statiq e.g. dotnet run on an ARM64 device such as an M1 Mac you'll receive SASS compilation errors:

[DBUG] Exception while executing pipeline Assets/Process: System.DllNotFoundException: Unable to load shared library 'libsass' or one of its dependencies.

Stack trace:

   at SharpScss.LibSass.sass_alloc_memory(size_t size)
   at SharpScss.LibSass.StringUtf8.op_Implicit(String text)
   at SharpScss.Scss.FromCore(String fromStringOrFile, Boolean fromFile, ScssOptions options)
   at SharpScss.Scss.ConvertToCss(String scss, ScssOptions options)
   at Statiq.Sass.CompileSass.ExecuteInputAsync(IDocument input, IExecutionContext context)
   at Statiq.Common.Module.ExecuteInputFuncAsync(IDocument input, IExecutionContext context, Func`3 executeFunc)

Per https://github.com/xoofx/SharpScss/issues/19 this seems to have a troublesome future ahead of it, so does it make sense to abandon use of SharpScss in favor of something else, or even move to Dart Sass now that libsass is deprecated?

daveaglick commented 2 years ago

I'm not necessarily opposed to switching out the Sass implementation. In fact, several years ago I was using a different libsass wrapper and ended up switching to SharpScss due to limitations of that one. The challenge would be to find a library that 1) is easily bundled and deployed along with .NET packages (preferably in a way I don't have to maintain myself) and 2) supports similar features to what SharpScss does so that the Statiq modules still works the same way.

Neither of these requirements are particularly onerous, but to my knowledge SharpScss is basically the only option at this point. Going to Dart Sass would be neat - but I'd want to rely on a third-party wrapper for that, not deploy and maintain the wrapping code in Statiq. Am I missing any other options?

withinfocus commented 2 years ago

The Dart migration is certainly new-ish and https://github.com/Taritsyn/DartSassHost has recently been reinvigorated and might work. I also see https://github.com/koenvzeijl/AspNetCore.SassCompiler but its dependencies likely rule it out.

daveaglick commented 2 years ago

Both of those look interesting, and I'm glad to see some efforts in .NET to modernize Sass compiling, but I'm not sure either is stable enough or far enough along for our use. One thing I did find interesting is the use of a JavaScript engine to handle in-process compiling (as opposed to shelling out to Node). We already do that for some other things in Statiq so the approach might be a good fit. Perhaps there are some lessons learned here that could be applied to a custom implementation based on the JS libraries.

In any case, it's something I think would be worthwhile to explore, but probably doesn't rise to the top of my own priority list so it'll be a while before I have a chance to take a closer look. If you or someone else wants to experiment, I'd be interested in the results. Otherwise I'll add this to the backlog to take a look at after Statiq Docs ships later this year.

daveaglick commented 2 years ago

Moving to Statiq Framework for tracking since that's where the Sass module lives.

withinfocus commented 2 years ago

I browsed around for a bit to see where this is headed and the SASS community is recommending https://github.com/Taritsyn/LibSassHost for .NET which has the earlier-referenced Dart version as well. While that's still marked as a preview version, it's getting more popular and is being used as a dependency in more and more projects. The current library is no longer being actively maintained, although maybe it would be reinvigorated at some point.

My question at this point is if you'd be willing to entertain a shift to the "SassHost" approach which will require some minor refactoring around the file import process and eventing. This seems more future-proof and could be done in phases without moving to Dart initially, perhaps most importantly because there are some breaking changes like the OutputStyle offerings there.

The catch here I suppose is that the Dart version -- as it's the supported one now -- is building with the desired ARM64 architecture, but you'd have to deal with the breaking changes.

daveaglick commented 2 years ago

I'd absolutely be open to dependency updates/changes - that seems inevitable as first Wyam and now Statiq comes up on 8 total years in service. Over such a long time span, and with such a large number of dependencies for various modules, it makes sense that there will be some drift and deprecation.

That said, my time is also very limited and I've been hesitant to work on parts that are currently functioning when there's still lots of greenfield work to be done. The Sass module works for many/most use cases today so taking the time to switch out it's compiler it's something I'm not likely to personally do for a while still.

TL;DR: I'd be thrilled to work with someone on a PR for this, but it'll still be a while before it rises high enough in the backlog that I'd work on it.

withinfocus commented 2 years ago

That was my way of saying "I may submit a PR" 😜 -- low priority for me too so I'll see what I can do in the near future.

klasjersevi commented 11 months ago

Any updates on where this is heading? Lib Sass is lacking more and more of the newer language features that Dart Sass provides, so It would be great to not have to maintain "legacy" Sass styling when using Statiq.

daveaglick commented 9 months ago

@klasjersevi It's partly dependent on finding a good library, and as far as I know there aren't any good alternatives right now. There's a wrapper around Dart Sass that I looked into, but because it relies on executing JavaScript, it's a little slow. And while we can actually run JavaScript code during generation (Statiq comes with a swappable JavaScript engine), it does limit the amount of integration that's available. In this case, we'd want the Sass engine to support a virtual file system since not all Statiq documents are available or expected from the file system.

Long story short: no additional work has been done on switching the Sass engine (by me at least), and until I find a more significant chunk of time, it's not critical on my own ranking of backlog issues at the moment.