JavaScript模块化
@ 姜波 | 星期三,六月 26 日,2019 年 | 4 分钟阅读 | 更新于 星期三,六月 26 日,2019 年

如果不用模块化编写代码,那么会具有以下问题

  • 代码杂乱无章,没有条理性,不便于维护,不便于复用
  • 很多代码重复、逻辑重复
  • 全局变量污染
  • 不方便保护私有数据(闭包)

模块化的基本实现:闭包的自调用函数

//日期控件
var DatePicker = (function(){
    return {
        init(){

        }
    }
})();

//Header
//  tabbar
//  login

//Content
//  sidebar
//  table

//Footer

var KTV=(function(){
    return {
        pay(){

        },
        xiaofei(){

        }
    }
})()

AMD模块化 –>requireJS

  • AMD:async module define:异步模块定义
  • AMD其实就是requireJS实现的模块化解决方案

其他模块化解决方案

  • CommonJS:Node中使用的模块化解决方案

  • CMD(common module define):seajs中提出来的模块化解决方案

    • 其实CMD可以认为是CommonJS的前端实现
    • seajs由阿里的(玉帛)编写
    • seajs在2,3年前比较火,从去年开始已经停止更新
      • vue 、angular、react已经集成了各自的模块化
      • es6模块化
      • webpack也有模块化的解决方案
  • vue、angular、react已经将模块化的思想植入在里面

AMD和CMD的不同之处

  • amd需要依赖前置,cmd需要依赖就近
  • 导入导出方式不同:
    • amd通过define定义,return导出;
    • cmd通过不需要定义,只需要最后通过module.exports、exports导出

requireJS —— AMD规范

  • 中文网:http://www.requirejs.cn/docs/api.html#jsfiles

基本用法

//1、通过script标签导入requirejs源文件
//2、编写模块文件,基本格式如下:
//cart.js
define([],function(){
    console.log('cart模块');
})
//product.js
define([],function(){
    console.log('product模块');
})
//3、首页调用模块:
require(["cart.js","product.js"],function(){
    //编写后面的逻辑代码
})
//等价于:
require(["cart","product"],function(){
    
})

入口文件

配置

require.config({
    //baseUrl
    //paths
    
})

定义模块的返回值(返回值相当于模块的入口)

//cart.js:
define([],function(){

    return {
        init(){

        },
        addProduct(){

        }
    }
})

//首页:
require(["cart"],function(cart){
    cart.init();
    cart.addProduct();
})
  • 注意:一般在导入模块的时候,需要将有返回值的模块[前面]导入,无返回值的模块[后面]导入

案例——模块依赖子模块

//productAdd.js
define([],function(){
    return {
        init(){
            console.log("添加商品");
        }
    }
})

//productEdit.js
define([],function(){
    return {
        init(){
            console.log("编辑商品");
        }
    }
})

//product.js
define(["productAdd","productEdit"],function(productAdd,productEdit){
    return {
        init(){
            console.log("商品列表");
        },
        add(){
            productAdd.init();
        },
        edit(){
            productEdit.init();
        }
    }
})

//首页:
require(["product"],function(product){
    product.init();

    product.add();

    product.edit();

})

检测第三方库是否支持AMD规范

if ( typeof define === "function" && define.amd ) {
    define([], function() {
        return jQuery;
    } );
}
  • 类似的还有:echarts

常用的模块、文件夹路径的配置

  • 一般用于配置第三方模块,比如jquery、bootstrap、zepto等等
require.config(
    paths:{
        jquery:"js/lib/jquery-1.11.min",
        zepto:"js/lib/zepto.min",
        bootstrap:"assets/bootstrap/js/bootstrap.min"
    }
)

define(["jquery","zepto"],function($,$$){

})

require(["jquery","bootstrap"],function($){

})

插件

  • 插件列表:https://github.com/requirejs/requirejs/wiki/Plugins
  • i18n 国际化
  • text 加载文件(.html文件。。。)
    • 插件github地址:https://github.com/requirejs/text

requirejs和vuejs浅显的比较

  • requirejs是一个库
    • 相当于:一个房间
    • 相当于:一个底盘
    • 功能:只是一种模块化的解决方案
  • vue是一个框架
    • 相当于:一栋楼
    • 功能:
      • 1、不仅仅是模块化的解决方案
      • 2、减少了DOM的操作(–>jquery的功能)
      • 3、。。。。。。

requirejs解决循环依赖

  • a已经依赖了b
  • b中先添加require模块的依赖,然后再添加a的依赖,但是并不要去通过回调函数的形参获取返回值
    • define(["require","a"],function(require){})
    • 在需要执行a模块代码的时候,require("a")()

node中的模块化

  • require(“http”).createServer()
  • require(“fs”).readFile()
  • require(“common/type”).doSth()

前端路由的意义

  1. 通过路由将各个功能从url上面就分辨出来了
    • /user/list
    • /user/3
    • /user/edit/3
  2. 路由还可以进行前进、后退等导航操作

前端路由的实现方式

  • 1、监听window对象的hashchange事件
    • hash值:通过location.hash获取,获取的值以#开头
    • 也可以通过location.hash来设置hash值,当然设置的新hash也应该以#开头
  • 2、history对象:popState/pushState

ES6模块化

浏览器调试

<script type="module">
    //导入模块
</script>

基本用法

//cart.js
export default {
    name:"张三",
    age:18
}

//index.js
import cart from "./cart.js"
cart.name
cart.age

导出模块

//cart.js
export const age = 18;
export function f1(){
    console.log("f1函数");
}
//默认返回值
export default {
    init(){
        console.log("初始化");
    }
}

//index.js
import cart,{ age,f1 } from "./cart.js"
cart.init();
age,
f1();

导入模块

//index.js
import cart as cartIndex from "./cart.js"
import { age as AGE } from "./product.js"

//使用变量:cartIndex
//使用变量:AGE
js
保存为图片

公众号

Image text

QQ

Image text

微信

Image text

微信打赏

Image text

社交链接