Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change the pre-processor for css #1167

Closed
trusktr opened this issue May 10, 2020 · 20 comments
Closed

Change the pre-processor for css #1167

trusktr opened this issue May 10, 2020 · 20 comments
Assignees
Labels
needs discussion pinned This is to pinned the PR/Issue in order to keep it open PoC welcome
Milestone

Comments

@trusktr
Copy link
Member

trusktr commented May 10, 2020

Status PoC

Currently, we are using stylus for writing CSS but we can consider moving with LESS or SASS (preferable).

@trusktr
Copy link
Member Author

trusktr commented May 11, 2020

Why is Less or Sass marked as "preferable"?


I vote for PostCSS, to stay in line with future CSS specs. See also CSSNext which is basically a preset that configures a collection of PostCSS plugins out of the box.


Although the Sass SCSS syntax is nice, I dislike the tooling very much because it relies on native builds for each platform (written in C++). Any time that someone runs npm install node-sass, it will run a node-gyp build to build the native modules.

I have used Sass a ton in various projects, and lately I have been so annoyed with build errors and things not working due to native modules getting in the way, that I've personally been happier using pure-JS alternatives like Stylus.

Even if Sass syntax is nicer, the Stylus tooling is much more friendly. I haven't ran into any problems with Stylus tooling, but with Sass I swear every other week some build problems happen and it gets very annoying to have to stop developing to figure out what's wrong. And even rm -rf node_modules && npm install doesn't even fix the issues sometimes, which is incredibly a pain in the bum.

In my humble opinion, choosing Sass will introduce a maintenance burden, and some end users may even open new issues when they encounter these problems although it isn't our fault.

Let's no pick Sass!


I haven't used Less for a long time, I'm not familiar with its tooling lately, but it is written in pure-JS, which I am totally in favor of over Sass's C++, regardless of how good Sass's syntax is.

@trusktr
Copy link
Member Author

trusktr commented May 11, 2020

Here's an interesting stat. Weekly download for each:

  • Stylus, 1.7m
  • Sass, 1.8m
  • Less, 2.5m
  • PostCSS............ 24.4m!

@anikethsaha
Copy link
Member

I am always ready to bet on postCSS. it gives us a huge control to our processing.

let's have postcss then.
I am thinking of having plugins packs in order to keep it consistent.

We need to list down some plugins which we want to use .

currently I am thinking of

any other ?

@anikethsaha
Copy link
Member

I will take a dig in this soon. will create a pack with the plugins we want.

@trusktr
Copy link
Member Author

trusktr commented May 11, 2020

I forgot CSSNext was deprecated in favor of postcss-preset-env, which is looking nice.

Regarding plugins, do you want to avoid just choosing, for example, all stage 1+ features of preset-env. In particular I like the CSS Nesting module, which is currently a stage 1 proposal.

(Neat that all these features are proposals for actual CSS, so eventually we may remove build steps for them, unlike Sass/Less/Stylus!)

@anikethsaha
Copy link
Member

Regarding plugins, do you want to avoid just choosing, for example, all stage 1+ features of preset-env. In particular I like the CSS Nesting module, which is currently a stage 1 proposal.

nesting is one of the things I am interested to write for future CSS. I wonder if we can pick the features and use them.?

@anikethsaha
Copy link
Member

I think we can . ref this

@trusktr
Copy link
Member Author

trusktr commented May 11, 2020

I wonder if we can pick the features and use them.?

It may be easier to just pick "stage 1", but yeah we can also just pick individual features. It's only for dev mode anyways, so it may not matter if there's more dependencies or not for compiling the CSS.

@trusktr
Copy link
Member Author

trusktr commented May 11, 2020

Also nice list of features by stage at http://preset-env.cssdb.org/features, and http://cssdb.org has the official list of proposals with stage level.

@anikethsaha
Copy link
Member

cool, lets have stage 1 then

@jhildenbiddle
Copy link
Member

I think discussions like this are most productive when we focus on problems that need to be solved. Perhaps I'm missing something, but so far I haven't read an "issue" in this issue.

