js模块化开发

为什么要模块化开发

ie6之前没有js引擎,js引擎在渲染引擎中。
ie6之后有了js引擎,这时js脚本是与HTML页面写在一起的,随着页面交互等复杂度的增加,又以页面为标准分成不同的脚本块(index.html中引用index.js;index2.html中引用index2.js脚本块)这是模块化的初现
这时出现一个问题,多个js脚本中包含同样的程序块,这时可以把这些共同的程序块提取到一个js文件中管理。这时在HTML页面中需要引用共同js文件和页面特有的js文件。
这时又出现一个问题,在HTML页面引用共同js文件时,在js文件中包含很多不是本页面需要的程序块,这时就产生了资源的浪费,所以说以页面为基础划分js文件并不是那么完美,为了解决这个问题,开始以程序功能模块划分js文件。

modelA.js

var a =[1,2,3,4,5].reverse();

modelB.js

var b=a.concat([6,7,8,9])

modelC.js

var c = b.join('-');

index.js

console.log(a);
console.log(b);
console.log(c);

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script src="js/modelA.js"></script>
    <script src="js/modelB.js"></script>
    <script src="js/modelC.js"></script>
    <script src="js/index.js"></script>
</body>
</html>

问题:
js引擎加载阻塞,必须按照程序的逻辑顺序加载引用模块
在这里
引用在同一个页面的js文件共用一个全局作用域
模块化解决的问题
加载顺序
污染全局

es5

立即执行函数
函数声明不是表达式,不能使用执行符号,而表达式可以。可以把函数声明变成表达式,使用括号包裹,变成表达式,在使用执行符号
modelA.js

var moduleA= (function () {
var a =[1,2,3,4,5].reverse();
    return{
        a :a
    };
  })();

modelB.js

var moduleB=(function(moduleA){
    var b = moduleA.a.concat([6,7,8,9]);
    return {
        b: b
    }
})(moduleA);

modelC.js

var moduleC=(function(moduleB){
    var c =moduleB.b.join('-');
    return {
        c:c
    }
})(moduleB);

index.js

(function(moduleA,moduleB,moduleC){
    console.log(moduleA.a);
    console.log(moduleB.b);
    console.log(moduleC.c);
})(moduleA,moduleB,moduleC);

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script src="js/modelA.js"></script>
    <script src="js/modelB.js"></script>
    <script src="js/modelC.js"></script>
    <script src="js/index.js"></script>
</body>
</html>

每个模块是用了立即执行函数,借用函数的闭包,使每个模块有了独立的作用域,同时模块之间可以依赖了,但是依然没有解决模块加载顺序问题

CommonJs

所有代码都运行在模块作用域,不会污染全局作用域。

模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。

模块加载的顺序,按照其在代码中出现的顺序

modelA.js

  var a=(function(){
    return [1,2,3,4,5].reverse();
})();
module.exports={
    a
}

modelB.js

var moduleA=require('./modelA')
var b=(function(){
    return moduleA.a.concat([6,7,8,9]);
})();
module.exports={
    b
}

modelC.js

var moduleB=require('./modelB')
var c=(function(){
    return moduleB.b.join('-'); 
})();
module.exports={
    c
}

index.js

var moduleA=require('./modelA')
    moduleB=require('./modelB')
    moduleC=require('./modelC')

    console.log(moduleA.a);
    console.log(moduleB.b);
    console.log(moduleC.c);

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0123467809-=">
    <title>Document</title>
</head>
<body> 
    <script src="js/index.js"></script>
</body>
</html>

对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。CMD 推崇 as lazy as possible.

CMD 推崇依赖就近,AMD 推崇依赖前置。

AMD(异步模块定义)

requireJS
modelA.js

define('moduleA',function(){
  var a=[1,2,3,4,5];
  return {
    a:a.reverse()
  }
})
 

modelB.js


define('moduleB',['moduleA'],function(moduleA){
    var b=[6,7,8,9,10];
    return {
     b: moduleA.a.concat(b)
    }
  });

modelC.js

define('moduleC',['moduleB'],function(moduleB){
    return{
        c:moduleB.b.join('_')
    }
})

index.js

    require.config({
        paths:{
            moduleA:'js/modelA',
            moduleB:'js/modelB',
            moduleC:'js/modelC',
            
        }
    })
   require(['moduleA','moduleB','moduleC'],function(moduleA,moduleB,moduleC){
    console.log(moduleA.a);
    console.log(moduleB.b);
    console.log(moduleC.c);
   })
      //所有模块加载完毕后,才会执行回调函数,前置依赖

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0123467809-=">
    <title>Document</title>
</head>
<body> 
    <script src="./node_modules/requirejs/require.js"></script>
    <script src="js/index.js"></script>
</body>
</html>

CMD(同步模块定义)

modelA.js

define(function(require,exports,module){
  var a=[1,2,3,4,5];
  return {
    a:a.reverse()
  }
})

modelB.js

define(function(require,exports,module){
    var moduleA=require('modelA')
    var b=[6,7,8,9,10];
    return {
        b: moduleA.a.concat(b)

    }
  }) 

modelC.js

define(function(require,exports,module){
    var moduleB=require('modelB')
    
    return {
        c:moduleB.b.join('_')

    }
  })

index.js

    require.config({
        paths:{
            moduleA:'js/modelA',
            moduleB:'js/modelB',
            moduleC:'js/modelC',
            
        }
    })
   seajs.use(['modelA.js','modelB.js','modelC.js'],function(moduleA,moduleB,moduleC){
    console.log(moduleA.a);
    console.log(moduleB.b);
    console.log(moduleC.c);
})

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script src="js/sea.js"></script>
    <script src="js/index.js"></script>
</body>
</html>

ES6

modelA.js

export default{
  a:[1,2,3,4,5]
}

modelB.js

import moduleA from './modelA.js'

  export default{
      b:moduleA.a.concat([6,7,8,9,10])
  }
   

modelC.js

import moduleB from './modelB.js'
export default{
    c:moduleB.b.join('_')
}

index.js

import moduleA from './modelA.js';
import moduleB from './modelB.js';
import moduleC from './modelC.js';

console.log(moduleA.a);
console.log(moduleB.b);
console.log(moduleC.c);

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script type="module" src="js/index.js"></script>
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值