对比requirejs更好的理解seajs

seajs遵循CMD规范,requirejs遵循AMD规范。AMD规范是预加载,CMD规范是赖加载。

下文举例假设有文件 b.js, c.js如下

//b.js
define(function(require, exports, module){
    console.log('b is loaded')

    function run(){
        console.log('b run');
    }
    exports.run = run;
})

//c.js
define(function(require, exports, module){
    console.log('c is loaded')

    function run(){
        console.log('c run');
    }
    exports.run = run;
})

1. seajs对依赖模块只加载不执行,requirejs对依赖模块既加载也执行

运行代码:

// seajs
<!DOCTYPE html>
<html>
<head>
    <title>seajs</title>
    <script type="text/javascript" src="./sea.min.js"></script>
</head>
<body>
<button id="btn">OK</button>
<script type="text/javascript">
    seajs.use('./a.js')
</script>
</body>
</html>

// requirejs
<!DOCTYPE html>
<html>
<head>
    <title>requirejs</title>
    <script type="text/javascript" src="./require.js"></script>
</head>
<body>
<button id="btn">OK</button>
<script type="text/javascript">
    require(['a'])
</script>
</body>
</html>

// a.js
define(['b'], function(){
})

运行结果:

seajs:

控制台无输出

requirejs:

控制台:

2. seajs ,requirejs在 require文件时既加载也执行

//a.js
define(function(require, exports, module){
    var b = require('b')
})

requirejs:

控制台:b is loaded

seajs:

控制台:b is loaded

3. seajs可以在任意处直接require文件,无需提前写依赖模块;一旦提前写了任意一个依赖模块,下面的所有require的使用必须保证也有其对应的依赖模块

seajs可以直接如下使用,无需写依赖['b']:

//a.js
define(function(require, exports, module){
    var b = require('b')
})

或

 运行结果:

控制台:b is loaded

假如 a.js 依赖了另一个 c.js,则在 a.js 中使用 require('b') 时必须也写上依赖['b'],否则b.js将因为查找不到而不会加载

define(['c'], function(require, exports, module){
    var b = require('b')
})

运行结果:

 控制台无输出(不会输出c is loaded, 因为没有require('c') )

如果此时我们执行b.run()

define(['c'], function(require, exports, module){
    var b = require('b')
    b.run()
})

控制台将会报错,因为此时b为null:

 此时正确写法应该写上依赖 ['b']:

define(['c', 'b'], function(require, exports, module){
    var b = require('b')
    b.run()
}) 

运行结果:

结论:

对于seajs,如果不写依赖那就一个都不要写,一旦写了,下面所有require的地方都需要提前在头部写上依赖

requirejs的依赖写法如下:

define(['c', 'b'], function(c, b){
    var b = require('b')
    b.run()
})

或

define(function(require, exports, module){
    var b = require('b')
    b.run()
})

//错误写法
define(['c'], function(c){
    var b = require('b')
    b.run()
})

4. seajs的require.async在执行到使用位置的时候才去异步加载

seajs:

如下例:

// a.js
define(function(require, exports, module){
    document.getElementById('btn').addEventListener('click',       function(){
     document.getElementById('btn').innerHTML = 'btn is clicked'
        init()
    })
    
    function init(){
        var b = require('b');
        b.run()
    }
})

运行结果:

控制台无输出

点击OK按钮, b.js 加载并执行b.js和run方法:

大家注意到,在未点击按钮之前,虽然没有执行init方法,但b.js依然被提前加载了进来,但没有被执行(没有输出b is loaded)。

很多时候我们想在执行init方法的时候再去加载b.js,而不是提前在页面加载的时候就把b,js加载。

这时候就需要用到require.async,如下:

//a.js
define(function(require, exports, module){
    document.getElementById('btn').addEventListener('click', function(){
        document.getElementById('btn').innerHTML = 'btn is clicked'
        init()
    })
    
    function init(){
        require.async('b', function(b){
            b.run()
        });
    }
})

这时候运行结果:

b.js没有被加载:

控制台无输出:

点击OK按钮:

b.js被加载

控制台输出:

这是因为当执行一个js时,seajs会先去查找匹配require,然后加载相应资源,但不执行。匹配到require.async时不加载。

所以,require.async达到了用到时再去异步加载并执行的目的。

小问题:

如果是requirejs执行下面代码:

//a.js
define(function(require, exports, module){
    document.getElementById('btn').addEventListener('click', function(){
        document.getElementById('btn').innerHTML = 'btn is clicked'
        init()
    })
    
    function init(){
        var b = require('b');
        b.run()
    }
})

资源如何加载?控制台又会输出什么呢?点击ok按钮又会输出啥? 答:资源加载了a.js, b.js, 控制台输出:b is loaded, 点击OK按钮控制台继续输出:b run (选择“答”后面的部分查看答案)

总结:

1. seajs对依赖模块只加载不执行,requirejs对依赖模块加载并执行

2. seajs ,requirejs在 require具体文件时既加载也执行

3. seajs可以在任意处直接require文件,无需提前写依赖模块;一旦提前写了任意一个依赖模块,下面的所有require的使用必须保证也有其对应的依赖模块

4. seajs的require.async在执行到使用位置的时候才去异步加载

本文demo:

https://github.com/saysmy/seajs-requirejs-demo

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Astropeak

用emacs的org2blog组件写cnblogs博客 -- 环境配置及使用

1133
来自专栏移动端周边技术扩展

Vue.js学习笔记(1)

851
来自专栏北京马哥教育

73条日常shell命令汇总,总有一条你需要!

1.检查远程端口是否对bash开放: echo >/dev/tcp/8.8.8.8/53 && echo "open" 2.让进程转入后台: Ctrl + z...

36611
来自专栏WindCoder

windows下python中pip与easy_install相关

下载地址:https://pypi.python.org/pypi/ez_setup

1051
来自专栏IT综合技术分享

一、搭建SpringBoot2.0.0M4基础Web项目

SpringBootDemo1 - [~-IdeaProjects-SpringBootDemo1] - IntelliJ IDEA 2017.2.4_022....

2232
来自专栏iOS开发笔记

iOS开发之-cordova项目创建

1.选择创建项目的目录 $ cd desktop 这里选择的是桌面,可以根据自己实际情况选择目录 2. 创建项目 $ cordova create hello ...

3356
来自专栏iOS122-移动混合开发研究院

【最新】LuaJIT 32/64 位字节码,从编译到使用全纪录

网上关于 LuaJIT 的讨论,已经显得有些陈旧。如果你对 LuaJIT 编译 Lua 源文件为具体的 32位或64位字节码,极其具体使用感兴趣的话,不妨快速读...

1970
来自专栏Python自动化测试

python自动化环境搭建

selenium是测试web应用程序的框架,selenium为没有测试脚本的人提供了(seleniumide)提供了录制/回放的工具,同时它也提供了特定...

1523
来自专栏开发技术

将tomcat添加为linux系统服务

  在博客 --》virtualBox安装centos,并搭建tomcat中,讲到了centos下搭建tomcat环境,发现启动tomcat不是那么方便,要是忘...

1462
来自专栏nummy

sphinx入门指南【2】 toctree指令详解

reST本身并不支持同时与多个文档进行交互,或者说将一个文档保存到多个文件中。Sphinx提供了自定义指令toctree来支持实现这个功能。

1203

扫码关注云+社区

领取腾讯云代金券