Closed localhost closed 7 years ago
Thanks for reporting this issue!
This is going to be interesting to fix, since Flutterby -- for the moment -- has a very simple and strict rule about how it deals with file extensions that clashes with files named like you described above. I am, however, very eager to fix this (in terms of resolving this obvious conflict), but need to think about how to do it without moving too far away from said simple rules.
For the time being, as a workaround, please rename your files to jquery-min.js
-- I know it's not ideal, but it's the best I can think of right now.
Just to clarify, the logic currently implemented by Flutterby is this: given an input file named foo.a.b.c.d
, it will apply the d
, c
and b
filters and export the result as foo.a
.
Here's a couple of ideas how we could fix the issue. I'm not in love with any of them so far, but let's see where we can take it from here:
Option 1: implement special case handling for min
extensions, simply making the .min
part of the base filename. Pro: quite easy to implement. Con: I'm not a big fan of special case handling, and it'll break as soon as there's another extension that's not min
but should not be treated as an actual extension.
Option 2: rework the way filters are derived from input file names to essentially stop the filter chain at the first extension that does not have a filter. For example, a file named jquery.min.js.erb
would run through the erb
filter, but then export as jquery.min.js
, because js
has no associated filter. Pro: it's a sound logic that other parts of the framework would possibly also benefit from; Con: as soon as you add a filter for js
files (for whatever reasons; maybe Babel preprocessing?), the whole thing will break down.
Option 3: keep a whitelist of "static file extensions" (eg. html
, txt
, js
, ...) that will always stop the filter chain: Pro: it's a simple and easy to follow rule that can't be nullified simply by adding a new filter (as described in Option 2); Con: it robs Flutterby of some flexibility, and it's probably not going to be a lot of fun to actually build and maintain such a whitelist.
I'll think some more about this, and of course I'm happy to hear any alternative suggestions.
I really like the current chaining filter logic as such. I'm also quite excited about an Opal as a filter for JavaScript files.
So option 1 would also have to consider something like .pack.js
and maybe some more. Option 2 seems to have even more downsides if one would love to integrate further JS preprocessing. I somewhat like option 3 even though it seems to be some work to keep such a list updated. But on the other side a filter could dynamically add a set of known extensions which it can work with. Option 3 makes most sense to me at the moment.
The basic problem seems to be that .min.js
and .pack.js
are somewhat reversed when compared with foo.js.min
, which could minimize first and then apply a nil filter to .js
. So maybe a filter should optionally be able to register a chain of extensions like .min.js
and .pack.js
for precompressed and minimized files.
Or maybe we could even have a wildcard like **.js
and associate it with a nil filter. Where **
means everything including all previous filters and *
means one filter. Con: sounds very complicated even as I write it.
At the moment, option 3 feels the most sane to me, too; ie., when working through a file's extensions, starting from the end, when encountering js
or any other whitelisted "static" extension, Flutterby will stop processing the file. This would at least solve the issue, even though I still don't feel 100% comfortable with defining such a list (but I'll play around with some code later.)
I'm not terribly concerned about Flutterby then not seeing the min
as a filter extensions, since the contents of the file will already be minified, with no further processing required. Besides that, I would prefer to move all asset compilation concerns (concatenation, minification, etc.) to whatever asset bundling code we may come up in Flutterby or a plugin gem in the future. I'm already experimenting with this in my hmans.io project:
Either way, I unfortunately won't have a lot of time for Flutterby this week due to client engagements, but I'll try to hack something up around the weekend.
After a couple of days of thinking about this (and stumbling over the way Flutterby currently deals with extensions in a project myself), I am currently leaning towards Option 2, ie.: if there is a file name with multiple extensions, Flutterby will consider all extensions to be filter extensions (starting with the last one, and moving towards the beginning of the file name), until it encounters any extension that is not recognized as a filter.
This assumes that users will probably never set up filters for extensions like html
, txt
or js
.
Any additional comments on this? Otherwise, I'm planning on implementing this some time during the next couple of days.
Sounds good to me. I somewhat came to the same conclusion.
Will filters be able to handle different/combined extensions?
Edit: Just saw the commits/pull request. Looks good and to answer my own question - a filter seems to be able to handle multiple extensions by calling Flutterby::Filters.add
for each extension it can handle.
How do you want to handle chained processing like .js
and then e.g. minimization?
How do you want to handle chained processing like .js and then e.g. minimization?
I currently have no plans to perform minification/uglification through a filter -- instead, there will be a mechanism bundled with a (near!) future version of Flutterby that can bundle, concatenate, minify etc. a collection of assets (I have a basic version of this implemented in my blog.)
With files like jquery.min.js
, they will probably already be minified.
Am I missing some obvious use case of per-file minifaction?
All good for now, I think.
If we have a minified JavaScript file named
js/jquery.min.js
it will be built asjs/jquery.min
, whereas the expected result would be to leave unknown extensions alone.A file called
jquery.scrollex.min.js
ends up asjquery.scrollex
.The following entries appear in the log: