Using Rails 3 and Ruby 2. I have the following apps:
App A
App B
Now app A and app B talk to each other via API. This is SOA. As the apps grow bigger, I found that the apps have CSS and Javascripts that can be re-used across the apps. I want to separate the assets (CSS, JS) to a different repo (e.g. app C), so that app A and B can just use the same assets repo.
Here are my questions:
For deployment, app C should precompile and minify, and app A and B should point to that repo. What are the options?
For development, app C should not be minified, but how should app A and B talk to app C continuously to get all changes on CSS/JS in app C?
I have searched through Google, but couldn't get much results. Perhaps my keywords were wrong. Please feel free to name the terms/conventions used for this practice.
If there are other better practices, please feel free to suggest too.
Simplest option might be to use a git submodule to share the assets files themselves between your two projects/apps.
Another option is to create your own gem with those assets files in it, and use that gem in both of your projects. This would require a little more work up front, but would be easier to manage versions down the track (git submodules need a few more manual steps to keep things updated as you change the submodule repository).
Related
I want to add frameworks like AngularJS, Bootstrap and polymer JS into my rails app. Problem with the gems is they are unstable with new versions and they even stop developing gems(which leads to failing of one gem which depends on another)
So I just want to add those frameworks directly into the application root html file via CDN(offered by the vendor). Is that a good practice? Will it cause any future problems in production environment?
Yes, if you are using reliable CDN's (and those offered my vendors can be treat as one) it may even bring you some improvements in the production enviromnent, e.g.:
those assets will be often already cached on your user's machines
it circumvents browsers limit the number of concurrent connections from the same domain (as your app)
On the flip side, on your dev enviromnent you'll have to wait a liiitle bit more for the website to load those assets comparing it to loading them from localhost ;)
if you dont use CDN,you have much control over the assets ,as they might change/update or sometimes the url can be down :( in worst case scenario..so i suggest using local assets if there is large dependency and for small dependency ...you may use cdn. :)
use this to set up polymer js onlocal.
I wanted to try out Angularjs. However, I have been trouble deciding on where I should located my angular app.
I am using Rails framework for the backend. I have seen tutorials where the entire angular app lives under the assets/javascript folder.
I was wondering if instead of living within the assets/javascript folder, I could make it live outside my rails directory entirely. That way, I can potentially separate my backend and front end entirely. (Is this recommended?).
I believe the asset pipeline also precompiles a lot of the assets. If I were to separate out the angularjs asset, would I need to precompile the assets somehow?
Thanks
I've been working through a similar set of questions. There are some good tools that allow you to integrate AngularJS directly into your rails asset pipeline, and they to me look good if you want just a little bit of Angular.
However, if you want a full Angular front-end, aka a single page web app, I think you'll eventually be limited by compatibility and some of the tooling. I feel like the Rails gems won't quite keep up with Angular, and so you'll be into version conflicts. I've also seen more and more tooling for Angular as a standalone, and I very much like the ng-boilerplate project template. I also like much of the testing tooling such as karma, and I haven't really sorted out a way to integrate karma with rails.
For that reason, I eventually decided that I'd keep the two separate. Initially, I did that through creating a rails application and a separate angular application (separate directories). I used ng-boilerplate as the framework for the angular end. I wrote a tutorial on that. This eventually got a bit frustrating, and I wrote some more thoughts on it, the main annoyance was that I had two git repositories and it was annoying to keep them in synch. It's also sort of annoying working with an IDE across two directories. I've ended up shifting to rails and angular being in the same folder, and they seem to play nice, as each uses different directories within that project.
In this current structure, I'm using the grunt setup that came with ng-boilerplate to minify all the code, package it and also run karma unit testing. I haven't yet nailed the end-to-end testing, but it's on my list. I've found this to be a relatively productive work environment. My chosen structure for my pages, controllers and karma test cases has some repeated code (I'm choosing not to factor it out to maintain readability). I'm planning to extend the rails scaffold generator to create the javascript framework for me - so when I create a persons rails scaffold, it will also create a persons angularjs scaffold for me. I'll update here if and when I do that work.
EDIT: I've completed the scaffolding work as well, which allows rails to automatically generate the angularJS elements when you generate the rails models/controllers etc. The blog post is here: http://technpol.wordpress.com/2013/09/24/rails-generator-to-generate-angular-views/
You could use a grunt based workflow:
How to manage AngularJS workflow with lots of script files
http://newtriks.com/2013/06/11/automating-angularjs-with-yeoman-grunt-and-bower/
If you start with a decoupled frontend, use mocks at first so you can stay within angular and not lose focus switching between backend and frontend logic. An advantage of building a single page application is that you can develop it independently of the backend api. See (http://docs.angularjs.org/api/ngMockE2E.$httpBackend) for information about mocking http responses.
We have been using AngularJS with our Rails application, in a way where we have been using Rails ERB templates, but switch over to using ng directive as and when required.
For this above setup we have used bower/bower-rails gem, which lets us use bower to manage the angular packages and their dependencies. We commit this into our repo, in the javascripts directory, and is taken care of by the Rails asset pipeline.
This setup has worked well for us considering we have above 50-50 % split of our views between the ERB templates and Angularjs.
More about this setup in the links below:
http://angular-rails.com/bootstrap.html
http://pete-hamilton.co.uk/2013/07/13/angularjs-and-rails-with-bower/
http://start.jcolemorrison.com/setting-up-an-angularjs-and-rails-4-1-project/
There are many advantages of separating out your api service (rails in this case) and your frontend components. As we do for ios/android apps, angular client can live on its own as a separate entity. It will be a static website that can be deployed on s3 or any static website host. It just needs to communicate with your api service. You could setup CORS to make it possible.
Some advantages of this workflow
You could use rails-api, which is a subset of rails application. If you are just going to use rails to build apis, it doesnt make sense to have all functionality that a complete rails app provides. Its lightweight, faster and inclined more towards building API first arch than a MVC arch.
You could use yeoman angular-generator to generate an angular app and make the most of grunt & bower to manage build (concat,uglify,cdnify etc) and dependencies (angular modules).
Deployments will become flexible. You won't need to depend on one to push the other.
If you ever plan to change your backend stack (eg rails to play/revel), you would not need to worry about your client components.
By splitting the development of the frontend and the Rails backend you could distribute the work over two development teams and keep the application as a whole very extensible.
There is also one downside to this approach.
By having the applications in two separate repositories, you can’t easily have a full integration test. So you will have to test the apps separately. You could mock your apis to test angular app.
We have been using this approach and would recommend others the same.
Less dependency & more productivity.
I was hoping you folks could recommend a "best practice" for source controlling binary assets for a Rails site in git.
My main concern is that as we work on the site, constantly adding and removing 500kb+ images from our git repo, the repo will eventually get pretty fat and unwieldy and we'll either have to manually remove those images from history (prone to disaster, as far as I can tell) or put up with a long initial download and extra wasted space on disk.
What are some alternatives for separating the app's logic from the assets? Git submodules? Anything else?
Thanks!
It seems this is pretty well covered elsewhere on SO and elsewhere. A start (after 5 seconds of searching):
On how binary files are tracked: http://osdir.com/ml/git/2009-04/msg01221.html
Seemingly relevant: Managing large binary files with git
If you're really seeing bloat in your repo and are wanting to keep the main rails app repo free of this, you can look into git submodules - all changes to the images would be kept within a separate assets (for example) repo, keeping your main repo free of incurred bloat.
Add the images folder to your .gitignore file. e.g.
/app/assets/images/*
I am interested in the pros and cons of the different tools for managing assets in Rails 3.0.x (especially on Heroku).
There are already some older questions regarding this topic, but in the meanwhile there are some new tools available.
I am especially interested in these tools:
Jammit
AssetHat
Rack PageSpeed
Jammit seems to can do everything that AssetHat can do and is also longer available. So where does AssetHat fit in?
Rack PageSpeed seems to do everything on the fly by directly working on the server response. Did you experience any performance issues by doing that? Would you recommend it over the other two solutions?
Hey there, I'm the author of AssetHat. Minification and concatenation are among the easiest performance boosts to implement; these features are common to Jammit, AssetHat, and rack-pagespeed. Rails has supported concatenation for a long time now (though it's done at runtime, rather than during deployment), and it's no surprise that Rails 3.1 supports both minification and concatenation during deployment.
The remaining features are what make each of these asset managers interesting. For example, Jammit is useful if you want to embed images and font files directly into your stylesheets. rack-pagespeed is also handy if you want to keep all your optimizations in a completely separate layer.
Inlining assets into CSS is great for static pages where stylesheets change infrequently. However, if your site is under active development, and the stylesheet changes even a tiny bit, the user's browser has to re-download the whole thing—including inline images and fonts that probably didn't change. It depends on the nature of your project.
If your assets are too big to inline or concatenate, AssetHat helps optimize for CDNs and parallel loading:
It takes great advantage of CDNs, whether it's Google's CDN, cdnjs (which uses Amazon's servers), or another CDN of your choosing. For example, just add <%= include_js :jquery %> to your layout (and a version number in a config file) to load jQuery from Google's CDN. If you're in dev mode and have a local copy of jQuery, that loads instead—easy offline dev.
AssetHat can rewrite stylesheets' image URLs to use your CDN instead. This reads from your config.action_controller.asset_host setting, and is done at deploy time. Your original CSS is left untouched.
If you have several JS files to load, it's sometimes faster to load them in parallel than to concatenate them (i.e., force them to load serially). You can switch on LABjs mode easily: <%= include_js 'big-file-1', ..., 'big-file-n', :loader => :lab_js %>. If you don't have a copy of LABjs locally, or if you're in production, LABjs loads from Amazon's servers via cdnjs.
By using CDNs like Google's or Amazon's, your users can load more assets in parallel (because there are more hostnames), enjoy greater speed, and sometimes, not even need to download assets at all (e.g., if they already loaded Google's copy of jQuery via someone else's website).
I've used AssetHat on Heroku by setting my deploy script to simply run rake asset_hat:minify (to minify and concatenate CSS/JS), commit those changes to my repository, then do the actual deployment.
In case you haven't seen these already, you might be interested in:
a longer walkthrough of AssetHat's features
the official website
the technical readme
the extensive docs
If you need help setting it up, or have any other questions, feel free to message me on GitHub (rondevera) or Twitter (#ronalddevera).
Jammit won't work out of the box on Heroku as far as I know. One option seems to be to use the Heroku Jammit plugin to manage your assets - https://github.com/chebyte/heroku-jammit.
Alternatively, Jammit can be configured to output to /tmp: http://geekninja.blogspot.com/2011/04/making-jammit-jam-with-heroku.html
Rails 3.1 will include Sprockets to handle asset packaging, I think that's worth considering.
I am currently using jammit on heroku, together with amazon s3, and it works like a charm :)
I can't say much about the others tools because I have not used them.
Which one did you pick, in the end?
Fernando.
For every project it's like having two parts: the Rails application and then all documents and pictures related to it.
I wonder how you organize them both.
Do you put everything under the same project root folder and apply Git on that folder or don't you protect your documents with Git at all?
Then, what if the docs are too sensitive or only for owners of that project. Then I probably should't have it under the same folder right?
How have you structured both your Rails code and belonging business documents?
Share your solutions!
If you're deploying with capistrano, as a lot of Rails apps are, the standard solution seems to be to keep these sorts of assets within the shared folder, and then get cap to symlink them into the application at the point of deploy.