Skip to content

Loading…

Sprockets outputs concatenated + source? #431

Closed
rprieto opened this Issue · 17 comments

5 participants

@rprieto

The Sprockets plugin seems to concatenate "required" files, but also output them separately in the build folder.
For example:

index.html.erb 
    include_javascript_tag "app"
app.js
    //= require query.min.js
    //= require model.js
    //= require email.js

Gives the following output:

build 
    js
       app.js           # everything, minified
       query.min.js     # unused
       model.js         # unused
       email.js         # unused

Is this expected?
How can we prevent all these unused source files from being copied?

@tdreyno
Middleman member

You can ignore any source file in Middleman by prefixing it with an underscore. I usually have one app.js and I //= require "_some_library_file"

@asgeo1

Thanks. I was looking for the answer to this.

At first I thought maybe it was just the sprockets require statements that needed the underscore - but I actually couldn't get it to work without also renaming the files with underscores.

I can't say I'm a fan of having to prefix my file names with underscores to be honest.

I prefer the rails way, in which you define which files should be precompiled in a ruby config file:

config.assets.precompile += ['app.js', 'app.css']

Perhaps something like that would be a good addition to middleman?

@bhollis
Middleman member

You can also ignore the files via config.rb: http://beta.middlemanapp.com/advanced/dynamic-pages ("Arbitrary Ignores").

Something like:

ignore 'javascripts/foo.js'
ignore 'javascripts/jquery*.js'
ignore /^javascripts/bar.*?\.js/
@asgeo1

Cool, thanks. That's definitely better than renaming the files with underscores.

I gave it a try and it worked. For my app it took about 10 lines of ignore to make it ignore all of my project js/css files.

Which is still not ideal, considering I only want to build a single app.js and a single app.css file. And I suppose I'll have to maintain that list of ignores as I add new files to my project, which will probably become annoying.

Perhaps if middleman also had a setting that worked opposite of ignore, then that would be the equivalent of what rails has with config.assets.precompile.

@bhollis
Middleman member

I don't think we'll do anything specific to Sprockets like Rails did. But maybe ignore needs an :except option? Or maybe we need an un-ignore command? That way you could

ignore 'javascripts/*', :except => 'javascripts/app.js'

? Just thinking out loud, not sure how that'd work.

Personally, I'd just prefer if Sprockets worked totally differently and worked off explicit manifests...

@bhollis
Middleman member

@asgeo1 One thing you could try is crafting a clever regex:

ignore %r{javascripts/(?!app\.js).*$}

That'll ignore any file under javascripts that isn't named app.js. It uses a negative lookahead assertion, which is only available in Ruby 1.9

@bhollis
Middleman member

If it helps, I've also done this in the past, which is a bit easier to understand:

Dir["source/javascripts/**/*.js*"].each do |f|
  next if File.basename(f) == 'app.js'
  ignore f.replace('source/', '')
end
@asgeo1

Yeah, that synax will definitely work and makes it much cleaner. I'll go with that if that's what you guys decide to do.

My only thoughts are that ignoring files seems like the opposite of what people will generally want to do in practice - i.e. create a white list of files to build. The default files in the white list could be app.css and app.js.

I'm trying to think why anyone would want to build all assets by default, esp. when the point of building is to concatenate everything into as few assets as possible.

@rprieto

I wasn't expecting so many comments! Some great advice, personally I'm happy to use underscores for the moment - this is what SASS uses for partials, so it is somewhat consistent.

I agree that a whitelist ("the rails way") is probably easier to manage: in most cases people will only have a few "target" combined files, but many source files to ignore in different folders. Support for globs would be great too, so it's easy to specify which files need to be processed, for ex:

process_only [ 'app.js', 'app.css', './3rdparty/**' ]
@tdreyno
Middleman member

As an aside, we're investigating a more robust asset build and dependency solution, but that won't be something we build until after 3.0 ships.

@rprieto

Do you know what the new solution will look like?

I really like the way tools like JAWR or Rails handle different builds. You can turn bundle processing on/off at a flick of a switch, and have your assets concatenated & minified or just included separately for debugging purposes.

I don't think the following is supported on Middleman yet, is it?

<%= javascript_include_tag "app", :debug => true %>
@tdreyno
Middleman member

You'd need to use the configure block in your config.rb to do per-build or per-environment options. If you've got a use-case for building a whole site, except a single JS file, please post a bug and we'll discuss it there.

Regarding a possible new solution, I'd like to integrate rake-pipeline

@rprieto

Is there any documentation on the per-environment options for configure? I didn't see anything so I'm using env vars set by the "master" rake build, which works but is not not ideal.

Regarding the JS files, I don't have a need to single out any file. My use case is the very typical "many CSS and JS files, that I would like served separately while developping, and concatenated/minified into 1 file for upstream builds".

I hadn't seen rake-pipeline before, it definitely looks interesting.

@tdreyno
Middleman member

We've talked about using separate files during dev as well, definitely on the radar.

Regarding environments, I guess those docs aren't too apparent.

configure :development do
  set :some_dev_var, "something"
end

configure :build do
  set :some_build_var, "something"
end
@tdreyno
Middleman member

Going to close this ticket and track Asset Pipeline improvements here: #437

@tdreyno tdreyno closed this
@rprieto

Thanks for the env-specific docs.
It makes sense to close this ticket, and I'm looking forward to the new improvements.

@andrew-aladev

just to clarify

configure :build do
  ignore "javascripts/vendor/*" # works perfect
  # ignore "javascripts/vendor" does not work
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.