模块化开发
开发环境前置软件
Node.js
Node.js是前端打包压缩工具流的运行环境,同时提供了npm工具可以快捷地安装其它以Node.js为基础的软件。windows下有时候会发生安装后在CMD中无法运行node的情况,需要设置一下PATH变量。
grunt/gulp
前端基础代码v1是采用CMD模块化开发,允许使用grunt或者gulp打包,同时雪碧图自动生成脚本也是采用gulp打包,建议至少安装gulp。
npm install -g gulp
webpack
前端基础代码v2采用的是Node.js的模块化开发方式,使用了webpack的各种loader,需要使用版本至少是v2.1.0-beta.12以上版本。
compass
前端基础代码v1的雪碧图自动编译工具采用的是compass。
python
CSS预编译工具采用了sass,sass预编译器基本上都需要依赖python,注意安装时也需要配置PATH变量
AMD规范
AMD规范定义了模块的基本定义方式,每个模块对应一个js文件,并且它的内容应该是这种形式:
require(id?, dependencies?, factory);
id 可选,表示模块的路径,也是模块的唯一标识 dependencies 可选,一个数组,表示模块依赖的其它模块 factory 必选,允许是对象或者函数,dependencies参数里定义的外部模块将会以参数的形式传给factory由于JavaScript是预编译语言,无法方便地从语言层面自动解析模块之间的依赖,使用AMD规范的项目需要预先加载支持AMD规范的加载器,一般使用的是require.js。
require.js定义了一个全局对象require,允许配置各种参数以及定义入口文件:
<script type="text/javascript" src="./js/require.min.js"></script> <script type="text/javascript"> require.config({ baseUrl: "./js/src", urlArgs: "__ts=" + new Date().getTime() }); require(["pages/index"], function(page) { console.log(page); }); </script>
CMD规范
CMD规范跟AMD规范非常接近,二者的加载器基本上也互相兼容,CMD的定义方式如下:
define(factory);
跟AMD规范最大的不同是在define函数的调用时并不指定该模块依赖哪些外部模块,同时factory也不会接收依赖模块对象参数,它拥有三个固定的参数:
require 函数,用于引入依赖的模块,可以使用以下方法导入模块 var mod1 = require(“./mod1”); exports导出对象,如果factory没有返回值将以它为导出对象。导出对象即为该模块被其它模块依赖时提供给其它模块的对象,所有的API都作为该对象的成员方法。 module 本模块的各种信息,比如id等等
CMD规范一般采用sea.js作为加载器,但事实上require.js同样兼容此规范。
注:前端开发架构1.0即是以require.js作为加载器,CMD规范作为代码规范。
CommonJS规范
AMD规范与CMD规范希望自己被使用于浏览器中的Web环境,它们拥有开发模式以及生产模式。在开发时通过加载器异步加载入口文件,并且分析依赖关系异步加载所有依赖的其它模块。
CommonJS规范更专注于服务器端或者本地应用环境,它并不关心开发模式以及生产模式,现今Node.js的模块定义即采用了CommonJS规范,它是通过node命令来自动同步分析依赖关系并且执行。CommonJS规范同样可以被应用到Web环境,但由于它并不要求加载器,在使用时必须编译成目标代码才能够正常执行,最出名的预编译器即是现今很流行的webpack。
跟AMD与CMD不同,CommonJS规范由于在使用时必须通过预编译,它不需要使用define函数定义模块,而是每个文件自然成为一个模块,同时拥有以下变量或者函数:
require
函数,用于导入一个模块,在webpack中经过预编译它会被转换成webpack内部函数名,不是真正意义上的javascript函数。
module
模块的附加信息,比如id。
module.exports
模块的导出对象,模块本身被依赖它的文件引入时会得到一个对象,该对象即是module.exports,模块的API都需要作为它的方法对外提供,简单来说它就是模块的值。
UMD规范
CommonJs和AMD风格一样流行,似乎缺少一个统一的规范。所以人们产生了这样的需求,希望有支持两种风格的“通用”模式,于是通用模块规范(UMD)诞生了。
它兼容了AMD和CommonJS,同时还支持老式的“全局”变量规范
(function (root, factory) { if (typeof define === 'function' && define.amd) { // AMD define(['jquery'], factory); } else if (typeof exports === 'object') { // Node, CommonJS之类的 module.exports = factory(require('jquery')); } else { // 浏览器全局变量(root 即 window) root.returnExports = factory(root.jQuery); } }(this, function ($) { // 方法 function myFunc(){}; // 暴露公共方法 return myFunc; }));
(function (root, factory) { if (typeof define === 'function' && define.amd) { // AMD define(['jquery'], factory); } else if (typeof exports === 'object') { // Node, CommonJS之类的 module.exports = factory(require('jquery')); } else { // 浏览器全局变量(root 即 window) root.returnExports = factory(root.jQuery); } }(this, function ($) { // 方法 function myFunc(){}; // 暴露公共方法 return myFunc; }));