mauricemach / zappa

Node development for the lazy.
zappajs.org
MIT License
949 stars 81 forks source link

App paths mask JS resources #94

Closed smathy closed 13 years ago

smathy commented 13 years ago

With this app:

require('zappa') ->
  @enable 'serve jquery'

  @get '/:foo/:bar?': ->
    "Foobar"

Try to go to /zappa/jquery.js and you'll see "Foobar" instead.

mauricemach commented 13 years ago

Yeah that one crossed my path too (pun unintended) and I've been thinking of the following API to be able to control the routes priorities (and customizing mounting paths while we're at it):

@serve jquery: '/custom/path/jquery.js', 'sammy', 'whatever'

@get '*': 'catch-all'

@serve would register the routes right away (contrary to @enable, which is just registering a setting to be interpreted later), so they wouldn't be preceded by the catch-all route.

But then again I'm not even sure if this "vendor + serve" thing will stick around much longer, as we actually need a real solution to client-side dependencies deployment. I've been talking to @epeli about that, and I've been considering how his piles project, ender, browserify, stitch, connect-assets and others could/should be integrated to zappa.

smathy commented 13 years ago

Is there ever a situation where you would want the static assets overridden by a dynamic handler? I think the @serve should always unshift the route onto the list of routes. My expectation is that those are static routes, just like the static handler provides, even if I have this code:

@get '/:foo/:id?': ->
  "Foo #{@params.foo}"

@serve 'jquery'
esamattis commented 13 years ago

No, I think there should not be such scenario at all, because many like to use some proxying server such as nginx that serves the static assets. You cannot override it from the app below it.

smathy commented 13 years ago

Well, real static assets served from nginx (or something) in front of the zappa app cannot be overridden by the app. But the three JS resources that zappa serves (jquery, sammy & zappa) are a different because zappa exposes them on a static-looking URL, but the files themselves are elsewhere.

smathy commented 13 years ago

I've been thinking about these paths, and I'm wondering whether they would be best implemented as middleware that sits in front of app.router - and therefore would happen before and independent of any of the normal app's routing.

esamattis commented 13 years ago

@smatthy actually node-pile does exactly that. Partial integration of node-pile to Zappa is in this pull request.

smathy commented 13 years ago

Until this is fixed, the following workaround works nicely:

require('zappa') ->
  @enable 'serve jquery'

  @get '/:foo/:bar?': ->
    return @next() if @params.foo is "zappa"
    "Foobar"
mauricemach commented 13 years ago

I've been thinking about these paths, and I'm wondering whether they would be best implemented as middleware that sits in front of app.router - and therefore would happen before and independent of any of the normal app's routing.

@smathy: You're right, they shouldn't be routes but middleware. They're a separate concern.

I don't think we should hard-position this middleware though. What if I want to, say, put gzip in front of everything?

So, I'll be pushing to master soon a version with @use 'zappa' replacing @enable 'serve zappa|jquery|sammy'. Both @client and @shared will add it automatically if it's not already there. Express does a similar thing with @app.router, it's automatically added when you define a route, if it has not been added before.

These assets will come before your routes as long as @use 'zappa' or one @client/@shared is placed before @use @app.router or any @get/@post/etc.

@epeli: I've been analyzing asset management in node and for the moment I'll avoid strongly coupling zappa to any specific solution. I'll elaborate on the mailing list thread.

smathy commented 13 years ago

Seems good, I'll have a closer look tomorrow.