JonAbrams / synth

The first back-end framework specially designed for single-page web applications
http://www.synthjs.com
MIT License
969 stars 70 forks source link

Front End Directory layout and more #51

Open franleplant opened 10 years ago

franleplant commented 10 years ago

Hi! I have been looking at Synth and I think it's awesome, the Back End side is pretty neat and simple, in fact you read my mind because I was planning to work on something similar.

There are a couple of things that I think that Synth needs to improve in order to live up to its potential, in particular, things related to the Front End, in order of importance:

1. Proper Angular.js Directory Layout

There has been a lot of discussions about Angular.js Directory Layout, in fact the Phone Cat official Angular.js tutorial uses the current Synth Angular directory structure, but the reality is that when working with non-trivial Angular apps this layout becomes obtrusive and just messy.

That's why a lot of smart people, even the Angular Guys, have been proposing alternative layouts that are module oriented instead of abstraction oriented:

My experience with Angular.js supports the Module Oriented directory structure, it fits better with the way of thinking and creating apps and it encourages better practices.

I think that Synth should go for this structure instead of the current abstraction-oriented layout.

Corolari: Implementing this structure will probably need Synth to integrate a more complex build system for which I encourage Browserify, I also can provide help with it.

2. Template Cache instead of Script tags

Angular.js has a built in mechanism to solve the Template Caching that currently Synth is solving with the <script id='path/to/template.html' type="text/ng-template">, which is more sophisticated and less obtrusive to the HTML document: enter Template Cache.

There are, also, components for both Grunt and Gulp that automate this process:

Please note that this are not the only ones, just the first that Google showed, but they do work seamlessly.

3. Preloaded Data should not be a Global Variable.

I think that the Preloaded Data is a great Idea, but I think it should not be a Global Variable, for starters it's really obtrusive for the HTML when you have a lot of data and it feels like Synth is getting a side track to implement this.

I believe there is a better way of solving this: Angular Service:

//common/preloadedData/preloadedData.js
angular.module('synth.preloadedData', [])

.factory('PreloadedDataService', function () {

  var preloadedData = { ... filled in the server ...};

  return preloadedData;
});

In this way you are not going Around angular in order to get this feature done.

4. Test integration by Default

I know this has its complexities to implement, but I strongly believe that Synth should come right out of the Box with testing in mind, it should have at least Front End and Back End test boilerplate and opinions about it. And if you are as crazy as I am with testing Synth you have Integration testing and High level testing with it, the Angular.js default is Protractor.

Other notes

I think that in some point Synth is going to need some type of Build System to delegate all the task that regularly needs to do, for which I strongly suggest Gulp instead of Grunt. And this are my personal reasons, but there are a lot more out there:

Synth has a lot of potential, and I'd be glad to submit pull requests implementing this in my spare time, I'd like your feedback, let me know what you think!

Fran

JonAbrams commented 10 years ago

Thanks so much for the very well thought-out and presented feedback!

On to your specific feedback:

Proper Angular.js Directory Layout

I agree that enforcing the current images/css/js/html directory structure just isn't flexible enough. Perhaps Browserify can help but I don't have any experience with is unfortunately. I'd be curious what an example front/ directory structure would look like using it.

Template Cache instead of Script tags && Preloaded Data should not be a Global Variable

Both of these make a lot of sense but would require server-side rendering of a js file. The pro would be cleaning up the index html served to the client, the downside would be an extra round-trip to the server to fetch the file, and remember that it cannot be cached. Of course, if the server + client support SPDY/HTTP2.0 then this would definitely be the way to go (since it can be sent with the html in the same request), but for now I think we're stuck placing this in the index html.

If you do have a lot of preloaded data, you can place the script tag that loads it at the bottom of your body element. Perhaps I'll even do that for the default template.

Test integration by Default

Agreed! It'd be nice to have it built-in, but I haven't spent a lot of time thinking about how this would look. I'm open to suggestions.

My thinking is that when you run synth test [-b|-f|-r] it runs the test commands commands defined in synth.json inside back/ and front/ respectively. Where -b is back-end, -f is front-end, and -r is root (i.e. for integration tests). That way you can have a tests folder inside back/, front/, and the root of the project that can be run with a single command.

Build system

On the topic of a build system, I've already started to investigate (but not yet implement) Gulp support. I agree, it's much nicer to work with than Grunt.

