Rails Asset Pipeline to a Grunt based approach - ruby-on-rails

I wish to try out Grunt so for a task I have duplicated a project and want to convert it from using the default asset pipeline to work all via Grunt and it's tasks.
I can then evaluate both approaches and go for what I think turns out the best.
I have disabled the pipeline in my application.rb file. I have set up my Gruntfile.js and want to first of all get it to concatenate my javascript files. I am using the grunt-contrib-concat task but what I cannot figure out is the best place to tell grunt to place the processed files?
Would it be in /public? I am just confused as to where these files will now be served from? I know that I cannot use the Rails asset helpers in my views and will have to reference them myself, but from where?
I hope you can help.

Related

Ruby on rails resource issue

I have a project that includes lots of js, css and png. I couldn't divide them into javascripts and stylesheets folders. For example I have plugin1 folder it includes js and css files and I want to keep them together in same folder. Could you help me?
If you want to use the rails assets pipeline Im nearly certain that you'll have to put the files into the correct location as described in the ruby guides. Rails will then pull all this together to create, for example, the js file. It would be, I imagine, a big job to change this set up.
I guess if your set on keeping the folders the same you'll just have to point to the JavaScript/CSS files the traditional way through the header/footer with links to the file locations.
The rails guides explain the asset pipeline pretty well, and are a good place to start digging around further.
Good luck!

Is it possible in Rails to have different assets directories for different environments?

