sass/libsass

Feature: Curate / normalize asset path

am11 opened this issue · 11 comments

am11 commented

Redirected from: #489 (comment)

Ruby sass 3.4.5, and libsass (latest master); do not curate/normalize the images paths of the output. Less, on the other hand, has two options --rootpath and --relative-urls, which help its compiler fix the asset paths in the generated output (see less/less.js#2084 (comment)).

Sass compilers assume that you would write the code keeping the destination paths (of output and images) in mind. Less also has this as a default behavior, but provide that other option as well.

I think some folks would want to code Sass relative to current source file directory, without caring about the output's destination.

One of two ways to go about it:

  1. A simple boolean variable check bool relative_urls (default: false), which would cause rewriting the urls relative to the output path, as the parser encounters any path.
  2. A more complicated LESS like option string rootpath_slug (default: null) (in addition to relative_urls), which would take relative path from output to input file and apply it to each url to give more control in this kind of scenario: less/less.js#2084 (comment).
am11 commented

@mgreter, @xzyfer, can we make something likeSASS_URL_NORMALISER (or *ZER :D) in new API, which acts similar to importer, but reports any URLs it encounters during the parse? This way users would be able to change URLs with the desired logic. :)

am11 commented

URLs with the desired logic

Some advanced stuff: For instance, test against some whitelist from database or some web service and amend the URL accordingly. Or any other unbelievable use-case. 😄

Also, some server-side code (for example; express in node.js) might be able to leverage this feature differently (by imploding some template strings inside the URL and pre-process it). This will be ultra customization.

For the relative paths feature detailed above, that could be written on top of this feature:

(pseudo code)

-> URL intercepted by AST
-> Pass URL string to `SASS_URL_NORMALISER` wrapper function (which calls user-defined `sass_options.sass_url_normalizer)
-> Within that scope, check if relative_urls option is set then resolve the correct URL as follow:
   ->  first resolve its absolute path from source (.scss/.sass) file path.
   ->  using the abs. path from previous step, resolve relative path w.r.t output_path.

If both sass_url_normalizer (function) and relative_urls (bool) are set, then normalizer function will take precedence and relative_urls will be disregarded.

Thoughts?

I wrote this pure Sass proof-of-concept that does something very similar https://github.com/glebm/sass-rewrite-url

Should this conversation be moved upstream to sass/sass?

am11 commented

Sounds fair to me. :)
Momentarily, can we provide a helper for it, a custom function?

jhnns commented

Should this conversation be moved upstream to sass/sass?

Yes 👍, but the last time they were not happy about it...

Imho this feature is absolutely necessary to publish components that don't assume anything about the project structure.

My rational is that our number 1 priority is sass feature parity. This may happen one day, but it won't be for a long while.

To be honest I'm currently of the opinion that this is the just job of a post processor. Alternatively I believe this or equivalent functionality is offered s by compass and the compass team have decided to support Libsass.

jhnns commented

If I wanted to publish a css library and reference assets (like bootstrap does), this can't be solved solely with post-processors imho.

am11 commented

I think:

  • this is one of those feature which should be ported into libsass/ruby-sass from compass; because proper asset path resolution (depending on the use-case) is not something without which your CSS code can survive.
  • compass has covered everything, compass is a great framework; but the idea really is to make some salient features first-class citizens of sass compilers for autonomy, regardless of there presence in compass or any third party plugin.
  • there is a reason why Less has provided it as a top-level feature: it is a must have; they also have frameworks and plugin systems to support everything possibly imagined and are very picky to support only features which has demand; use-case driven as they put.. so there is definitely a demand for it out there.
  • you cannot convince ruby-sass guys easily, because mostly they use compass as if it is part of ruby-sass (gem install sass compass), I suppose we (currently deprived of compass) stand a better chance to make distinction of must-have vs. aux features :)

While I think this is a usefull feature, I pretty much agree with @xzyfer on this. It is not really a high priority currently. I personally also postprocess urls with another tool (I need to have this possibility anyway in my postprocessor). But I guess we would not be against it if anybody would like to take a lead here to get this implemented properly!?

I created a collective ticket to keep track this and other "non-urgent" feature requests, in order to keep the issue tracker a bit more clean for the more 1st aid issues. I would like to encourage everybody interested in this particular feature to add their comments into this closed issue anyway.

Thanks for your understanding and your contribution!