That being said, I do have some thoughts on the pre/post-processor debate that may be useful for future discussions. As the author of a complex grid system compatible with Less, Sass, Stylus and PostCSS, I've spent my fair share of time with each of these tools.

  • PostCSS is not an either/or discussion. Many projects (including docsify-themeable) use both a pre-process like Sass and PostCSS. There are scenarios where PostCSS is the only processor capable of accomplishing a goal, and IMHO this is where its true value lies (not just as a replacement for Sass/Stylus/Less).

  • PostCSS is not a 1:1 replacement for pre-processors like Less, Sass, and Stylus. Plugins provide functionality similar Less, Sass, and Stylus but it's up to you to cobble together a working system. Yes, it's flexible, but that flexibility comes at a cost: the syntax and features available will be unfamiliar to developers unless they are familiar with a project's PostCSS configuration, documentation is scattered across plugin repos, plugin quality is varied, plugins can break with new versions of PostCSS, plugin order must be configured properly, etc. These are all things to consider when maintaining an OSS project with developers of varying skill levels. It's faster and easier to send devs to the Sass/Stylus docs than it is to ask them wrap their heads around a custom PostCSS configuration, and it's easier to manage a single dependency for Less/Sass/Stylus that it is to manage all of the plugins required for a feature-rich PostCSS configuration that aims to replace Less/Sass/Stylus.

  • Download metrics are not a useful measurement of value. PostCSS, by itself, doesn't actually do anything (the plugins do). Those 25.9m downloads/week give no indication as to how PostCSS is being used, so it would be misguided to assume devs are choosing PostCSS instead of Less, Sass, or Stylus. A better indication would be review the most popular PostCSS plugins to determine the most common use cases. Interestingly, the most popular plugins are those that perform tasks outside the scope of Less, Sass, and Stylus, which indicates that for most projects PostCSS serves a different purpose than Less, Sass, or Stylus.

  • Despite the above point, it's worth pointing out that the download stats listed above for Sass are inaccurate. There are two popular implementations of Sass that run under Node: sass (1.98m/wk) and node-sass (5.2m/wk). Combined, these make for over 7m downloads/week. If download stats are of any importance, then Sass has a clear lead over Less and Stylus.

  • Less, IMHO, is not an option worth considering. Basic pre-processor functions like loops require a hacky syntax and extending its functionality with plugins is an exercise in frustration due to the lack of proper documentation.

  • Sass and Style are very similar in terms of functionality, with each having a few features the other lacks. For 99% of devs, the decision will come down to syntax preference, not feature requirements.

  • Dart Sass is the newest version of Sass. It compiles to pure JavaScript and addresses the concerns mentioned above (those issues are associated with node-sass).

Whew.

My vote would be for PostCSS + (Dart) Sass largely because this is what docsify-themeable currently uses. I could make the conversion to something else, but I don't see how that would be a good use of time without some compelling arguments.

@anikethsaha
Copy link
Member

thanks for the detailed points.

I agree that it can be a barrier for others to contribute and also we may not get most of the features we get from other processors like loops (we can get them through other plugins but not from postcss-preset-env ... maintainability cost should be considered here. )
For me personally, the issue with stylus is its syntax. indentation based syntax and that does make the code hard to read in non syntax supporting ide like GitHub

about dart-sass, it does need some experience with dart right? I do think it can be barrier as well (at least for me who doesn't know dart)

maybe postcss + sass?

cc @trusktr thoughts?

@jhildenbiddle
Copy link
Member

To clarify, The “sass” package on npm is Dart Sass. Dart Sass compiles to pure JavaScript, so it is a drop-in replacement for node-sass (with some api differences and a few quirks to be considered).

I misspoke above though: docsify-themeable is currently using node-sass. Switching over to sass (Dart Sass) was as easy as installing the sass module and fixing one issue in my source that Dart Sass didn’t like but node-sass was okay with.

@anikethsaha
Copy link
Member

so if we want to use it with postcss I believe we need to use the sass parser for postcss right ?

@jhildenbiddle
Copy link
Member

We use two npm packages: 1) sass and 2) postcss (+ plugins). Sass will process .scss files and output .css files, then PostCSS will process the Sass-generated .css files and output the final .css files.

@anikethsaha
Copy link
Member

ohh I thought of having sass in .css.

yea this seems better 👍

@trusktr
Copy link
Member Author

trusktr commented Jun 19, 2020

Dart Sass compiles to pure JavaScript

Awesome! I just realized this. All my issued were with node-sass.

so far I haven't read an "issue" in this issue.

@jhildenbiddle I converted an old card I found in the formerly "5.0!" board that I assume someone put there a long time ago. I didn't open the issue intending for this to be a task, but had simply converted the existing cards into issue.

Sass and Style are very similar in terms of functionality, with each having a few features the other lacks. For 99% of devs, the decision will come down to syntax preference, not feature requirements.

Is it even worth switching from stylus to sass then? One less thing to do if we don't convert.

EDIT: As docsify-themeable is already in sass, then yeah we'll need to make a choice.

it's up to you to cobble together a working [PostCSS] system... It's faster and easier to send devs to the Sass/Stylus docs than it is to ask them wrap their heads around a custom PostCSS configuration

What about postcss-env?

That seems to give us all the features without the cobbling and without a custom config. What is really attractive about it is the future-forward compatibility with syntax that is being planned (who knows what will actually make it though). It's like using coffeescript instead of Babel nowadays I feel like (though I don't know how accurate that simile is).

My vote would be for PostCSS + (Dart) Sass largely because this is what docsify-themeable currently uses.

Curious why you chose postcss + sass vs postcss-env (would like to learn your thoughts, I have less experience in this area). I'm curious to know what postcss-env (without config, just using defaults with everything) lacks compared sass/stylus.

