{"id":13739635,"url":"https://github.com/srph/angularjs-structure-styleguide","last_synced_at":"2025-03-21T22:42:33.946Z","repository":{"id":22652145,"uuid":"25995240","full_name":"srph/angularjs-structure-styleguide","owner":"srph","description":"Thinking in Components","archived":false,"fork":false,"pushed_at":"2016-06-22T12:38:46.000Z","size":41,"stargazers_count":271,"open_issues_count":2,"forks_count":15,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-01-26T17:15:44.595Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/srph.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-10-31T00:21:59.000Z","updated_at":"2024-10-29T21:26:25.000Z","dependencies_parsed_at":"2022-08-21T09:00:49.971Z","dependency_job_id":null,"html_url":"https://github.com/srph/angularjs-structure-styleguide","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/srph%2Fangularjs-structure-styleguide","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/srph%2Fangularjs-structure-styleguide/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/srph%2Fangularjs-structure-styleguide/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/srph%2Fangularjs-structure-styleguide/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/srph","download_url":"https://codeload.github.com/srph/angularjs-structure-styleguide/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244880550,"owners_count":20525511,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T04:00:35.971Z","updated_at":"2025-03-21T22:42:33.925Z","avatar_url":"https://github.com/srph.png","language":null,"funding_links":[],"categories":["JavaScript"],"sub_categories":["AngularJS"],"readme":"angularjs-structure-styleguide\n==============================\n\nBasic, personal, opinionated style on structuring your AngularJS, adhering to [John Papa](https://github.com/johnpapa)'s [LIFT principle](https://github.com/johnpapa/angularjs-styleguide#application-structure-lift-principle).\n\n**What is LIFT?**\n\n- ```L```ocating our code is easy\n- ```I```dentify code at a glance\n- ```F```lat structure as long as we can\n- ```T```ry to stay DRY (Don’t Repeat Yourself) or T-DRY\n\n## Unmaintained\nThis style guide is no longer maintained.\n\n## Table of Contents\n\n1. [Context](#1-context)\n2. [Overview](#2-overview)\n3. [App](#3-app)\n4. [Core](#4-core)\n5. [Components](#5-components)\n6. [Overall](#overall)\n\n## 1. Context\n\nThis was created to offer a *more* in-depth guide for AngularJS developers that want their apps to scale, maintainable, and whatever\n\n**This guide gives emphasis to components or directives** inspired by [ReactJS](facebook.github.io/react/) and [Flux](facebook.github.io/flux/). For more information in regards to this emphasis, check this [article](https://medium.com/@srph/breaking-down-angularjs-to-smaller-components-f2ab70a104d0) I wrote on Medium.\n\nPlease, feel free to diverge from this guide.\n\n[Back to top](#table-of-contents)\n\n## 2. Overview\n\nBasically, this is how our app will be.\n\n### First-level simplification\n\n```\n├── app/\n├── components/\n├── core/\n├── dist/\n├── less|sass/\n├── vendor/\n```\n\n### Extended\n\n```\n├── app/\n|  ├── user\n|  |  ├── partials/\n|  |  ├── components/\n|  |  |  ├── ThatDirective/\n|  |  |  |  ├── i18n/\n|  |  |  |  ├── tests/\n|  ├── user.create/\n|  ├── user.edit/\n|  ├── newsCategory/\n|  ├── newsCategory.create/\n|  ├── newsCategory.edit/\n├── components/\n├── core/\n|  ├── constants/\n|  ├── filters/\n|  ├── resources/\n|  ├── services/\n|  ├── utils/\n|  ├── app.js\n|  ├── bootstrap.js\n|  ├── constants.module.js\n|  ├── filters.module.js\n|  ├── components.module.js\n|  ├── resources.module.js\n|  ├── services.module.js\n├── dist/\n|  ├── css/\n|  ├── js/\n|  ├── images/\n|  ├── views/\n├── less|sass/\n├── vendor/\n```\n[Back to top](#table-of-contents)\n\n## 3. App\n\nThe ```app``` folder contains all the app's states. And each state may contain the controllers, directives, services to be **specifically** used for itself or child states.\n\n```\n├── app/\n|  ├── user/\n|  |  ├── i18n/\n|  |  |  ├── en.js\n|  |  |  ├── kr.js\n|  |  ├── components/\n|  |  ├── tests/\n|  |  ├── partials/\n|  |  ├── user.state.js\n|  |  ├── user.controller.js\n|  |  ├── user.html\n├── ...\n```\n\n### Q: What is a state? ###\n\nUsed to register a state, see [ui-router](https://github.com/angular-ui/ui-router). This also has been asked before, see [this issue](https://github.com/srph/angularjs-structure-styleguide/issues/1).\n\n### Q: What if I started having more than 1 partial, controllers, and other things?\n\n**Stop using multiple controllers, partials, services**. It is more **recommended** to use directives for the sake of modularity and maintainability. It is only okay to use partials for chunk of non-functioning mark-up.\n\n```\n├── app/\n|  ├── user-profile/\n|  |  ├── components/\n|  |  |  ├── Avatar/\n|  |  |  |  ├── Uploader.js\n|  |  |  |  ├── Webcam/\n|  |  |  |  |   ├── Webcam.js\n|  |  |  |  |   ├── WebcamShootButton.js/\n|  |  ├── user.state.js\n|  |  ├── user.controller.js\n|  |  ├── user.html\n├── ...\n```\n\n### Q: What if I have nested states?\n\n**As much as possible, try to avoid nested *directories* of states. For example, we have this state hierarchy:**\n\n```\n- main\n  - user\n    - user.create\n    - user.edit\n    - user.delete\n    - profile\n      - profile.create\n      - profile.edit\n      - profile.delete\n```\n\nThis is how we structure our directory. Why? This way, nested states can be easily found and understood while adhering to the **LIFT** principle.\n\n```\n├── app/\n|  ├── news/\n|  ├── news.create/\n|  ├── news-category/\n|  ├── news-category.edit/\n```\n\n### Q: How do I indicate a url nest or a state nest?\n\n**Use ```.```(dot) for states of the same module**. For instance, if we have the ```users``` *CRUD* module, then we'd have ```users.create```, ```users.edit```, **...**).\n\n**Otherwise, use ```-``` to signify hierarchy**. For instance, we have a ```group``` module which is under the ```users``` module, then we'd have: (```users```, ```users.create```, **...**, ```users-groups```, ```users-groups.create```, **..**).\n\nTo elaborate, here's an example: an app consists of a news CRUD [url: ```/news/*```] and a news category CRUD [url: ```/news/categories/*```]. We expect it to have these states:\n\n```\nnews (abstract state)\nnews.index\nnews.create\nnews.edit\n\nnews-category (abstract state)\nnews-category.index\nnews-category.create\nnews-category.edit\n```\n\nThis is how we create our directory:\n\n```\n├── app/\n|  ├── news/\n|  ├── news.index/\n|  ├── news.create/\n|  ├── news.edit/\n|  ├── news.category/\n|  ├── news-category.index/\n|  ├── news-category.create/\n|  ├── news-category.edit/\n```\n\n### Q: What if my state is composed of two words?\n\n**Use ``camelCase``; do not separate it with a ```-```(dash).** Do not use ```-```(dash) to signify that a name consists of two words. Use it to signify a nest or hierarchy. If a state consists of two separate words (e.g, soulja boy, sticky nav), use ```camelCase```. For example, ```souljaBoy```, ```stickyNav```.**.\n\nWhy? This allows us to properly signify and understand what a dot (```.```) and dash (```-```) does.\n\n```\n├── user/\n├── user-awesomeName/\n├── user-anotherModule/\n├── user-maybeAnotherModule/\n├── user-thatModule/\n├── user-thatModule.index/\n├── user-thatModule.create/\n```\n\n### Q: Where do I put my tests or i18n?\n\n**Tests and i18n should be put close to our components or state as possible.**\n\n*Why?* This avoids the replication of our structure for our tests; and, makes them easier to view.\n\n### Q: How do I handle each language for the i18n?\n\n**The filename of each i18n should signify only the language it is supposed to handle**. If a component only has one i18n file, simply put it at the same directory it will be used with.\n\n```\n|  ├── user\n|  |  ├── en.js\n|  |  ├── user.controller.js\n|  |  ├── user.state.js\n|  |  ├── ...\n```\n\n[Back to top](#table-of-contents)\n\n## 4. Core\n\nThe ```core``` folder contains all ```modules```, app ```bootstrapper``` (see [```angular.bootstrap```](https://docs.angularjs.org/api/ng/function/angular.bootstrap)), and all *common* or *shared* files (in short, non-specific components) used in the app such as ```services```, ```constants```, ```controllers```, ```resources```, ```utils```, and ```filters```.\n\n```\n├── core/\n|  ├── constants/\n|  ├── filters/\n|  ├── resources/\n|  ├── services/\n|  ├── utils/\n|  |   ├── progress.config.js/\n|  |   ├── restangular.config.js/\n|  ├── app.js\n|  ├── bootstrap.js\n|  ├── constants.module.js\n|  ├── components.module.js\n|  ├── filters.module.js\n|  ├── resources.module.js\n|  ├── services.module.js\n```\n\n### Q: What does each of the js file in the *root* of the ```core``` folder do?\n\n- ```app.js``` is our application module, the highest-level module, which contains all other modules. For instance, ```angular.module('app', ['app.resources', 'app.directives', 'app.services', 'app.constants']); ```.\n- ```bootstrap.js``` does nothing but bootstrap the app ```angular.bootstrap(document, ['app'])```.\n- ```*.module.js``` is the module to be respectively used for each (all *constants* in the ```constants/``` directory should use ```constant.module.js```).\n\n### Q: What are ```resources```?\nThese come in handy when you frequently request an API for data. Fill in ```resources``` with your $http-service-wrappers to wrap ```$http``` or ```Restangular``` methods, or store data from a server response. Otherwise, put in the ```service``` as a normal service.\n\n## 5. Components\n\nThe ```components``` folder contains mostly general-solution|non-feature-specific ```directives```.\n\n```\n├── components/\n|  ├──  StickyNavThatDoesThat/\n|  |  ├── tests/\n|  |  ├── StickyNavThatDoesThat.spec.js\n|  |  |  ├── Hamburger.spec.js\n|  |  |  ├── Search.spec.js\n|  |  ├── i18n/\n|  |  |  ├── en.js\n|  |  |  ├── jp.js\n|  |  |  ├── kr.js\n|  |  ├── tests/\n|  |  ├── StickyNavThatDoesThat.js\n|  |  ├── Hamburger.js\n|  |  ├── Search.js\n|  ├── AwesomeProgressBar/\n|  |  ├── i18n/\n|  |  ├── tests/\n|  |  ├── AwesomeProgressBar.js\n|  ├── components.module.js\n```\n\n### Q: Why is this named as ```components``` not ```directives```?\n\nIt took me a long while to decide whether how it should be named. After some time, I preferred to use ```components``` *because* our ```directives``` are actually being used as components. Again, your preference.\n\n### Q: Why are the directives separated from other angular modules?\n\nI had decided to separate directives because:\n\n1. Directives are way too large to be nested inside the ```core``` folder.\n2. They need emphasis and will contain mostly a large part of your app\n\n**Write the file names of your directives (components) in StudlyCase**.\n\n*Why? To emphasize components.* In the future, I might tweak a huge part of the guide to *StudyCase*. *camelCase* does not seem to give proper emphasis to itself, so.\n\n[Back to top](#table-of-contents)\n\n## 6. Overall\n\nDo not forget that this is a personal, opinionated structure styleguide. Although I have been using an almost-similar structure in production, your structure will vary on your project (team size, etc) from time-to-time. Make sure to keep it simple.\n\nIt is *always* better to create feature-based instead of role-based structure. Because, based on my experience, role-based structure will always be harder to write, read, and maintain.\n\nLike I said in the [Context](#1-context), please feel free to diverge.\n\n[Back to top](#table-of-contents)\n\n## Acknowledgement\n\n**angularjs-structure-styleguide** © 2014, Kier Borromeo (srph). Released under the [MIT](http://mit-license.org/) License.\n\n\u003e [srph.github.io](http://srph.github.io) \u0026nbsp;\u0026middot;\u0026nbsp;\n\u003e GitHub [@srph](https://github.com/srph) \u0026nbsp;\u0026middot;\u0026nbsp;\n\u003e Twitter [@_srph](https://twitter.com/_srph)\n\n[MIT]: http://mit-license.org/\n\nThis style guide has been largely influenced by [John Papa](https://github.com/johnpapa/)'s [AngularJS Style Guide](https://github.com/johnpapa/angularjs-styleguide#application-structure-lift-principle) (which also includes a lecture with regards to an AngularJS app structure).\n\n## Contribution\n\nI'd suggest to issue a proposal or a question first (for discussion purposes) before submitting a pull request. This avoids unrewarded / unmerged pull requests (if ever).\n\nIf you have any questions, issues, or whatever, feel free to send me a tweet on [twitter](https://twitter.com/_srph), or just submit an issue.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsrph%2Fangularjs-structure-styleguide","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsrph%2Fangularjs-structure-styleguide","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsrph%2Fangularjs-structure-styleguide/lists"}