bdkjones / CodeKit2

CodeKit 2 Beta
97 stars 4 forks source link

Foundation 5.4.5 (Compass stack) issues #443

Open Veraxus opened 10 years ago

Veraxus commented 10 years ago

The latest Compass-compatible build of Foundation (5.4.5) seems to be incompatible with CodeKit's internal version of Compass.

I've only just started to unravel the compatibility nightmare that is Foundation 5.4.5 - but I get the following message when I create a new Zurb Foundation with Compass project in CodeKit...

Compass was unable to compile one or more files in the project: 

NoMethodError on line ["27"] of /Users/Matt/Desktop/zf544/config.rb: undefined method `version' for nil:NilClass
Run with --trace to see the full backtrace

The lines in question were added in Foundation 5.4.5 (Compass version) along with a gem file that is supposed to allow Compass compiling through Bundler (and some additional dependencies - ugh). Here are the lines in question...

if Gem.loaded_specs["sass"].version > Gem::Version.create('3.3')
  warn "You're using Sass 3.4 or higher to compile Foundation. This version causes CSS classes to output incorrectly, so we recommend using Sass 3.3 or 3.2."
  warn "To use the right version of Sass on this project, run \"bundle\" and then use \"bundle exec compass watch\" to compile Foundation."
end

I'm starting to think that Compass is on it's way out in Foundation, considering the popularity of libsass and the fact that Zurb is giving libsass preferential support over Compass... but I thought I'd get this logged here since this might turn into a bigger issue.

Also, deleting those checks in config.rb allows the project to compile, but Zurb warns of issues... https://github.com/zurb/foundation/issues/5811#issuecomment-56975540

bdkjones commented 10 years ago

"Unraveling the nightmare" is exactly the right expression. Here's the rundown:

What Happened

The official Ruby Sass team recently released version 3.4, which is what’s included with the latest version of CodeKit. Sass 3.4 introduces some syntax changes that are backwards-incompatible.

Zurb updated Foundation to support Sass 3.4, but that broke compatibility with Sass-Rails and the Libsass compiler (neither of which currently support Sass 3.4+ syntax). So, Zurb rolled Foundation back and now require you to use the older Sass 3.2 or 3.3 compilers and Compass < 1.0.

How This Affects CodeKit

Installing Foundation WITH Compass requires you to delete those bottom lines from the config.rb file in order to have CodeKit compile the project using Compass. HOWEVER, there is no guarantee that the compiled CSS will be correct, because CodeKit is on Sass 3.4 and Compass 1.0.1.

In my own testing with the official CodeKit website (which is built on Foundation and compiled with Libsass), I found that several things broke when I updated Foundation to the latest release and then compiled using the Sass 3.4 Ruby compiler (Libsass could not compile the latest version of Foundation correctly because it uses newer Sass syntax.) Little things like hamburger menus, etc did not come out correctly.

You can, however, create a new Foundation project WITHOUT Compass and CodeKit will compile it just fine as long as you flip on the Libsass compiler for your Sass files.

How Zurb Should Handle This

The CORRECT solution is to issue (and maintain) multiple forks of Foundation:

This is a lot of work for Zurb, so I see why they don't want to do it. I don't blame them for simply saying, "Use older Sass until the Sass team(s) fix this mess."

The Real Problem

The official Ruby Sass compiler keeps advancing, introducing new features and backwards-incompatible syntax changes. Libsass, however, always lags Ruby Sass. Libsass is still trying to get all the features and syntax of Sass 3.2 implemented correctly, let alone the new stuff in 3.3 and 3.4!

But Ruby Sass is excruciatingly slow. It's the ONLY major compiler that's still written in Ruby. (Other than Haml and Slim, which are primarily targeted at folks running Ruby on Rails anyway). Ruby is never going to be fast. As long as the official Sass compiler is in Ruby, it will always be slower than the competition (Less and Stylus).

Folks that make Sass frameworks (like Zurb) correctly see Libsass as, "Where the puck is going". Libsass is the compiler everyone WANTS to use. It's FAST and can easily be used in any environment (Ruby, Node.js, JavaScript, etc with just a thin wrapper client).

But until we convince the entire Sass team of that, we're going to be in for some choppy times as major framework vendors struggle to support both cutting-edge features in the Ruby Sass compiler AND Libsass.

The Big Risk

This upheaval in the Sass world is a huge opportunity for Less and Stylus. Both of those compilers are written in JavaScript. While they can't match the speed of Libsass, they are "fast enough" in practical terms.

If Sass remains fractured in this way, I suspect many framework vendors and web developers will take a closer look at Stylus, by @LearnBoost. It's come a long way and, like Sass, is now a superset of the CSS syntax, meaning you can write 100% normal CSS and simply add in the parts of Stylus that you like. A great example is http://jeet.gs by @mojotech, which offers a Sass and Stylus version.

Zurb Foundation is hardly the only project facing this current mess. Bourbon, Bourbon Neat and many other popular frameworks are currently maintaining two versions: one for Ruby Sass and one for folks that want to use Libsass.

If the official Sass team drags this out for years, Sass risks folks jumping ship to languages that aren't fighting over what their future should be. In my opinion, Sass has built a strong advantage by courting vendors like Zurb, who build popular frameworks based on the language. But those vendors are only going to put up with this giant mess of Ruby/Libsass for so long before they leave for more stable platforms.

The Long-Term Solution

Ultimately, in my opinion, the best solution is to bring Libsass up to 100% feature parity with Ruby Sass and keep it there. Libsass should take over the title of "official" or "canonical" Sass and all future development of the language should happen there. The Ruby compiler should transition to a thin wrapper that simply calls the Libsass binary (just like the Libsass CLI is just a thin node.js wrapper).

This is the outcome that is best for Sass users, major Sass vendors (like Zurb) and the future of Sass itself.

I've considered launching a kickstarter to give the Libass team the resources to hire more than one guy to bring the tool to parity with Ruby-Sass, but I'm unsure what the community response would be.

bdkjones commented 10 years ago

Also, regarding "compass on the way out" --> Right now, Compass is not compatible with Libsass. But the author of Compass, @chriseppstein, is one of Libsass's biggest proponents. He's committed to making Compass compatible with Libsass in the future.

I don't think the Zurb team dislikes Compass. Rather, they simply want to use the fast compiler.

chriseppstein commented 10 years ago

cc: @nex3

bdkjones commented 10 years ago

Also, I'm debating how to handle this situation in CodeKit. The options appear to be:

  1. Bundle older versions of Compass/Ruby-Sass that are used ONLY when compiling a Foundation project that uses Compass instead of Libsass.
  2. Limit folks to installing Foundation WITH Libsass for now.
  3. Warn users who choose to install Foundation with Compass that CodeKit's compilers are currently newer than the ones recommended by Zurb and that they may get unexpected results in edge cases as a result. CodeKit would also remove the lines you quoted from the config.rb file so that the project compiles.

It is NOT an option to keep CodeKit on Sass 3.2 for the next six months. Folks that don't use Foundation want the latest version of the Ruby Sass compiler.

It's also not an option to let folks switch to an OLDER version of the Sass compiler as an external compiler in CodeKit because the Ruby Sass team changed the damn CLI interface so that the commands CodeKit passes to Sass 3.4 will fail on Sass 3.3-. (Ugh.)

Like I said: "Unraveling the nightmare" is the correct phrase.

gakimball commented 10 years ago

@bdkjones, these are my thoughts exactly, and thanks for being sympathetic to our troubles :) It was our mistake to even try supporting Sass 3.4 at all, and now that we're rolling back we have to do a bit of damage control. As far as our preference, we don't really have one. The Compass stack is still the default if you use our CLI, but increasingly we're using the libsass stack for client projects.

In theory if our codebase was split, for our specific needs we would only need two:

This is due to the changes in variable scope and the fact that our codebase doesn't use any 3.3+ features. We are looking at that stuff for our upcoming web apps framework, which is where we have to make those choices again. It would be nice to use maps and these wild selectors functions and all that, but it cuts libsass out entirely, and we have to deal with having the slow Ruby compiler in our JavaScript-only stack.

There are two ways to look at libsass:

  1. Its speed and portability makes it the preferable choice.
  2. Because it lacks feature parity with Ruby Sass, it shouldn't be used in production.

It's too late for option 2; libsass is only growing in popularity, and people aren't going to accept it has a "nice to have", compatibility-wise. The support needs to be there for major libraries like ours, it would seem. But as you've already articulated, the feature gulf is only going to get wider.

I do understand the immense challenge and time investment required to port Sass to C, so I get there's no easy solution here. Maybe one day a C implementation can be the canonical one, and we can port it to Ruby, JavaScript, and Brainfuck all day long. But until these two libraries are more closely aligned, we're stuck between a rock and a hard place. We either keep our feature set more modest to make everyone happy, or we axe support for an increasingly-popular library.

Veraxus commented 10 years ago

Thanks for the fantastic writeups @bdkjones and @gakimball - this is definitely a messy situation for everyone involved and that goes a long way toward making sense of it.

Bryan, in regards to your hypothetical CodeKit options, my vote is for option one - or a feature like it.

I'd be wary of automatically using an older version of Ruby Sass for Compass projects with no way to override that in the event of hypothetical future breaking changes... but speaking purely out of selfishness and personal preference, it would be tremendously useful if CodeKit bundled multiple versions of Ruby-Sass and let me select which to use on a project-by-project basis.

It's definitely less than ideal, but considering the muddy situation right now with Sass and projects that depend on it, it would be the most flexible and reliable solution for the time being.

gakimball commented 10 years ago

Another quick thing on our end, right now we won't support Sass 3.4 until:

Support for a fake !global keyword was added in this pull request to the libsass repo, which was merged in back in June but hasn't made it into a stable release yet.

As it turns out, the changes in variable scope don't really affect our codebase. It's the mere existence of !global that freaks out compilers.

bdkjones commented 10 years ago

Yea. CodeKit is currently using the latest master branch of Libsass, so Libsass in CodeKit won't freak out about !global. (To my mind, there isn't really a stable release of Libsass --- it's all beta anyway.)

In practical terms, you can install Foundation WITH Compass in CodeKit 2.1.6, comment out the lines you guys added at the bottom of the config.rb file, and then use Ruby Sass 3.4 and Compass 1.0.1 to compile --- it does work. But I don't know the edge cases where this will fail. What CSS classes are generated incorrectly?

@gakimball Also, it would GREATLY help if you guys could update that extra bit in the config.rb file to first test for the existence of an installed Sass gem before you try to call it to see what version is installed. Right now, you're just assuming that the Sass gem is installed on the system, which it won't be for folks that use an app like CodeKit (or any of my competing apps) to compile.

chriseppstein commented 10 years ago

What CSS classes are generated incorrectly?

Please link to the Sass issue so we can investigate.

gakimball commented 10 years ago

@bdkjones Ah okay, yep we can do that. Or can we change it to check against the version of the library itself rather than the Gem? I don't write much Ruby, but if we can check like this:

Sass::Version

Then that's guaranteed to always be there, right?

The idea behind the check was just to inform 3.4 users of what's going on. We should have had a Gemfile in there from the beginning, and been telling users to use bundle exec, but we're getting around to it now in our documentation.

chriseppstein commented 10 years ago
$ irb
irb(main):001:0> require 'sass/version'
=> true
irb(main):002:0> Sass::VERSION
=> "3.4.4 (Selective Steve)"
irb(main):003:0> Sass.version
=> {:major=>3, :minor=>4, :teeny=>4, :name=>"Selective Steve", :date=>#<DateTime: 2014-09-13T00:20:07+00:00 ((2456914j,1207s,0n),+0s,2299161j)>, :number=>"3.4.4", :string=>"3.4.4 (Selective Steve)"}
irb(main):004:0> Sass.version[:major] == 3 && Sass.version[:minor] < 4
=> false
gakimball commented 10 years ago

@chriseppstein Awesome, thank you!

eberth commented 10 years ago

I tried creating a foundation project, without compass and it compiles but without any foundation styles, is there a way I can make it work, I dont care if I use compass or not.

alloutnow commented 10 years ago

I just installed Foundation 5 with Sass on Ubuntu 14.04, yesterday, and followed the instructions on zurb.com's website. The styles do not work at all! This set-up seems to be too complicated for it to work properly; to many dependencies. It increases the likelihood for things to break.

bdkjones commented 10 years ago

Select the app.scss file in CodeKit, then check the use libsass compiler box. I explained this clearly in the 2.1.7 release notes. Reading those release notes is really important.

devinrhode2 commented 9 years ago

What if Sass unified on a Go or Coffeescript version? These seem popular among ruby folks. A js version would be 'fast enough', but the Go version would certainly be pretty unifying in my eyes. Very interested in watching how this plays out.

gakimball commented 9 years ago

@devinrhode2 libsass is that unified library; it's written in C. There are a handful of ports written in Go already.

By the way, Foundation 5.5 will be out on Friday, which will finally upgrade our codebase to be Sass 3.4 compatible.