{"id":19820,"date":"2013-01-10T08:34:14","date_gmt":"2013-01-10T15:34:14","guid":{"rendered":"http:\/\/css-tricks.com\/?p=19820"},"modified":"2013-01-12T09:35:39","modified_gmt":"2013-01-12T16:35:39","slug":"how-do-you-structure-javascript-the-module-pattern-edition","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/how-do-you-structure-javascript-the-module-pattern-edition\/","title":{"rendered":"How Do You Structure JavaScript? The Module Pattern Edition"},"content":{"rendered":"

JavaScript is interesting in that it enforces no particular structure upon you. “Bring Your Own Organization”, if you will. As I write more and more JavaScript in web app sites, this becomes more and more interesting. How you structure your JavaScript is very important because:<\/p>\n

    \n
  1. Done right, it makes code easier to understand for others and yourself re-visting your own code.<\/li>\n
  2. Having a decided-upon structure helps keep future code clean and encourages your declared best practices.<\/li>\n
  3. It makes your code testable.<\/li>\n<\/ol>\n

    Before I go any further, let it be known that I am far from a master of JavaScript. There are a lot of smart folks in the JavaScript world that have been doing and talking about this for longer than I knew what a div was.<\/p>\n

    This has been a topic in my mind lately because I’ve been writing a lot more JavaScript for CodePen<\/a>, which is very JavaScript heavy. We’ve been using the “Module Pattern” since the beginning and it’s been serving us quite well I think. <\/p>\n

    Then I posted this article about the making of the Treehouse ad<\/a>, and within it I also used the Module Pattern for the JavaScript there. Louis Lazaris chimed in that this is how he’s been liking to write JavaScript lately too, and started a bit of a discussion<\/a>. Louis followed it up with an article<\/a> explaining his preferred structural pattern.<\/p>\n

    The Concept<\/h3>\n

    It’s easier to understand concepts like this if there is an example to build from. Let’s say we’re building a news widget. It lists some news articles, and has a button in which you can load more news articles.<\/p>\n

    The Module<\/h3>\n

    Humble beginnings:<\/p>\n

    var NewsWidget = {\r\n\r\n};<\/code><\/pre>\n

    Just an object. I like my JavaScript variables starting with a lowercase character, but Modules get an uppercase first character. Just a convention that helps code readability.<\/p>\n

    Settings<\/h3>\n

    The news widget will likely have some significant numbers associated with it (e.g. how many articles in it). Also, some significant elements (DOM nodes) that will need to be accessed regularly.<\/p>\n

    There will be a number of sub-functions of this module that do small specific things. Many of those may need access to these settings and “cached” elements. So, we’ll make the settings available to each of them.<\/p>\n

    var s,\r\nNewsWidget = {\r\n\r\n  settings: {\r\n    numArticles: 5,\r\n    articleList: $(\"#article-list\")\r\n  }\r\n\r\n};<\/code><\/pre>\n

    We’ll get to the sub-function access in a second.<\/p>\n

    Init Function<\/h3>\n

    To “kick things off” we’ll have just one<\/strong> function be called. This will be consistent across all modules, so you know exactly where to look when you start reading the code and figuring out what happens when.<\/p>\n

    var s,\r\nNewsWidget = {\r\n\r\n  settings: {\r\n    numArticles: 5,\r\n    articleList: $(\"#article-list\"),\r\n    moreButton: $(\"#more-button\")\r\n  },\r\n\r\n  init: function() {\r\n    \/\/ kick things off\r\n    s = this.settings;\r\n  }\r\n\r\n};<\/code><\/pre>\n

    The first thing the init<\/code> function will do is set the variable s<\/code> (which we declared at the same level as the Module) to be a pointer to the settings. Because of where s<\/code> was declared, this means all sub-functions of the Module will have access to the settings. Nice.<\/p>\n

    Binding UI Actions<\/h3>\n

    Alex Vasquez set up a convention for us at CodePen where we would have a function just for binding the UI events. You never write any code that “does stuff” when you bind, you just do the binding and then call another appropriately named sub-function.<\/p>\n

    var s,\r\nNewsWidget = {\r\n\r\n  settings: {\r\n    numArticles: 5,\r\n    articleList: $(\"#article-list\"),\r\n    moreButton: $(\"#more-button\")\r\n  },\r\n\r\n  init: function() {\r\n    s = this.settings;\r\n    this.bindUIActions();\r\n  },\r\n\r\n  bindUIActions: function() {\r\n    s.moreButton.on(\"click\", function() {\r\n      NewsWidget.getMoreArticles(s.numArticles);\r\n    });\r\n  },\r\n\r\n  getMoreArticles: function(numToGet) {\r\n    \/\/ $.ajax or something\r\n    \/\/ using numToGet as param\r\n  }\r\n\r\n};<\/code><\/pre>\n

    Combining Files<\/h3>\n

    Chances are the news widget isn’t the only JavaScript you’ll have on a page. There will be lots of Modules you’ll need to load. Perhaps the news widget is on every page of your site, so belongs in a global.js file. This global.js file will ultimately be a a bunch of Modules concatenated, and then a big kick off party.<\/p>\n

    There are all kinds of ways to handle this concatenation stuff. It could be a dev tool like CodeKit and it’s ability to do appends\/prepends<\/a>. It could be some fancy Grunt.js<\/a> build script thing. <\/p>\n

    At CodePen we use Ruby on Rails and it’s asset pipeline<\/a>. So for us, the global.js file would be something like:<\/p>\n

    \/\/= require common\/library.js\r\n\r\n\/\/= require module\/news-widget.js\r\n\/\/= require module\/some-other-widget.js\r\n\r\n(function() {\r\n\r\n  NewsWidget.init();\r\n\r\n  SomeOtherModule.init();\r\n\r\n})();<\/code><\/pre>\n

    That’s All Folks<\/h3>\n

    Pretty darn satisfying way to write JavaScript, I think. It satisfies the three points I made about the importance of structure. <\/p>\n

    Regarding the testing point, I know that wasn’t discussed much, but I’m sure you can imagine how having smaller specific functions in change of specific tasks are easier to write assertions for. That’s how most JavaScript testing is done (e.g. Jasmine<\/a>). For instance, in some form of code or another: “I assert that when this function gets this value this other thing happens and is equal to some other value.”<\/p>\n

    This is the tip of the iceberg. I’ve only just started it, but Learning JavaScript Design Patterns<\/a> (free to read online!) by Addy Osmani looks to be going a lot deeper down this rabbit hole. <\/p>\n","protected":false},"excerpt":{"rendered":"

    JavaScript is interesting in that it enforces no particular structure upon you. “Bring Your Own Organization”, if you will. As I write more and more JavaScript in web app sites, this becomes more and more interesting.<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"sig_custom_text":"","sig_image_type":"featured-image","sig_custom_image":0,"sig_is_disabled":false,"inline_featured_image":false,"c2c_always_allow_admin_comments":false,"footnotes":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":[]},"categories":[4],"tags":[],"jetpack_publicize_connections":[],"acf":[],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":302876,"url":"https:\/\/css-tricks.com\/why-javascript-is-eating-html\/","url_meta":{"origin":19820,"position":0},"title":"Why JavaScript is Eating HTML","date":"February 13, 2020","format":false,"excerpt":"Web development is always changing. One trend in particular has become very popular lately, and it fundamentally goes against the conventional wisdom about how a web page should be made. It is exciting for some but frustrating for others, and the reasons for both are difficult to explain. A web\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2019\/02\/js-pattern.png?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":358496,"url":"https:\/\/css-tricks.com\/the-invisible-javascript-backdoor\/","url_meta":{"origin":19820,"position":1},"title":"The Invisible JavaScript Backdoor","date":"December 8, 2021","format":false,"excerpt":"An interesting (scary) trick of an nearly undetectable exploit. Wolfgang Ettlinger: What if a backdoor\u00a0literally\u00a0cannot be\u00a0seen\u00a0and thus evades detection even from\u00a0thorough\u00a0code reviews? I'll post the screenshot of the exploit from the post with the actual exploit circled: If you were really looking super closely you'd probably see that, but I\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2021\/12\/hangul_filler_backdoor-1.png?fit=844%2C683&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":344316,"url":"https:\/\/css-tricks.com\/links-on-react-and-javascript\/","url_meta":{"origin":19820,"position":2},"title":"Links on React and JavaScript","date":"July 13, 2021","format":false,"excerpt":"As a day-job, React-using person, I like to stay abreast of interesting React news. As such, I save a healthy amount of links. Allow me to dump out my latest pile. Most of this is about React but not all of it. The Plan for React 18 \u2014 A bunch\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2018\/04\/react.jpg?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":366468,"url":"https:\/\/css-tricks.com\/web-development-books-you-can-get-for-free\/","url_meta":{"origin":19820,"position":3},"title":"Great (and Free!) Web Development Books You Can Get Online","date":"June 27, 2022","format":false,"excerpt":"Right after \"Where is the best place to learn?\" perhaps the most commonly asked question I hear from folks getting into code is \"What web development books should I get to learn?\" Well, consider this an answer to that question as I've curated a list of books that are not\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2022\/06\/books-code.png?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":325341,"url":"https:\/\/css-tricks.com\/javascript-operator-lookup\/","url_meta":{"origin":19820,"position":4},"title":"JavaScript Operator Lookup","date":"November 9, 2020","format":false,"excerpt":"Okay, this is extremely neat: Josh Comeau made this great site called Operator Lookup that explains how JavaScript operators work. There are some code examples to explain what they do as well, which is pretty handy. My favorite bit of UI design here are the tags at the bottom of\u2026","rel":"","context":"In "Link"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2020\/11\/js-operators.png?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":344024,"url":"https:\/\/css-tricks.com\/beginner-javascript-notes\/","url_meta":{"origin":19820,"position":5},"title":"Beginner JavaScript Notes","date":"July 8, 2021","format":false,"excerpt":"Wes has a heck of a set of \"notes\" for learning JavaScript. It's organized like a curriculum, meaning if you teach JavaScript, you could do a lot worse. It's actually more like 85 really fleshed-out blog posts organized into sections and easily navigable. If you want to be walked through\u2026","rel":"","context":"In "Link"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2021\/07\/Screen-Shot-2021-07-05-at-11.56.04-AM.png?fit=1200%2C603&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]}],"featured_media_src_url":null,"_links":{"self":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/19820"}],"collection":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/comments?post=19820"}],"version-history":[{"count":7,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/19820\/revisions"}],"predecessor-version":[{"id":19831,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/19820\/revisions\/19831"}],"wp:attachment":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/media?parent=19820"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/categories?post=19820"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/tags?post=19820"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}