Before executing Asset Precompile (rake assets:precompile) I want to apply gulp tasks to my JavaScript files which are located here:
app/assets/javascripts/my_angular/directives/*.js
app/assets/javascripts/my_angular/controllers/*.js
So when I later run rake assets:precompile it will pick already processed-by-gulp files.
But the problem for me is that I do not want to simply overwrite existing JS files with its gulp output files since I still need original, not touched files for comfortable development.
I think I need to have two folders:
1) development_assets
2) production_assets (auto-generated folder with gulp output)
Is it possible in Rails to have different assets directories for different environments? (development, production). If yes - how to configure it?
Maybe there is another solution for my problem? Without having two separate directories... I am open to suggestions.
You can configure the assets path with config.assets.prefix = '/gulped-assets'. If you do that in config/environments/production.rb, it'll apply to production but not development, letting you still use your original files in dev. You'll need to either make sure your deploy process runs Gulp before asset compilation, or run Gulp locally and include /gulped-assets in your repository.
You can also add a preprocessor to the asset pipeline, which would leave you needing just one /assets directory. You do that by specifying a file extension and a handler, then adding the extension to all the files you want processed that way, just like you have with .sass, .erb, etc. To crib from the Rails examples, it looks like this:
module BangBang
class Template < ::Tilt::Template
def prepare
# Do any initialization here
end
# Adds a "!" to original template.
def evaluate(scope, locals, &block)
"#{data}!"
end
end
end
# config/initializers/bang.rb
Sprockets.register_engine '.bang', BangBang::Template
Then any file containing .bang in the extensions will have a ! appended to it. There's already support for a lot of different tasks out there, so perhaps you can avoid Gulp in favor of a Sprockets-only pipeline. Depending on your Gulp tasks, you might even be able to shell out and run data through them to build a hybrid pipeline.
Or, you can go the other direction and replace Sprockets with a Gulp-only pipeline. There are a lot of people doing that, and anything I'd write here would be long and only duplicate their work, so check out the gulp-rails-pipeline gem and perhaps read Gulp - a modern approach to asset pipeline for Rails developers for another angle on it.

Grunt and Rails

I'm working on using a Grunt workflow to manage my assets in my Rails app rather than Sprockets.
So far, I have my apps JS and CSS both being concatenated and minified into public/assets/javascripts/application.js and public/assets/stylesheets/application.css respectively.
And also have my Bower components JS and CSS being concatenated and minified into public/assets/javascripts/vendor.js and public/assets/stylesheets/vendor.css respectively.
Fonts and Images from Bower components are then copied into public/assets/(images|fonts).
This is all well and good but now I need the references to fonts/images within those files to be updated to reflect their new location.
I have looked at cssmin and yes it rewrites file references but I cannot get the file path to change depending upon the type of file being referenced.
Any ideas on how I can do this?
Also, I ahve been reading about Grunt plugins which can read your view files and use those to minify and concatenate files and update the and tags in the views for you.
Surely I can't do that in a Rails app? Is there a way I can deal with this in Rails?
This other StackOverflow post may be of help:
Integrate Grunt into Rails asset pipeline
The accepted answer recommends using the Half Pipe gem.
The second answer linked to a blog post about a Do-It Yourself solution: Goodbye, Sprockets! A Grunt-based Rails Asset Pipeline.
I haven't used either solution, but they are worth a try.

Rake Pipeline or Rails Asset Pipeline

Trying to understand a few things about rails:
I have used rake-pipeline with rake-pipeline-web-filters successfully in the past for my front-end projects.
Recently, with a rails backend, My front-end assets are getting produced using the Rails Asset pipeline. I take it they are both similar but I am failing to align it in my head how it maps to the Assetfile way of doing things in rake pipeline.
So, questions:
Is Rake Pipeline an alternative to Rails Asset pipeline? If yes, why and what is the history & pros/cons of these two solutions? If not, how are they related?
With Rake pipeline, you addon the excellent rake-pipeline-web-filters to get all the concatenation, minification, pre-processing like scss, minispade etc. With Asset Pipeline, it seems hard to configure. One immediate limitation is that all my JS is eval'd immediately and I dont have support for minispade in the Assset Pipeline. The alternative to that is the minispade-rails gem.
In general, I am trying to understand how to go about getting a similar build process with rake pipeline Assetfile in Rails Asset pipeline.
Can someone clarify these two build processes and how to generally think about them?
Is Rake Pipeline an alternative to Rails Asset pipeline? If yes, why and what is the history & pros/cons of these two solutions? If not, how are they related?
rake-pipeline is not a direct alternative to sprockets. rake-pipeline is infinitely more flexible and more powerful. The asset pipeline is really just a preprocessor with concatenation. It does not make things like source maps and module wrapping easy. Sprockets does "dependency management". I quote dependency management because writing something =require inside a javascript file is a horrible way to "manage dependencies".
Rake pipeline defines a the steps required to build assets. This is the pipeline. Here's a build process you may think of:
Compile coffeescript into javascript
Wrap all javascript files in minispade modules
Concatenate all the files
Minify the concatenated file.
You can construct very complicated build pipeline. See Iridium's Assetfile for probably the most complex rake pipeline example in the world. Rake-pipeline is not just for constructing assets for web applications. It can be used to build any sort of code base. Ember.js uses it to construct release files for both Ember.js and Ember-Data. You could do this with sprockets, but it would be a huge waste of time and extremely awkward.
Sprockets seems to be optimized for development, where rake-pipeline is optimized for complex applications. Individual assets are available in development. This makes developing faster because assets don't have to be concatenated (only preprocessed if need be). This is not possible with rake-pipeline. Rake-pipeline only cares about inputs and outputs. The intermediate build files are not accessible.
You can use rake-pipeline inside of rails if you like. The rake-pipeline gem bundles a rails engine to replace the asset pipeline with itself. If you are building a complex frontend application I may recommend this. If you only want to wrap JS files in modules, then you can look into the various projects for the asset pipeline.
With Rake pipeline, you addon the excellent rake-pipeline-web-filters to get all the concatenation, minification, pre-processing like scss, minispade etc. With Asset Pipeline, it seems hard to configure. One immediate limitation is that all my JS is eval'd immediately and I dont have support for minispade in the Assset Pipeline. The alternative to that is the minispade-rails gem.
See previous paragraph.
In general, I am trying to understand how to go about getting a similar build process with rake pipeline Assetfile in Rails Asset pipeline.
This is impossible with sprockets. Sprockets functionality is really a subset of rake-pipeline. Rake pipeline can do everything sprockets can do and do it better. The downside is that it requires more configuration.
I recommend you take a look at assetfile I linked. It can give you an idea what you can do with rake-pipeline. Here are some thing's I've done with rake-pipeline.
Include environment specific JS/CCS (like production, development, test) etc in my final build
Allow other code to tie into my build process with hooks
Create initializer files for my Ember application
Precompile handlebars templates
Strip out assertions not required in production code.
Generate an HTML5 Cache manifest from my inputs
You could do all of these with the asset pipeline but it's not worth the effort.

How can all.js be created manually?

I'm using the function for caching multiple javascript files into one:
<%= javascript_include_tag :all, :cache => true %>
The way I understand it this creates the all.js file the first time a HTML file using it is generated.
But if the app is configured to use an asset host on a seperate server that does not deliver HTML the file will not be created. Is there a way to generate all.js manually on deploy?
You need to configure your deploy task in order to compress and create the file.
If you use Capistrano, you can add a callback to be executed on deploy.
Otherwise, the are a couple of alternatives that offers also a more efficient solution. The standard Rails strategy only merges all files into a single one. But you can gain additional benefit by compressing and minifying the final result. For more information you can read the GitHub asset deployment strategy or the Jammit documentation.
A great project for javascript concatenation is sprockets, which can be found here: http://getsprockets.org/
It's really easy to setup and integrate with capistrano. Might be worth a look.

Resources