JavaScript modules – Working with big JavaScript projects – Standards



JavaScript modules – Working with big JavaScript projects – Standards

0 0


javascript-modules

Presentation about modules in JavaScript

On Github kwiniarski / javascript-modules

JavaScript modules

Working with big JavaScript projects

by Krzysztof Winiarski

Big project, big problems

  • hard to read
  • hard to test
  • hard to maintain
hard to read Code is for humans, for machines only to execute. Style guide will help others to read. hard to maintain Code duplication, no portability, global namespace pollution... hard to test as a consequence all above...

Any suggestions how to improve?

  • Standards
  • Modules
  • Automation
Modules as one of many good programing practices.
Part I

Standards

Improving maintainability with style guidelines

Do we need standards?

Principles of maintainability

Maintainable code is:

  • readable
  • consistent
  • predictable
  • documented
  • testable

Readable code

  • coding conventions
    • indention levels
    • statement termination
    • line length
    • line braking
    • blank lines
    • curly braces
  • naming conventions
    • variablesAndFunctions
    • CONSTANTS
    • Constructors
    • _otherConventions
    • $jQueryCollection

Consistent code

When you establish coding and naming conventionsstick to them!

Ideally code should look as if it was written by the same person.

Predictable code

Avoid complexity and stick to the programing principles

KISS, DRY, YAGNI, loose coupling, separation of concerns, open/closed, single responsibility, IoC

In JavaScript you have to think asynchronous

so it will be better if you are familiar with events, callbacks & promises

Some of those principles come together, creating design patterns, like for example SOLID:
  • SRP - Single Responsibility Principle, module/class should be responsible for one thing
  • OCP - open/close principle, module interface should be open to extension but closed to modification
  • LSP - Liskov Substitution Principle, any module should be substitutable by modules builded upon original one
  • ISP - Interface Segregation Principle, many client-specific interfaces are better then one general
  • DIP - Dependency Inversion Principle

Documented code

Why I see you are all embraced?

One of the most important habits, yet hardest to follow.

Testable code

Embraced again?

TDD, BDD... No mater how you name it. What is important you will always write code you only need. Unit test will also warn anyone who will try to brake your implementation.

Part II

Modules

Improving maintainability with modules

Principles of modularity

  • specialized
  • independent
  • decomposable
  • recomposable
  • substitutable
In computing and systems design a loosely coupled system is one in which each of its components has, or makes use of, little or no knowledge of the definitions of other separate components.Specialized The module’s parts should be integral to solving the single problem that the module exists to solve. The public API should be simple and clean.Independent Modules should know as little as possible about other modules. Instead of calling other modules directly, they should communicate through mediators.Decomposable It should be fairly simple to test and use modules in isolation from other modules. Recomposable It should be possible to fit various modules together in different ways to build a different version of the same software or an entirely different application.Substitutable It should be possible to completely substitute one module with another, as long is it supplies the same interface. The rest of the application should not be adversely impacted by the change.The Open Closed Principle states that a module interface should be open to extension but closed to modification.

No out of the box solution yet

but we can do this:

  • Object literal notation
  • Module pattern
  • CommonJS modules
  • AMD modules
There are no build in JS solutions we can use. However there are few design patterns which will help to maintain project.

Object literal notation

In JavaScript functions are first-class citizens and we can make strong use of it.

What is it, does anybody know? First-class citizen is an entity which supports all the operations generally available to other entities. These operations typically include being passed as a parameter, returned from a function, and assigned to a variable.

Example

var myCart = {

  totalAmount: 0,

  items: [],

  placeholder: document.getElementById('#cart'),

  addItem: function (item) {
    this.items.push(item);
    this.totalAmount += item.price;
  }

};

Pros

  • Simple implementation
  • Relatively easy to create instances with Object.create

Cons

  • No encapsulation, easy to overwrite property
  • Variables may leak

Module pattern

Lets add closure concept to the object notation.

Example

