sass-eyeglass/eyeglass-assets

Asset replacement

Closed this issue · 6 comments

A feature that Compass had as a side-effect of how it worked, was that anyone could replace the assets that came with an extension after they were installed into their project. Since eyeglass assets won't be installing assets into the application's codebase, we should consider whether asset replacement is a feature that is needed.

In order for an application to replace an asset used by a module, an asset can be registered as a replacement.

// Verifies an asset exists and returns a reference to it for use by other asset functions.
@function asset($relative-path, $module-name: null) {
  @return // abstract asset identifier.
}

// $asset-mapping is map of (original-asset: replacement-asset) as returned by the asset() function.
@mixin override-assets($asset-mapping) {
  $original-values: register-asset-overrides($asset-mapping);
  @content; // renders content with the overrides in place.
  $temp-values: register-asset-overrides($original-values);
}

To make this work, we'd need to keep a global map of the active overrides and pass it transparently into the calls to asset-url.

This affects the design in the sense that we really need them to import a sass file to use the asset helpers if this feature is present. I think this is a Good Thing™

I never ran into a use case where I needed to use this side effect (bug). My cases maybe limited but i guess I'm ignorant on why you would need to do this? Is it so you can modify a stock asset and personalize it then just replace the libraries version?

I think I agree with @scottdavis on this. This always felt a bit odd that it worked this way in compass.
I feel that, as a module author, I should be able to control the level of configuration. If I wanted to make an image configurable, I could do something like...

$my-module-config-some-image: 'path/to/image.png' !default;
.bg {
  background-image: asset-url($my-module-config-some-image);
}

That said, we could potentially leverage assetResolver per #1 to allow changing the on-disk reference to point elsewhere. The caveat being that this is an "app wide" config rather than per instance, but that's probably what most people would want anyway (and closer to the current compass behavior). e.g. the return object from assetResolver could look something like...

return {
  url: ...,
  destination: ...,
  source: ... // override on disk source path
}

You would then do something like... assetSource = assetResolver(asset).source || asset.sourcePath.
This would allow the app owner to essentially redirect any asset reference to point to a different file on disk. (e.g. could be used when reading in assets for sprites, image dimensions, data URIs, etc)

I can definitely see the argument for allowing local asset overrides, but this might be better served via a separate extension (e.g. eyeglass-assets-manager or something) that could add this special use case functionality, which could then force the requirement that you @import a sass file and allow asset context switching.

I don't think we want to support asset replacement. If it's a configurable option for a module, you probably should either (1) configure it through a not-yet-determined-configuration-system, or (2) take the approach @eoneill used where the Sass !default does the heavy lifting for us.

Personally I lean towards (2) because it forces an eyeglass module developer to consciously decide what should be exposed to the outside world.

Never crossed my mind, I've rarely included assets with a module. When I do, they are usually set as a default variable — easy to override anyway.

Alrighty. over engineered. I get it. 😜