Regarding documentation, the https://preset-env.cssdb.org/features website seems to have enough documentation to allow me to use all the features. What sorts of docs are missing? Or you mean configuration docs (for each plugin) are missing from there, for example?

If we use postcss-env, wouldn't we avoid having to worry about configuration mostly?

The usage looks fairly straight forward and simple: https://github.com/csstools/postcss-preset-env#usage

@jhildenbiddle
Copy link
Member

What about postcss-env?

postcss-env is an interesting project. It can replace a preprocessor like Sass but only if the following are true:

  1. Maintainer do not require or expect to use the additional features offered by other preprocessors (like Sass)
  2. Maintainers accept the likelihood that specific features can and likely will change which can lead to bugs that may or may not be caught at compile time

The first item is self-explanatory. The second item is (to me) the more interesting one.

Consider the CSS working stage definitions. Only stage 3+ features are considered "stable and subject to little change", and only six features offered by postcss-env match this description:

Screen Shot 2020-06-20 at 1 46 33 PM

By default (i.e. no configuration), postcss-env supports stage 2+ features which "should be considered relatively unstable and subject to change". Using stage 2, stage 1, or stage 0 features becomes increasingly more risky as their syntax and/or functionality is increasingly likely to change. When this happens, updates to CSS will be required. Hopefully each individual postcss plugin responsible for handling a feature will be able to recognize the use of an "older" syntax and provide some kind of warning, but what if they don't (or can't)? The end result is a breaking change that may or may not be detected and fixed before it gets released to the public.

To make a quick comparison of postcss-env and Sass, consider the ability to nest rules (W3C spec, postcss-nesting plugin, Sass docs). Using postcss-env, this is a "highly unstable and subject to change" feature (stage 1) while Sass' implementation is stable with additional features. Postcss-env is limited and less stable because it is tied to a work-in-progress W3C proposal. Sass does not have this dependency, which is why it has been able to offer this feature with additional functionality for years.

That seems to give us all the features without the cobbling and without a custom config.

postcss-env doesn't offer the same features as other processors like Sass, nor is it intended to. It is intended to make CSS features for which there are W3C specifications (in various stages of development) available to developers before they are widely adopted by browsers.

Postcss offers an impressive collection of plugins that provide functionality for which no W3C specification exists, but these plugins would not be added to postcss-env because their functionality is outside of the scope of what postcss-env is designed to do. If you want "unofficial" functionality (perhaps to match what Sass does), then you're back to creating and managing a custom postcss configuration.

Curious why you chose postcss + sass vs postcss-env (would like to learn your thoughts, I have less experience in this area). I'm curious to know what postcss-env (without config, just using defaults with everything) lacks compared sass/stylus.

Some of the big differentiators are flow control (@if, @else, @for, and @while directives), mixins, functions, lists, maps, and a number of built-in modules that make everything from working with colors to list management easier. Those are features that aren't offered by postcss-env nor will they be in the future unless they become a W3C proposal. Features like nested rules are available with postcss-env but require adopting a "highly unstable and subject to change" stage 1 feature (as described above). Other features like flow control are available using additional postcss plugins (postcss-each, postcss-conditionals, postcss-for, etc.), but implementation now involves creating a custom configuration, maintaining postcss + plugin updates and compatibility, an understanding by devs of which postcss plugins are in use, etc.

CSS preprocessors are intended to make life easier, so I favored the tool that did that.

If we use postcss-env, wouldn't we avoid having to worry about configuration mostly?

Only if, as per the first answer above, the maintainers 1) do not value the additional features offered by other preprocessors and 2) we accept the risks involved with writing CSS per work-in-progress specifications that are likely to change. Personally, I enjoy the extra features Sass provides and I prefer the stability Sass' syntax.

As for postcss itself, I stand by my statement from an earlier comment:

There are scenarios where PostCSS is the only processor capable of accomplishing a goal, and IMHO this is where its true value lies (not just as a replacement for Sass/Stylus/Less).

Here is a list of the postcss plugins used by docsify-themeable, each of which performs a tasks that Sass is not designed to handle:

In summary: Sass for authoring CSS, PostCSS to fix CSS.

Hope this helps explain things a big better.

@stale
Copy link

stale bot commented Aug 21, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Aug 21, 2020
@sy-records sy-records added pinned This is to pinned the PR/Issue in order to keep it open and removed wontfix labels Aug 22, 2020
@jhildenbiddle jhildenbiddle added this to the 6.x milestone Mar 1, 2024
@jhildenbiddle jhildenbiddle modified the milestones: 6.x, 5.x Jun 16, 2024
@jhildenbiddle
Copy link
Member

This issue has been addressed by PR #2469. The changes will be available when Docsify v5 is released.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs discussion pinned This is to pinned the PR/Issue in order to keep it open PoC welcome
Projects
None yet
Development

No branches or pull requests

4 participants