var myCart = function () {

  var totalAmount = 0,
      items = [],
      placeholder = document.getElementById('#cart');

  return {
    addItem: function (item) {
      items.push(item);
      totalAmount += item.price;
    },
    total: function () {
      return totalAmount;
    }
  };

};

But what about dependencies?

Inject dependencies

var myCart = (function ($) {

  return function cart() {

    var totalAmount = 0,
        items = [],
        placeholder = $('#cart');

    return {
      addItem: function (item) {
        items.push(item);
        totalAmount += item.price;
      },
      total: function () {
        return totalAmount;
      }
    };

  };

})(jQuery);

How about automatic dependency resolution?

Impossible without additional tools.

Pros

  • Clean and flexible model
  • Relatively easy to create instances
  • Encapsulation
  • Dependency injection
This model is very flexible and can be used to build singletons, observers, etc.

Cons

  • Methods added later cannot access privates
  • Hard to test private parts of module
  • No automatic dependency resolution

So what with this automatic dependency resolution?

CommonJS modules

Modules/1.0

CommonJS implementations

  • Node.js
  • CouchDB
  • RingoJS
  • many more...

Example

var $ = require('jquery');

module.exports = function cart() {

  var totalAmount = 0,
      items = [],
      placeholder = $('#cart');

  var prototype = {
    addItem: function (item) {
      items.push(item);
      totalAmount += item.price;
    },
    total: function () {
      return totalAmount;
    }
  };

  return Object.create(prototype);  

};

What about browser?

AMD modules

Modules/AsynchronousDefinition

Not a CommonJS project anymore

AMD API

  • define(id?, dependencies?, factory);
  • define.amd
  • require(dependencies, callback);

AMD libraries

Example

module.js
define('myCart', ['jQuery'], function ($) {

  return function cart() {

    var totalAmount = 0,
        items = [],
        placeholder = $('#cart');

    var prototype = {
      addItem: function (item) {
        items.push(item);
        totalAmount += item.price;
      },
      total: function () {
        return totalAmount;
      }
    };

    return Object.create(prototype);  

  };

});
app.js
require(['myCart'], function (myCart) {
 
  var cart = myCart();
  cart.addItem({price: 5});
  
});

Compatibility

AMD + CommonJS

UMD

Universal Module Definition

Example

(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    define([], factory);
  } else if (typeof exports !== 'undefined') {
    module.exports = factory();
  }
})(this, function () {
  return function cart () {
    // module body
  };
});

This will work in Node.js and in the browser(with RequireJS for example).

Feature

ECMAScript modules

  • Will be implemented in ECMAScript 6 Harmony(aka. JavaScript.next or ES.next)
  • Don't confuse with class - ES.next will have it too
  • Still working draft...

Example

module.js
module Cart {
  import something from otherModule 

  var internalData;
  
  function internalFunction() {}
 
  export function addItem(item) {}
  export function total() {}
}
app.js
import {addItem, total} from Cart;

addItem({ptice: 5});

Use Test it today

Controversy

Proposed solution is not compatible with currently adopted solutions like CommonJS or AMD.

Managing modules

  • npm - Node Packaged Modules
  • Bower - A package manager for the web
Part III

Automation

Improve maintainability with automation

Why?

  • Save you time
  • Focus on your code
  • Clean workflow
Clean workflow - any other developer can easily join without any need to learn how to build and test your code

What?

  • Building deployment packages
  • Code analysis (code lint)
  • Unit tests and code coverage
  • Documentation update

When?

  • development
  • deployment

Building deployment packages

Summary

  • Learn and spreed programing principles
  • Switch on asynchronous thinking
  • Know tools and solutions JavaScript has to offer
  • Write modules, use package manager
  • Automate what you can

Any questions?

The End

Thank you for your attention!

Bibliography

Learning JavaScript Design Patterns by Addy Osmani A Few New Things Coming To JavaScript by Addy Osmani JavaScript Module Pattern: In-Depth by Ben Cherry Maintainable JavaScript by Nicholas C. Zakas Programming JavaScript Applications by Eric Elliott JavaScript Patterns by Stoyan Stefanov