rendrjs / rendr

Render your Backbone.js apps on the client and the server, using Node.js.
MIT License
4.09k stars 313 forks source link

modelUtils - hardcoded typePath #493

Open crwang opened 8 years ago

crwang commented 8 years ago

Hi guys,

I'm trying to restructure our app in a way that would be more conducive to require js bundling.

What I'd like to do is have this structure:

├─┬ app
│ ├── collections
│ ├── controllers
│ ├── lib
│ ├── models
│ ├── templates
│ ├── views
│ │
│ ├─┬ bundle1
│ │ ├── collections
│ │ ├── controllers
│ │ ├── lib
│ │ ├── models
│ │ ├── templates
│ │ └── views
│ │ 
│ └─┬ bundle2
│   ├── collections
│   ├── controllers
│   ├── lib
│   ├── models
│   ├── templates
│   └── views

I personally feel this structure will make the requirejs bundling much cleaner and it could help with making things more componentized so that people could more easily share code.

However, modelUtils is currently hardcoding typePath with the app on the front as:

var typePath = {
  model: "app/models/",
  collection: "app/collections/"
};

https://github.com/rendrjs/rendr/blob/master/shared/modelUtils.js

It doesn't seem like there's a really simple way to workaround this without breaking changes.

One idea is to allow passing in a forward slash so a model could have the name:

/bundle1/model_name and then getFullPath in modelUtils could look for that and not prepend app, but that's pretty ugly and a patch.

Any thoughts on this?

alexindigo commented 8 years ago

Hey, Nice to see you thinking about future of Rendr.

I'll start from the end. I've been there – starting things with / that are not the root of the FS, it's a slippery slope, leads to many bugs and much confusion (in node and in the browser). I found that sticking to the AMD narrative of having baseUrl and not using leading / is much saner approach.

As for proposed structure, for me it looks very similar to:

├─┬ app
│ ├── collections
│ ├── controllers
│ ├── lib
│ ├── models
│ ├── templates
│ ├── views
│ │
│ ├─┬ node_modules
│ │ ├─┬ bundle1
│ │ │ ├── collections
│ │ │ ├── controllers
│ │ │ ├── lib
│ │ │ ├── models
│ │ │ ├── templates
│ │ │ └── views
│ │ │ 
│ │ └─┬ bundle2
│ │    ├── collections
│ │    ├── controllers
│ │    ├── lib
│ │    ├── models
│ │    ├── templates
│ │    └── views

Which allows better comparability and it will be easier for different kind of bundlers (not only requirejs).

And regular require('bundle1/controllers/my_controller.js') would work. And it will allow to have separate code bases, versioning and all the goodies that big (multi-bundle) projects need.

It still might require to modify Rendr, but it should be more along with the way everything else works in node. And I think it's possible to make it backwards compatible. For example if "first folder" in the path doesn't exist, try to resolve it as node module.

Sidenote: I'm working on new bundler for requirejs, that will make it much easier to have separate bundles with existing structure. But it's more somewhat short-term solution before we have everything in separate node module. – https://www.npmjs.com/package/multibundle (still work in progress)

crwang commented 8 years ago

Thanks @alexindigo great suggestions. I was thinking of breaking into node_modules as a second step but if we need to modify rendr to accomplish this, you may be right that the best way to break it up would be to look into the node_modules path to help modularize as we were discussing previously. I'l take a look at this sometime this week some. I have a feeling there will be more complications than model utils putting things into node_modules now, but I think it's the best approach for the future. :smile: