前端模块化

前言

前端开发领域发展到目前阶段:

  • 零件化 - 最终呈现给用户是一个完整的产品(由各个零件组成的)

    • 降低生产成本 – 多人协作(每个人各司其职)
    • 降低使用成本 - 各个零件之间是低耦合的
  • 组件化 - 将一个完整的产品划分成各个组件

    • 前端开发中更多是指HTML页面和CSs样式
  • 模块化 - 将一个完整的产品划分成各个模块

    • 前端开发中更多是指JavaScript逻辑
  • 组件化与模块化的关系

    1. 将一个完整的产品,划分成若干的组件
    2. 将每一个组件划分成若干的模块
  • 组件化与模块化的特点

    1. 是低耦合的 - 软件开发的统一原则
    2. 是热插拔的 - 指的是需要时使用,不需要是去掉

 

前端模块化是什么

所谓模块化,就是指根据功能的不同进行划分,每个功能就是一个模块。最终,一个完整的产品是由各个模块组合而成的。

特点:

  • 独立性 - 可以针对一个模块单独进行设计、研发,相对工作量和难度变小。
  • 复用性 - 一些通用模块(例如登录或注册)可以被重复使用,而不用每次重新开发。
  • 解耦性 - 模块与模块之间,将相互影响降到最低,使得更换、升级或添加某个模块,不影响其他模块的工作。
  • 灵活性 - 通过选择和组合不同的模块,可以快速构建一个新的产品。

 

ECMAScript 5的模块化
没有模块化概念

无模块化概念

 

函数的封装

函数的定义可以将代码逻辑封装在指定的函数作用域中

无法在全局作用域再定义一个outer()函数

 

对象的定义

使用对象实现的好处:

  • 解决了全局命名空间可能出现的冲突问题。因为所有的模块成员都是作为一个对象的属性或方法存在的。
  • 模块成员之间也存在着某种关系。因为被定义在同一个JavaScript对象中,作为属性或方法存在。而这个对象名成为了所有模块成员对外的一个统一的模块名称。

 

自调函数

看似引入对象概念后,这个模块的解决方案不错,但依旧存在着一些问题。对于这样一个模块(对象),是可以从外部对该模块(对象)的属性或方法进行修改的。这就导致了会产生一些意外的安全问题,而这个问题可以通过自调函数来进行解决。

 

最终模块化结构
var outer = (function (){
	var v = 'longestory';
	var interface ={
		getAttr: function (){
			return v;
       },
		inner: function (){
			return 'this is inner function.";
		}
	}
	return interface;
})();

 

ECMAScript 6的模块化
ECMAScript 6的模块化
  • ECMAScript 2015的模块自动开启严格模式,即使没有写use strict;.

  • 可以在模块中使用import和export命令。

 

export命令

export命令用于将指定的模块内容导出,该命令可以修饰在function、var、let或 const等之前。

export var v = 100;
export const c = 1000;
export let l = 'this is string.';
export function fn(){
	return 'this is function.';
} 

 

import命令

irmport命令用于导入其他模块所提供的功能,

import {...} from modulepath;
import {导出的名称 as 别名}from modulepath

使用import命令导入的名称必须与模块使用export 导出的名称一致。
使用 import命令导入其他模块的内容时,默认使用的是模块声明的名称。也可以在导入时,进行重命名。

 

前端模块化规范
  • CommonJS
  • RequireJS(AMD)
  • SeaJS(CMD)

 

RequireJS
加载RequireJS
<script src = 'script/require.js' defer async='true'></script>

 

主模块的编写
<script data-main='scripts/main.js' src='scripts/teauire.js' defer async='true'></script>

 

定义模块
  • 健值对方式定义

  • 函数式定义

  • 存在依赖的函数式定义

 

加载模块
  • RequireJS使用config()函数对模块的加载行为进行自定义。
reauire.config({
	paths: {
		'jquery':''jquery.min',
		'underscore': 'underscore.min',
		'backbone': 'backbone.min'
	}
};
  • RequireJS使用require()函数来加载指定模块。
require(['jquery' , 'underscore', 'backbone'], function ($,_, Backbone) {
	// some code here
});

 

SeaJS
加载SeaJS
<script src = 'script/sea.js' defer async='true'></script>

 

加载模块
  • 利用config()方法进行配置
//seajs的简单配置
seajs.config({
	base: '../sea-modules/',
	alias: {
		'jquery': 'jquery/jquery/1.10.1/jquery.js'
    }
})
  • 利用use()方法加载模块
//加载入口模块
seajs.use('../static/hello/src/main')

 

定义模块
  • 利用define()方法定义模块
//所有模块都通过define来定义
define(function (require, exports, module){
	//通过require 引入依赖
	var $ = require('jquery');
	var Spinning = require(''./spinning')
   //通过exports对外提供接口
   eports.doSomething= ...
	//或者通过module.exports提供整个接口
  	module.exports = ...
});
Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