Next Steps

I'd love to see you make an ideal Synth project directory structure and put it on github. It doesn't have to work, but it could be an interesting example to discuss what an ideal Synth project would look like. Including tests, Gulpfile, manifest files, front-end layout, etc.

franleplant commented 10 years ago

This is great talking right here!

Front directory structure

My personal favorite is something like this, which is based on the links detailed on the issue:

|- front
    |- app
      - app.js
      - app.spec.js
      |- admin (example module)
        - admin.js
        - adminController1.js
        - adminService1.js
        - adminDirective1
        - adminController1.spec.js
        - adminService1.spec.js
        - adminDirectirve1.spec.js
        - admin1.tpl.html
        - admin2.tpl.html
    |- common
      |- resource
        - resource.js
        - resourceTweets.js
        - resourceTimeline.js
        - specs...
      |- security
        - security.js
        - authentication.js
        - authorization.js
        - specs...
    |- bower_components 
    - index.html
    ...other top level files

Specs are test files.

Or at least a variant of the presented structure.

As you can see you are enabling the developer to work with modules which is a more logical way of constructing an application. Each module is developed solo, tested solo, and then integrated. The same thing for vendor angular js module.

I just discovered another resource implementing a variation of the Module Oriented layout: https://www.npmjs.org/package/generator-cg-angular

Template Cache instead of Script tags && Preloaded Data should not be a Global Variable

Id like to separate both again :)

Template Cache instead of Script tags

This wont require any server side rendering or another call to the server to get it. I was using the Gulp plugin which generates an Angular Module with all the templates cached inside it and then you integrate it with your build system, for example Browserify, which, if desired, will output an unique js file to be loaded from the index.html (in production mode). Templates dont change as often as data so you can include them within your build safely.

Preloaded Data should not be a Global Variable

Agree. I will think further about other ways of solving this.

Rest

I agree with everything else. Thank you for using Gulp!

I will be making the directory structure layout today if I find the time.

Thank you! Fran

JonAbrams commented 10 years ago

Awesome, I look forward to it!

franleplant commented 10 years ago

Hi! Sorry for not getting this sooner.

The front directory inner layout would be something like this:

https://github.com/franleplant/synth-front

I accept variants of it in any way, but I think that maintaining Module Oriented directory structure is really good.

Also the css directory is empty because there are a lot of strategies to organize Css code (Sass and Less too), I wont get to deeper into this for now, but I like Smacss way.

JonAbrams commented 10 years ago

Interesting. How would Synth know which HTML partial to preload at a given path?

Btw, I'm trying to think of how to get away from enforcing a particular front end directory structure. Having a dedicated front-end gulpfile could help. It could also define the command for running the test suite. 

Were you thinking the back folder should have its own gulpfile too?

On Fri, Jul 11, 2014 at 9:08 AM, Francisco Guijarro notifications@github.com wrote:

Hi! Sorry for not getting this sooner. The front directory inner layout would be something like this: https://github.com/franleplant/synth-front I accept variants of it in any way, but I think that maintaining Module Oriented directory structure is really good.

Also the css directory is empty because there are a lot of strategies to organize Css code (Sass and Less too), I wont get to deeper into this for now, but I like Smacss way.

Reply to this email directly or view it on GitHub: https://github.com/JonAbrams/synth/issues/51#issuecomment-48749909

franleplant commented 10 years ago

How would Synth know which HTML partial to preload at a given path?

I think that the main goal when working with Angular.js application is to build Single Page Applications, so all templates should be pre loaded when page is first loaded, thus, using the $templateCache method that we were talking previously.

Btw, I'm trying to think of how to get away from enforcing a particular front end directory structure...

It's the old discussion between Freedom and a Standard, studied way of doing things. In regards of the build system support for this, in particular Gulp, there will be no issue in supporting any directory structure.

While built in Grunt and naturally messy, the ngbp Build System has some interesting concepts, you probably should give it a look. It adds all .js files as source files, all .spec.js file as tests files for Karma and all tpl.html files as partial templates that are cached inside Angular's TemplateCache.

Were you thinking the back folder should have its own gulpfile too?

TLDR: If you need it, use it!

In general, the Back End does not need to automate tasks, the task automation is really attached to Front End assets. I was not thinking about using Gulp for the Back End but if you find any use case there is no need, from my point of view, to avoid using it.

