rendrjs / rendr-app-template

Basic skeleton for a Rendr app. Deprecated in favor of ./examples dir in rendr repo.
MIT License
285 stars 83 forks source link

Modularization of the site #52

Closed jskulski closed 10 years ago

jskulski commented 10 years ago

Hey spike + others;

We were working off this for our mobile app. For deployment we thought it would make sense to have two modules:

We thought that would be nice for deployment, pushing work to npm and also allowing us to use grunt for devtasks like linking githooks etc.

I am having issues doing this though, it looks like rendr.entryPath works for the server but breaks down on the client side. So far I've:

Now clearly the last thing was just a hack and we're still running into issues and things aren't working correctly. I can give better details, but my questions are a little higher level:

Is this a wacky idea in general am I fighting against node/the framework? Or is this just not a well tested use case?

spikebrehm commented 10 years ago

@jskulski good to hear from you. I'd like to support this use case, but I've just never tried, which would explain why it doesn't work. I'm glad to help considering we're planning to reorganize our own mobile web app, using something like apps/moweb instead of site. We've found it's really useful to encapsulate little bits of site functionality like mini-sites or landing pages in their own Express apps, so we would reorganize like this:

apps/
    moweb/ (Rendr app)
    status/ (small utilities)
    my_landing_page/ (i.e.)
server/
    middleware/ (shared middleware)
    index.js (main Express app)

and server/index.js would have lines like:

var express = require('express')
  , mowebApp = require('../apps/moweb/app')
  , statusApp = require('../apps/status/app')
  , myLandingPageApp = require('../apps/my_landing_page/app')
  , mw = require('./middleware')
  ...;

var app = express();

app.use(mw.someGlobalMiddleware());
app.use(statusApp);
app.use(mowebApp);
app.use('/my_landing_page', myLandingPageApp);

We also want to be able to mount separate Rendr apps in the same codebase using this method, but rendr.entryPath is the last part.

Can you send over a quick sample app showing your approach so far?

jskulski commented 10 years ago

@spikebrehm Very happy this is all happening.

I wasn't quite sure about the pattern, so glad to hear you had a similar idea. Gives me confidence that it's a good solution.

We have our project folder and a copy of the rendr-app-template in site. So:

project/
  Vagrantfile
  config/
  puppet/
  readme.md
  site/

I split the problem into two parts: moving grunt to the root directory and modularizing our site. I tried moving grunt first, got stuck and then tried modularizing. I started to run into the same errors so I believe they have a common root.

First thing was moving grunt to the root level and adding the site/../ location the grunt config. We also had to create a package.json to get the server to run.

beaker/
  Gruntfile.js 
  package.json
  ...the rest..

Now that we have grunt server running, we load the app and hit it and get an express error:

500 Error: Failed to lookup view "home/index"
at Function.app.render (/Users/jskulski/Code//beaker/site/node_modules/rendr/node_modules/express/lib/application.js:495:17)
at ServerResponse.res.render (/Users/jskulski/Code//beaker/site/node_modules/rendr/node_modules/express/lib/response.js:756:7)
at /Users/jskulski/Code//beaker/site/node_modules/rendr/server/router.js:83:11
at Object.module.exports.index (/Users/jskulski/Code//beaker/site/app/controllers/home_controller.js:3:5)
at /Users/jskulski/Code//beaker/site/node_modules/rendr/server/router.js:71:12
at callbacks (/Users/jskulski/Code//beaker/site/node_modules/rendr/node_modules/express/lib/router/index.js:161:37)
at param (/Users/jskulski/Code//beaker/site/node_modules/rendr/node_modules/express/lib/router/index.js:135:11)
at pass (/Users/jskulski/Code//beaker/site/node_modules/rendr/node_modules/express/lib/router/index.js:142:5)
at Router._dispatch (/Users/jskulski/Code/beaker/site/node_modules/rendr/node_modules/express/lib/router/index.js:170:5)
at Object.router (/Users/jskulski/Code/beaker/site/node_modules/rendr/node_modules/express/lib/router/index.js:33:10)

Interestingly enough, we also eventually run into this error when we try to modularize the site. Without moving grunt.

Next I created a simple index.js like so (and exporting the start function)

var beaker = require('./beaker');
beaker.app.start()

the server will run but rendr is looking in the wrong place for modules. We will get errors like:

Error: Cannot find module '/Users/jskulski/Code/beaker/app/routes'

I can use paths.entryPath in config to hardcode the right directory, but that seems like it shouldn't be necessary if things were modular.

jskulski commented 10 years ago

Some other things I've found:

If I add an entryPath to config:

 paths:
    entryPath: /Users/jskulski/Code/beaker/site

Then the server loads module correctly but express has an issue loading modules. This error is from express:

500 Error: Cannot find module '/Users/jskulski/Code/beaker/app/app'

in rendr/server/middleware/initApp.js we can see why this is failing. In line 12:

var App = require(rendr.entryPath + '/app/app');

rendr.entryPath at this point is not the one used in config but seems to be process.cwd(); adding in site here, ends us at the view error that we discovered above:

500 Error: Failed to lookup view "home/index" 

And I believe this is due to rendr's index.js, line 12:

  exports.entryPath = process.cwd();

If I add /site to that, that has the same effect as adding /site to middleware/initApp.js, line 12 (above.) Do we have access to the config yet?

spikebrehm commented 10 years ago

@jskulski I just added an example to the examples directory of airbnb/rendr (which will supercede airbnb/rendr-app-template) to show how to do this in a basic way:

https://github.com/airbnb/rendr/tree/master/examples/04_entrypath

It required this change to the Rendr source: https://github.com/airbnb/rendr/commit/91401ae462da4954512e00e80fa94a988f458053

Which should fix the 500 Error: Failed to lookup view "home/index" error you encountered.

Note here where I explicitly set rendr.entryPath:

https://github.com/airbnb/rendr/blob/2f22f8c422e92b98131ddd06724f0ed65477b885/examples/04_entrypath/apps/main/index.js#L7

Now, this is kind of dirty (and makes it hard to run multiple Rendr apps in the same project) so I'll see if I can get it to work with the paths.entryPath config option. In the meantime, see if this works for you.

jskulski commented 10 years ago

Awesome, @spikebrehm. This is what we were going for. Multiple rendr apps will be nice, but this gives us a good ground for our build / release process. Thanks!