Modular JS
liuyicheng@meituan.com
Modular
When we say an application is modular, we generally mean it's composed of a set of highly decoupled, distinct pieces of functionality stored in modules.
当我们说一个程序是模块化的,通常我们指它是由一组存放在模块中的高度解耦的独立功能片段所组成。
http://addyosmani.com/writing-modular-js/
http://www.tuicool.com/articles/UZnq6j
优缺点
可维护性
- 方便组合,分解
- 方便单个模块调试,升级
- 多人协作,互不干扰
可测试性
- 单元测试
性能损耗
发展
内容样式交互混用
⬇︎
分离成独立文件
⬇︎
动态加载
⬇︎
模块化
⬇︎
服务器端 - CommonJS
浏览器端 - AMD
CommonJS
The official JavaScript specification defines APIs for some objects that are useful for building browser-based applications. However, the spec does not define a standard library that is useful for building a broader range of applications.
http://www.commonjs.org/
http://arstechnica.com/business/2009/12/commonjs-effort-sets-javascript-on-path-for-world-domination/
The CommonJS API will fill that gap by defining APIs that handle many common application needs, ultimately providing a standard library as rich as those of Python, Ruby and Java.
With CommonJS-compliant systems, you can use JavaScript to write:
-
Server-side JavaScript applications
-
Command line tools
-
Desktop GUI-based applications
-
Hybrid applications (Titanium, Adobe AIR)
CommonJS Standards
-
Modules
-
Binary strings and buffers
-
Charset encodings
-
Binary, buffered, and textual input and output (io) streams
-
System process arguments, environment, and streams
-
File system interface
-
Socket streams
-
Unit test assertions, running, and reporting
-
Web server gateway interface, JSGI
-
Local and remote packages and package management
CommonJS Implementations
CouchDB ( npm )
RequireJS
RingoJS
SeaJS
curl.js
node.js
when.js
http://www.commonjs.org/impl/
Modules/1.1
Modules/1.1
Sample Code
// math.js
exports.add = function() {
var sum = 0, i = 0, args = arguments, l = args.length;
while (i < l) {
sum += args[i++];
}
return sum;
};
// increment.js
var add = require('math').add;
exports.increment = function(val) {
return add(val, 1);
};
// program.js
var inc = require('increment').increment;
var a = 1;
inc(a); // 2
module.id == "program";
Node.js
Implementations
Modules/1.0 (yes)
Unit Testing/1.0 (yes)
Node.js
AMD
Asynchronous Module Definition
The Asynchronous Module Definition (AMD) API specifies a mechanism for defining modules such that the module and its dependencies can be asynchronously loaded. This is particularly well suited for the browser environment where synchronous loading of modules incurs performance, usability, debugging, and cross-domain access problems.
It is unrelated to the technology company AMD and the processors it makes.
https://github.com/amdjs/amdjs-api
AMD api
define
require
Loader Plugins
Common Config
define
Sets up the module with ID of "alpha", that uses require, exports and the module with ID of "beta":
define("alpha", ["require", "exports", "beta"], function (require, exports, beta) {
exports.verb = function() {
return beta.verb();
//Or:
return require("beta").verb();
}
});
An anonymous module that returns an object literal:
define(["alpha"], function (alpha) {
return {
verb: function(){
return alpha.verb() + 2;
}
};
});
require
define(['require'], function (require) {
//the require in here is a local require.
});
define(function (require, exports, module) {
//the require in here is a local require.
});
define(function (require) {
var a = require('a');
});
define(function (require) {
require(['a', 'b'], function (a, b) {
//modules a and b are now available for use.
});
});
Loader Plugins
define(['text!../templates/start.html'], function (template) {
//do something with the template text string.
});
Common Config
{
baseUrl: './foo/bar'
}
{
shim: {
'some/thing': {
deps: ['a', 'b'],
exports: 'some.thing',
init: function (a, b) {
return some.thing + 'another';
}
}
}
}
{
paths: {
"some": "some/v1.0"
}
}
AMD Implementations
RequireJS
curlJS
Dojo Loader
YUI Modules
Sandbox
+
Namspace
add
// name.js
YUI.add('name', function(Y) {
Y.namespace('mt').name = 'lyc';
});
use
// index.js
YUI({
modules: {
'name': './name.js'
}
}).use('name', function(Y) {
Y.log(Y.mt.name);
});
Namespace Are Old School
http://blog.millermedeiros.com/namespaces-are-old-school/
ES6 Modules is comming
ES6 Modules
ES6实现了模块功能,试图解决JavaScript代码的依赖和部署上的问题,取代现有的CommonJS和AMD规范,成为浏览器和服务器通用的模块解决方案。
http://es6.ruanyifeng.com/#docs/class
export & import
// profile.js
export var firstName = 'David';
export var lastName = 'Belle';
export var year = 1973;
import {firstName, lastName, year} from './profile';
function setHeader(element) {
element.textContent = firstName + ' ' + lastName;
}