As you probably should know, test and start routines are usually automated in package.json

dancancro commented 10 years ago

Before you go discussing and settling on a new file directory structure for this project, you might want to take a step back and consider the total costs/benefits of keeping this project separate from others or combining it with others to make something really great.

I have tried to make the options as clear as I can in the following spreadsheet. I think this is the most comprehensive such illustration. So please give it at least a look before you set a course. I've added a new sheet called "Net advantages" so you can easily compare each pair of options. http://www.dancancro.com/comparison-of-angularjs-application-starters/

Modular file organization seems to be universally accepted as better. From my research, I have come across 8 generators that have this characteristic. So I would have a look at them.

Providing freedom of file structure seems pretty important to you. Could you say a bit about why this is the top priority? If it means not allying with others and reaping the benefits of that, it seems to be pretty expensive. If you know of any logical rationale for different organization approaches (other than making them modular) I would appreciate knowing about them.

Gulp seems to be pretty universally preferred. So I imagine the other projects will start adopting it soon if they haven't already.

Regards, Dan

P.S. If you would like to help keep the Synth column of the spreadsheet up-to-date, I would appreciate the help. I limited access to it so just send me a request to share it.

JonAbrams commented 10 years ago

Thanks Francisco & Dan, and sorry for not responding here sooner. Dan, I'll respond to you in my next comment.

Francisco, thanks for making an example directory structure, it was super helpful! I've just taken it and modified it to a format that I think is more 'synthy'. Thoughts?

Dan, thanks for making that spreadsheet, I actually found it and contributed to it a little while back, it's super handy! I'm not sure I follow you though when you suggest combining projects. If you want to discuss that further please send me an email to talk privately or create a new github issue if you feel it's important to discuss publicly.

As for allowing for modular front-end app layouts and using gulp, we're in agreement I think, see the above example I just shared with Francisco :)

When I talk of not being opinionated on front-end app structure, I just mean allowing for flexibility so that Synth supports Ember, Backbone, Angular, or any potential front-end framework. I admit now that Synth's current requirement that css, js, and html files to be in their own directories was a mistake.

franleplant commented 10 years ago

@dancancro That spreadsheet is something else! Thank you for that! Its incredible how much angular kick off starter tools are out there, and its incredible also, the fact that there are so many tools that roughly do the same, I agree with you that it will better for Synth to integrate some existing community starter instead of re inventing the wheel. That leads us to the selection process which is really something else! Im not particular happy with some of the kick starter applications in one aspect or the other, so I should review more thoroughly your list to give a honest choice, but, for example, NGBP is really nice, but its done with Grunt and its gruntfile.js is one of the worst nightmares ever existed, once tried to add sass and it was a pain to deal with, in fact, I believe that the Build System has gotten so complex that not even the NGBP developers are aware exactly of what it do. Its getting un-maintainable

One thing that Im strongly believe, is that we need to return to the source in one way or another until we create an abstraction that is not that leaky in terms of Build System, I mean, for example NGBP adds every js file to your HTML but sometimes you need to add files manually or check index.html for missing files... we can talk more about this later.

My point is that, for example, Google Web Starter Kit was created by some very famous and smart guys and takes a very simplistic approach to the build system, its just a couple of lines of code, and its really easy to turn it into a very simplistic Angular suited build system. Simple tends to be better and more maintainable.

@JonAbrams I think that the structure variant is really good, at least much more than the Synth's current.

Both:

TL; DR As for both accomplishing Directory Freedom and Scalability I suggest a very simplistic approach in terms of build system such as the one used by Google Web Starter Kit. I have been working with a fork intended to be suited for angular js (I will be using it for a real project soon), it only required some few changes.

Maybe we can integrate in someway one or the other.

Cheers!

dancancro commented 10 years ago

:( oh no, yet another best way that I need to study. Instead of just saying it's simple and better, can you clarify the specific advantages of Google Web Starter Kit over the others?

1) Everyone agrees that simplicity is better. 2) Everyone agrees that consistency is very important and the differences between styles is not so important. You often hear, "Just pick a style any style and stick to it" 3) Nobody agrees on which style to keep and which other styles to throw away even though (2). That's the thing that really puzzles me. If there were agreement on a single style, consistency which is universally valued as a good thing would become automatic.