Skip to content
This repository has been archived by the owner on Jun 15, 2023. It is now read-only.

Chaplin + Rails asset pipeline #212

Closed
starkovv opened this issue Oct 2, 2012 · 29 comments
Closed

Chaplin + Rails asset pipeline #212

starkovv opened this issue Oct 2, 2012 · 29 comments

Comments

@starkovv
Copy link

starkovv commented Oct 2, 2012

Would be awesome to have an example of using Chaplin with Rails asset pipeline and Requirejs.

@lukateake
Copy link
Contributor

Forgive me if I'm misinformed but doesn't Paul Miller's Ostio and Ostio-API provide this? I'm not a Rails guy.

@starkovv
Copy link
Author

starkovv commented Oct 2, 2012

No he didn't.

Ostio - is a repository which holds only pure coffee-script front-end app which is subject to be compiled by using build tool.
Ostio-API - is just a Rails app, there is nothing about coffee-script, javascript and backbone/chaplin especially.

@paulmillr
Copy link
Contributor

Yep, ost.io does not use asset pipeline because I prefer to decouple frontend and backend. This gives the ability to work on both projects in parallel, like we’re doing today. And to keep repos clean and much more maintainable.

After all, ost.io is just an example provider for ost.io api. Which means companies can do the same, open-source their frontends (because the real value is in the backend + data, in the most cases) and show developers that do stuff for their platform how to properly implement things. This will lead to massive API utilization etc.

A perfect example of this is Cloud.app for OS X. They gave away annotated source for their service which served as a great example backbone app.

@starkovv
Copy link
Author

starkovv commented Oct 2, 2012

Paul, I totally agree with you and I think the same way.

To be honest I use Rails asset pipeline because of its scss+compass functionality, especially about building image-sprites.

Nevertheless I'm still encouraging someone to show working example with rails asset pipeline and requirejs :-)

@paulmillr
Copy link
Contributor

building image-sprites

Sounds like a neat feature request.

I think you can use scss + compass with brunch too. Or maybe there is something shitty in brunch that prevents normal development with the stuff?

@starkovv
Copy link
Author

starkovv commented Oct 2, 2012

Probably the problem is that I'm not yet familiar with brunch.

@molily
Copy link
Member

molily commented Oct 2, 2012

I’m going to create a repository for a quickstart with Rails, probably tomorrow. The basic idea is using the requirejs-rails gem.

@ktmiller
Copy link
Contributor

ktmiller commented Oct 2, 2012

I've been implementing chaplin with requirejs on rails. The weirdest thing
we've run into is compiling with r.js and having to include the controller
files in the routes.js definition. Otherwise r.js can't seem to find the
files to compile. I don't know if it's the best solution -- hell, you might
have a better one -- but it's the one we're working with right now.

Katie

On Tue, Oct 2, 2012 at 12:04 PM, Mathias Schäfer
notifications@github.comwrote:

I’m going to create a repository for a quickstart with Rails, probably
tomorrow. The basic idea is using the requirejs-rails gem.


Reply to this email directly or view it on GitHubhttps://github.com//issues/212#issuecomment-9082748.

@molily
Copy link
Member

molily commented Oct 2, 2012

@ktmiller That’s totally fine I think, we’re doing that, too.
Per default, the Rails asset pipeline only precompiles the files which are linked explicitly (i.e. processes and copies them to /public/assets). Some optional controllers and their dependencies will be missing and Chaplin won’t be able to lazy-load them.
One way to circumvent this is to load these dependencies explicitly in the main application module. Then requirejs-rails will compile them into the application.js. If you want to keep this file small and use the benefits of lazy-loading, you can add the individual files to config.assets.precompile so they are precompiled.

@paulmillr
Copy link
Contributor

@starkovv
Copy link
Author

starkovv commented Nov 5, 2012

Thank you for your efforts!

@thomasconner
Copy link

I am curious if anyone else might be able to think of a solution as I have not.

In rails when you are about to deploy you typically precompile your assets (js, css, etc.) into minified, gzipped single files (could be multiple but different topic). However, this works for chaplinjs up until you load a controller that is matched by a route. This will result in the following being called in the dispatcher class...

# Load the constructor for a given controller name.
# The default implementation uses require() from a AMD module loader
# like RequireJS to fetch the constructor.
loadController: (controllerName, handler) ->
    controllerFileName = utils.underscorize(controllerName) + @settings.controllerSuffix
    path = @settings.controllerPath + controllerFileName
    if define?.amd
        require [path], handler
    else
        handler require path

This loads the unminified version from the asset pipeline.

My question is if there is a way to load the minified version rather then the unminified version. Hope I was clear enough and this makes sense.

@molily
Copy link
Member

molily commented Feb 4, 2013

