{
    "componentChunkName": "component---src-templates-post-js",
    "path": "/blog/2013/05/22/lessons-learned-kicking-off-an-angularjs-project",
    "result": {"data":{"site":{"siteMetadata":{"title":"your friend Joel's digital garden","description":"Articles and notes from a collaborator at egghead.io. Musings on software, business, and life from a skilled virtual assistant.","author":{"name":"Joel Hooks"},"keywords":["Video Blogger"]}},"mdx":{"excerpt":"After a year of working with a large AngularJS project, I thought I'd share a\nfew of the lessons that I learned in the process. Firstly, I love AngularJS. It\nsuits my needs exceedingly well, and I expect it will be my goto for the…","fields":{"github":"https://github.com/joelhooks/joelhooks-com/tree/master/content/legacy_blog/2013-05-22-lessons-learned-kicking-off-an-angularjs-project.markdown"},"body":"var _excluded = [\"components\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"layout\": \"post\",\n  \"title\": \"Lessons Learned: A Year with a Large AngularJS Project\",\n  \"date\": \"2013-05-22T00:00:00.000Z\"\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, _excluded);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"After a year of working with a large AngularJS project, I thought I'd share a\\nfew of the lessons that I learned in the process. Firstly, I love AngularJS. It\\nsuits my needs exceedingly well, and I expect it will be my goto for the\\nforseeable future when I need a solid framework for \\\"thick client\\\" single page\\napplications. It's awesome. The team working on it is world class, the community\\nis fantastic, and it combines a killer combo of functionality for building web\\napps.\"), mdx(\"h2\", null, \"Code Organisation\"), mdx(\"p\", null, \"This one is huge. When I arrived the app basically followed what the\\nangular-seed project represents. Lots of monolithic single files that contained\\ntoo much code. We migrated from that to using John Resig's \\\"Simple Class\\nInheritence\\\" to divide up encapsulated pieces of functionality. This approach\\nworks well, and as long as you keep the inheritance shallow generally works. We\\nwere saddled with a \\\"dirty sock drawer\\\" still, where monolithic folders existed\\nto house various types of classes.\"), mdx(\"pre\", null, \"- project -- controllers --- someController.js --- someOtherController.js --- ... --- someController99.js\"), mdx(\"p\", null, \"Which lead to a controllers folder that would twist the eyes. My new rule is\\nthat if you hear yourself humming the ABCs in your mind in order to find a\\nspecific file, your folders probably have too many files.\"), mdx(\"p\", null, \"Today I'd want to start building my project in a more modular fashion. Each\\ndiscreet bit of functionality, or functional area, contains the majority of the\\nfiles/classes/objects that it needs to function. In a perfect world, these\\nmodules would be completely modular, and could be extracted and placed in other\\nprojects as reusable \\\"meta\\\" components. This is difficult sometimes because you\\nwill likely also need a set of common utilities, helpers, or other such files\\nthat serve as shared dependencies across your modules. Unless reusability is a\\nrequirement, I won't spend a lot of time ensuring absolute seperation, but it is\\nwhere the bar is raised and something that I keep in mind as I develop.\"), mdx(\"p\", null, \"Cliff Meyers \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://cliffmeyers.com/blog/2013/4/21/code-organization-angularjs-javascript\"\n  }, \"has written a great\\narticle\"), \"\\non organizing your code in a large Angular app.\"), mdx(\"h2\", null, \"Directives are awesome and powerful\"), mdx(\"p\", null, \"I'm of the opinion now that Directives are the \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"killer feature\"), \" of AngularJS.\\nThey are wonderful little packages of contained UI/Presentation logic. They\\npresent so much flexibility and power with their ability to extend the grammar\\nof HTML. We definitely use directives, but perhaps not as much as we could.\"), mdx(\"p\", null, \"One of my favorite aspects of Angular Directives is that they are composable.\\nUsing them as HTML attributes, we are able to leverage directives to build\\ncomplex widgets with layered functionality. This can be a double-edge sword at\\ntimes, when the layered functionality wants to compete, but overall it is\\nawesome.\"), mdx(\"p\", null, \"If I was starting a project today, I would put some serious thought into\\norganizing Directives as visual components and behaviors. There are already\\nseveral projects that wrap popular UI frameworks with Angular Directives, but it\\nisn't strictly necessary to use a full-blown component set to approach it with\\nthis mentality. What are the primary components of the application? How can it\\nbe built around directives so that the primary components are shared throughout\\nthe application instead of cut-n-paste HTML and CSS sprinkled everywhere. How\\ncan I leverage these components for future work?\"), mdx(\"p\", null, \"If you haven't watched them yet, bounce on over to John Lindquist's\\n\", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://egghead.io\"\n  }, \"egghead.io\"), \" and check out the series on Directives. All of\\nthe videos are excellent, but the Directives information is enlightening.\"), mdx(\"h2\", null, \"Know thy framework\"), mdx(\"p\", null, \"Since I've started this project, I've definitely spent some time with the\\n\", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/angular/angular.js/tree/master/src\"\n  }, \"Angular internals\"), \". The source code is highly readable and well tested, so it is\\na \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"great read\"), \" if you are into clean/tight JavaScript.\"), mdx(\"p\", null, \"While I've spent some time with it, this is an area I'd like to get more\\nintimate with. Many things are still \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"black box\"), \" to me, and while I trust the\\nfolks building Angular, I still feel the need to understand what is occuring\\nwhen I build applications. This is one of my immediate goals right now, so\\nhopefully down the road I might have a thing or two to say about how Angular\\nworks uner the hood.\"), mdx(\"p\", null, \"As an aside, I feel compelled to do the same thing with\\n\", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/jquery/jquery/tree/master/src\"\n  }, \"jQuery\"), \". So much source,\\nso little time.\"), mdx(\"h2\", null, \"The Build\"), mdx(\"p\", null, \"Sadly, with this project we are required to use Maven and JAWR for our build. It\\nhas been a real struggle and we can't do \\\"proper\\\" builds. We've been able to\\nbuild some tools that help to mitigate, but I don't recommend using Maven for\\nyour front end code.\"), mdx(\"p\", null, \"If I was starting the project today, I would definitely use\\n\", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/yeoman/generator-angular\"\n  }, \"Yeoman\"), \" to easily generate\\ntemplates and make life easier.\"), mdx(\"h2\", null, \"The CSS\"), mdx(\"p\", null, \"This isn't related to Angular directly, but is another important aspect of your\\n\", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"AngularJS project\"), \" so I wanted to spend a little time on it.\"), mdx(\"p\", null, \"I will admit that a year ago my attitude was \\\"f css\\\". It confused and frustrated\\nme to the point of distaste. Obviously this stemmed from ignorance, and I've\\nspent the last year trying to play makeup with CSS. My attitude is no longer \\\"f\\ncss\\\" and sounds more like \\\"SCSS!\\\" because I found a happy place where CSS and I\\ncan get along.\"), mdx(\"p\", null, mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://sass-lang.com/\"\n  }, \"SCSS\"), \" syntax takes many of the pain points that put the\\nscrews to my brain with vanilla CSS and added a nice level of clarity. On top of\\nthat, Compass provides a pile of wicked mixins that eliminate an entirely new\\nlevel of pain from the stylesheet workflow.\"), mdx(\"p\", null, \"In the future I want to dig into SASS/Compass deeper, combining its expressive\\nstyling capabilities with the module and component level AngularJS work outlined\\nabove. I'd like to use a more organized approach to my stylesheets with\\nsomething like \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://smacss.com/\"\n  }, \"SMACSS\"), \" providing a baseline standard for how the styling is\\nimplemented and organized.\"), mdx(\"p\", null, \"At this point, CSS and I have fully made up. I've removed a lot of my ignorance,\\nwhich was obviously the key to building a solid relationship. We will see how it\\ngoes. One day at a time.\"), mdx(\"h2\", null, \"Conclusion\"), mdx(\"p\", null, \"If you are building a single-page web application, AngularJS is a solid choice.\\nIt is important to decide on and implement structure for your application early.\\nConsider up front how to organize your code into modules and components so that\\nyou can harness the power of Directives and maximize reusability potential.\"), mdx(\"p\", null, \"Some good comments on \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://news.ycombinator.com/item?id=5756911\"\n  }, \"Hacker\\nNews\"), \" if you'd like to join the\\ndiscussion.\"), mdx(\"p\", null, \"You might also enjoy: \", mdx(\"a\", {\n    href: \"https://joelhooks.com/blog/2013/07/15/a-look-at-angularjs-internal-directives-that-override-standard-html-tags/\"\n  }, mdx(\"strong\", null, \"AngularJS Directives That Override Standard HTML Tags\"))), mdx(\"p\", null, \"or maybe: \", mdx(\"a\", {\n    href: \"https://joelhooks.com/blog/2013/08/03/learn-angularjs-in-a-weekend/\"\n  }, mdx(\"strong\", null, \"Learn AngularJS this Weekend\"))));\n}\n;\nMDXContent.isMDXComponent = true;","frontmatter":{"title":"Lessons Learned: A Year with a Large AngularJS Project","date":"May 22, 2013","banner":null,"slug":null,"keywords":null}}},"pageContext":{"id":"64f13be9-1b51-56ea-aa1d-b6cea80074af","prev":{"id":"10eb0f2a-5127-5802-bc8e-a4796934db0b","parent":{"name":"2013-06-06-my-sketchnotes-and-thoughts-from-baconbizconf-2013","sourceInstanceName":"legacy"},"excerpt":"It is hard to explain how excited I was when Amy announced\n BaconBizConf  in April of 2013. A\nsmall conference devoted to like-minded people that either are, or want to be,\nbootstrapping product businesses. The speaker lineup included personal \"gurus…","fields":{"title":"My Sketchnotes and Thoughts from BaconBizConf 2013","slug":"blog/2013/06/06/my-sketchnotes-and-thoughts-from-baconbizconf-2013","date":"2013-06-06T00:00:00.000Z"}},"next":{"id":"38331ba3-a55e-5bf9-aa92-aa1db8f4edcc","parent":{"name":"2013-05-21-size-and-composition-of-effective-teams","sourceInstanceName":"legacy"},"excerpt":"The success or failure of  any  project is based on the team or teams working on\nit. Teams are like fingerprints and snowflakes. They are composed of individuals\nwith unique experiences and skillsets. When we set out to build large\napplications in a…","fields":{"title":"Size and Composition of Effective Software Teams","slug":"blog/2013/05/21/size-and-composition-of-effective-teams","date":"2013-05-21T00:00:00.000Z"}}}},
    "staticQueryHashes": ["1045846374"]}