diff --git a/content/maintainability1.html b/content/maintainability1.html index 7d7da3a..8e11357 100644 --- a/content/maintainability1.html +++ b/content/maintainability1.html @@ -135,7 +135,7 @@

Do not expose implementation details

})(); -

A common pattern for classes (e.g. objects instantiated from a prototype) is to simply mark class methods as private by starting them with a underscore. You can properly hide class methods by using .call/.apply to set "this", but I won't show it here; it's a minor detail.

+

A common pattern for classes (e.g. objects instantiated from a prototype) is to simply mark class methods as private by starting them with an underscore. You can properly hide class methods by using .call/.apply to set "this", but I won't show it here; it's a minor detail.

Do not mix definition and instantiation/initialization

@@ -154,7 +154,7 @@

Do not mix definition and instantiation/initialization

module.exports = FooObserver; -

While this is a proper module (I'm excluding the wrapper here), it mixes initialization with definition. What you should do instead is have two parts, one responsible for definition, and the other performing the initialization for this particular use case. E.g. foo_observer.js

+

While this is a proper module (I'm excluding the wrapper here), it mixes initialization with definition. What you should do instead is have two parts: one responsible for definition, and the other performing the initialization for this particular use case. E.g. foo_observer.js

 function FooObserver() {
@@ -326,7 +326,7 @@ 

Building an application out of packages

Using the glue build system

-

So, now we have a somewhat detailed spec for how we'd like to build. Node has native support for require(), but what about the browser? We probably need a elaborate library for this?

+

So, now we have a somewhat detailed spec for how we'd like to build. Node has native support for require(), but what about the browser? We probably need an elaborate library for this?

Nope. This isn't hard: the build system itself is about a hundred fifty lines of code plus another ninety or so for the require() implementation. When I say build, I mean something that is super-lightweight: wrapping code into closures, and providing a local, in-browser require() implementation. I'm not going to put the code here since it adds little to the discussion, but have a look.

@@ -368,7 +368,7 @@

Including files and building a package

Binding to global functions

-

We often want to bind a particular name, like require('jquery') to a external library. You can do this with replace(moduleName, string).

+

We often want to bind a particular name, like require('jquery') to an external library. You can do this with replace(moduleName, string).

Here is an example call that builds a package in response to a HTTP GET:

diff --git a/content/maintainability2.html b/content/maintainability2.html index c1a496a..cf22ced 100644 --- a/content/maintainability2.html +++ b/content/maintainability2.html @@ -48,13 +48,13 @@

Refactoring an existing module

4. Delay concrete instatiation as long as possible by extracting module state setup into a single bootstrap file/function. Defining a module should be separate from running the module. This allows small parts of the system to be tested independently since you can now require your module without running it.

-

For example, where you previously used to define a class and then immediately assign a instance of that class onto a global variable/namespace in the same file; you should move the instantatiation to a separate bootstrap file/function.

+

For example, where you previously used to define a class and then immediately assign an instance of that class onto a global variable/namespace in the same file; you should move the instantatiation to a separate bootstrap file/function.

5. If you have submodules (e.g. chat uses backend_service), do not directly expose them to the layer above. Initializing the submodule should be the task of the layer directly above it (and not two layers above it). Configuration can go from a top level initialize() function to initialize() functions in submodules, but keep the submodules of modules out of reach from higher layers.

6. Try to minimize your external surface area.

-

7. Write package-local tests. Each package should be have unit and integration tests which can be run independently of other packages (other than 3rd party libraries and the common package).

+

7. Write package-local tests. Each package should have unit and integration tests which can be run independently of other packages (other than 3rd party libraries and the common package).

8. Start using npm with semantic versioning for distributing dependencies. Npm makes it easy to distribute and use small modules of Javascript.

@@ -75,7 +75,7 @@

Guidelines for new projects

Tooling: npm

-

Finally, let's talk about distribution. As your projects grow in scope and in modularity, you'll want to be able to load packages from different repositories easily. npm is an awesome tool for creating and distributing small JS modules. If you haven't used it before, Google for a tutorial or read the docs, or check out Nodejitsu's npm cheatsheet. Creating a npm package is simply a matter of following the CommonJS conventions and adding a bit of metadata via a package.json file. Here is an example package.json

+

Finally, let's talk about distribution. As your projects grow in scope and in modularity, you'll want to be able to load packages from different repositories easily. npm is an awesome tool for creating and distributing small JS modules. If you haven't used it before, Google for a tutorial or read the docs, or check out Nodejitsu's npm cheatsheet. Creating an npm package is simply a matter of following the CommonJS conventions and adding a bit of metadata via a package.json file. Here is an example package.json

 { "name": "modulename",