@thomasconner, if you add the controller file to config.assets.precompile, Rails will minify the file and copy it to the assets folder (http://guides.rubyonrails.org/asset_pipeline.html#javascript-compression). But this will just minify one file, one would need to use Dir.glob or similar to precompile all necessary files.

A better way is to set up a requirejs-rails configuration for each controller, so a package with all dependencies is created (not just the controller but also models and views).

If you don’t want lazy-loading at all but just one big file, it’s possible to force including all controllers and their dependencies into the application.js. https://github.com/chaplinjs/chaplin-rails demonstrates this by requiring all controllers in Application.

@thomasconner
Copy link

Thanks! I will give this a try.

@aaronchi
Copy link

I built a simple compiler in rake that allows you to use Chaplin in the rails asset pipeline without any special extensions (commonjs/requirejs). If anyone is interested, I can put up a chaplin-rails gem.

@thomasconner
Copy link

I am very interested in this and wouldn't mind a gem. This sounds awesome!

@aaronchi
Copy link

@thomasconner Here's how I solved the loadController issue:

_(Chaplin.Dispatcher.prototype).extend
  loadController: (controllerName, handler) ->
    fileName = Chaplin.utils.underscorize(controllerName) +
      @settings.controllerSuffix
    moduleName = fileName.replace /(?:^|[-_])(\w)/g, (_, c) ->
      if c then c.toUpperCase() else ''
    handler window[Backbone.history.options.app][moduleName]

I camelize the underscored name of the controller and then search for it in the namespace that I have given to all of the classes in my chaplin app. The only thing you have to do is pass Chaplin the name of your application somewhere. I am doing this through the router:

@initRouter Newton.routes, app: 'Newton'

I'll put a gem together sometime next week with the compiler and post the link here.

@thomasconner
Copy link

Ok cool. Thanks

@molily
Copy link
Member

molily commented Feb 15, 2013

@aaronchi What’s the benefit of putting all modules in a global namespace? The whole idea of AMD is to overcome this practice. Are you probably looking for almond.js, which is a minimal AMD implementation without any loading capabilities?

@aaronchi
Copy link

@molily The AMD format can be a bit frustrating for Rails users as Rails has its own way of managing assets. Using AMD inside of the Rails asset pipeline requires special gems, and when used in conjunction with other javascript, it can be a pain to setup, and the advantages are limited IMO.

My compiler allows us to use Chaplin inside of Rails, without having to worry about AMD loaders or having to specify dependencies at the top of each class. In the end, it's just a different way of compiling the source code.

You already provide a commonjs/requirejs option. This would be a non-amd option that is targeted for use specifically in the Rails asset pipeline.

@vendethiel
Copy link
Contributor

Using AMD
i
s
a pain

Just joking, don't hit me, thanks for your work :p.

@molily
Copy link
Member

molily commented Feb 15, 2013

Rails has its own way of managing assets

Unfortunately yes. It’s not an interoperable way to specify modules and dependencies in JavaScript, so it has no general value. I’m using Rails a lot but I try to avoid that. I agree that requirejs-rails, r.js and require.js/almond.js aren’t easy to set up, but it’s really worth the time to set up a build/packaging tool and a module loader that actually understands your JavaScript code and its dependencies.

Anyway, if you’re working on a way to translate the CJS require statements into asset pipeline requires, I think this will be useful for several people.

… without having to worry about AMD loaders or having to specify dependencies at the top of each class.

O RLY? Specifying module dependencies (or, if possible, use dependency injection) is a crucial feature of software systems. That’s why Chaplin is using AMD/CJS after all.

@starkovv
Copy link
Author

@molily @aaronchi After all, I agree with @paulmillr that it's not good idea to build backend and frontend in the same environment. As I think the best way in current context would be to use Rails explicitly for backend and Brunch (http://brunch.io) for frontend.

@chrisabrams
Copy link
Contributor

@starkovv Please convince some of the engineers at my office that it is better to split the environment :P

@starkovv
Copy link
Author

@chrisabrams these are actually two different apps:

  1. backend API
  2. fronend web-application / iOS application / other

I'd compare it with salad of vegetables and fruits. Not tasty, at least for me :P

@chrisabrams
Copy link
Contributor

Right, same here. We have a web app, iOS app, and Android app. Still they'd rather not split things up, even if that means repeating theirself :O

Doesn't make any sense to me...but at least it's not my team.

@aaronchi
Copy link

This is not intended to be a discussion about the 'best' way to setup an application. Some people want an option to use Chaplin in Rails so let's give them the option.

Backbone works fine without AMD. The Chaplin maintainers want to enforce AMD, and that's fine too. But it is still a useful platform that works fine when you compile it without the AMD structure.

@starkovv
Copy link
Author

As I think the more options is available the better for everyone. That's how open-source rocks.

@paulmillr
Copy link
Contributor

The Chaplin maintainers want to enforce AMD

Actually I don’t like AMD. You still can use chaplin without AMD, with Brunch, which uses synchronous common.js modules.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants