23
Modules in JavaScript Or How to Break Your Code (Into Little Pieces) A Talk by Michael Cordingley

Organizing JavaScript

Embed Size (px)

DESCRIPTION

Organizing JavaScript into modules, both file-based and logical.

Citation preview

Page 1: Organizing JavaScript

Modules in JavaScriptOr How to Break Your Code

(Into Little Pieces)

A Talk by Michael Cordingley

Page 2: Organizing JavaScript

Module Types

● Modules are sometimes misunderstood

– Confusion in naming● They come in different

flavors

– File

– Logical● In an ideal world, the two

overlap 1:1

● File Modules

– Each piece of code to its own file

● Logical Modules

– Each piece of code to its own predictable code location

Page 3: Organizing JavaScript

The Cost of Structure

● Three different difficulty levels

– Different trade-offs of fixed versus variable costs

Complexity vs. Scale

Simple Moderate Complex

Project Scale

Pro

ject

Co

mp

lexi

ty

Page 4: Organizing JavaScript

File Modules

● Break your code out into separate files

– Ideally, one file per idea● Files should be small and logically arranged on the file-

system

● Don't forget about production!

– Files need to be concatenated and minified as part of your build process.

Page 5: Organizing JavaScript

File Modules – Simple

● If a project uses very little JavaScript, throw it it all into a single file for each page.

● Didn't you just say one idea per file?

– I lied.● It's more maintainable to have everything in one place, if that

place isn't too cluttered.

– We only need organization schemes when we have too much.

● When starting a new project, START WITH THIS ONE unless you have good reason to do otherwise!

Page 6: Organizing JavaScript

File Modules – Moderate

● Break code out into separate files and load them each with a script tag.

– Don't forget to bundle these into a single file that gets loaded as a giant blob for production

● Doesn't this get hard to keep up with all of the dependencies?

– Only if you have several files

– Most projects never reach that scale

Page 7: Organizing JavaScript

Transitioning to Moderation

● It isn't a clean break

● Just start pulling your nouns out into separate files as your project acquires them

– These are probably reusable across pages anyway

– Pulling them out also encourages you to write a clean interface

● If you page script exceeds 200 lines, you probably have lurking nouns, or at least some code that could be DRYed out.

– Please don't wait this long!

Page 8: Organizing JavaScript

File Modules – Complex

● So you went for the moderate route and now you're drowning in files?

– Time to level up.● Pull in a formalized way to load and compile files

– require.js

– yepnope.js

– etc.

Page 9: Organizing JavaScript

Caveat Emptor

● Things like require.js are geared more for single-page apps than for multi-page apps

– Most of your projects are probably multi-page apps

– You're probably only drowning in JS files if you have a single-page app

– require.js becomes painful very quickly if you want to use it on a multi-page app

Page 10: Organizing JavaScript

Transitioning to Complexity

● Update your file module to conform to your module-loader of choice

● Update every usage of that module to be loaded with the module-loader

● Don't forget the whole concatenation/minification thing

– This is where the pain ramps up

– You need to define blobs● Separate bundlings of code that load together

Page 11: Organizing JavaScript

File Modules in the Future

● ECMAScript 6 (Harmony) will bring native modules to the language

– Shim: https://github.com/ModuleLoader/es6-module-loader

– Despite the shim, this is not yet ready for general consumption

● The spec isn't finished yet

Page 12: Organizing JavaScript

Logical Modules

● Where do your objects, functions, and variables all live?

– Hint: Not in the global namespace.

– I'm not lying this time!

Page 13: Organizing JavaScript

Logical Modules – Simple

● Just keep 'em in your page script

– If you haven't broken it out into its own file anyway, it probably isn't very big or very complicated

● Pull it out into a logical module at the same time that you'd pull it out into a file module and for the same reasons

Page 14: Organizing JavaScript

Logical Modules – Moderate

● OK, so it's out into its own file

– Don't make it a global!● Projects get cluttered this way

– It needs a home that is globally-accessible● It may be an object that you reuse across pages● It may be repeated functionality

– Like enhancing your site navigation

Page 15: Organizing JavaScript

Introducing the Application Object

● Make a global

– But only one!

– For now, it's just an object literal● Call it “App” or the name of your project: “FooBarFighters”

– No, I'm not actually familiar with their music

– Yes, the puns are always intentional, even when bad

Page 16: Organizing JavaScript

Application Object – Continued

● Attach your modules to this object

– e.g. App.Navigation, App.Forms, App.InstantiableObject

– Submodules go as properties on their parent modules● If your module needs initialization, add an “init” or

“initialize” method to it.

– e.g. App.Navigation.initialize();

– This is responsible for calling submodule intializers● If you have modules that need initialization, also have an

“App.initialize();” method that gets called on DOM ready

Page 17: Organizing JavaScript

Application Object – Finish

● This application object can and should be broken out across multiple files.

– The “App.initialize()” method saves you from having to worry about the order in which they load

● The Application object just comes first● Don't forget about “this”

– Useful to avoid having to bake the full module name into functions that use other functions

– e.g. Inside of “App.Navigation.initialize()” “this” is “App.Navigation”

Page 18: Organizing JavaScript

The Catch

● “This is great! Everything is cleanly separated out into its own place, but I need to load a module after the page load and then initialize it.”

– OK.● “Oh yeah, and I don't know if it'll have loaded before the

Application starts or not.”

– Um, K.● “And this other piece needs to run only (before|after) the rest

is all set up.”

– …why are you doing this to me?

Page 19: Organizing JavaScript

Logical Modules – Complex

● Introducing the Application object!

– But this time, it's a real, instantiated object● “var App = new Application();”

– You could write the definition of “Application” yourself, but it's best not to

– We'll get to that

Page 20: Organizing JavaScript

The New Application Object

● When a new module gets loaded after the application has started, this will automatically start it.

– Otherwise, it'll wait until the application starts● It also publishes events

– So you can run code just before and just after the application starts

– It even doubles as a free event bus● The modules also get events

– Same deal as the Application

Page 21: Organizing JavaScript

And where do I get this?

● What, you don't want to reinvent the wheel?

– Fine, here it is: https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.application.md

● “But, I don't use or want Underscore, Backbone, and the whole rest of Marionette!”

– Jeez, you're picky.

– https://github.com/mcordingley/Appliance

Page 22: Organizing JavaScript

The End Goal

● Reduce complexity

– Whenever you introduce a new organizational tool, make sure it reduces project complexity

– Use the simplest scheme you can get away with

– Make things as easy as possible for anyone who has to maintain your code after you've left it behind

Page 23: Organizing JavaScript

Thank You

● This talk can be found in article format at:

– http://michaelcordingley.me/articles/when-spaghetti-overflows-your-plate