JS模块化简单实现

本文介绍了如何实现一个简单的JavaScript模块加载器,类似requireJS的功能。通过分析加载过程,解决了如何加载脚本、判断模块加载完毕及暂存执行回调函数等问题。文章提及使用DOM元素加载脚本以避免跨域,并通过模块状态跟踪依赖。虽然未处理循环依赖问题,但程序会因不满足条件而终止执行,避免无限循环导致崩溃。
摘要由CSDN通过智能技术生成

曾经花了一段时间去看RequireJS源码,虽然就两千行左右的代码,但原谅我的愚笨,真的有点看不懂。想想,还是自己实现一个再说。

简单目标

实现类似requireJS的功能,涉及到的功能

// 定义模块,三个参数
define(id, deps, factory)

// 执行模块,两个参数
require(deps, factory) 

简单分析

先上一个简单的例子,进行分析:

require(['main'], function(main) {
    console.log('start~~~');
    main.hello();
});
  1. 过程分析

通过deps参数,很容易知道该文件依赖的脚本是main.js,然后去加载依赖的脚本,加载完之后执行一遍并且将执行的结果作为回调函数factory的参数,然后执行该匿名的回调函数即可。

  1. 问题分析

    1. 如何加载脚本

      这个比较容易想到两个方式,一种用ajax请求,另一种用Dom元素添加让浏览器加载;由于ajax请求会有跨域问题,我们采用Dom加载的方式。

    2. 如何判断模块加载完毕

      曾经我想用script的onload事件来判断对应的模块加载,但问题在于onload只是说明了脚本已经加载,但是并没有执行。调整一下思路,定义模块的状态,在加载的时候,将状态标为加载中;记录模块的依赖数,当该模块的所有依赖全部加载完成,将执行回调函数作为该模块的对应输出,模块加载完成。

    3. 如何暂存和执行回调函数

      比如上面这个简单的例子,将回调函数作为模块main加载完毕后的回调函数即可;若依赖的模块有多个,每个依赖加载完后进行就判断依赖是否加载完毕,是就执行回调。注意,此时也意味着当前模块加载完毕,可以执行返回结果了。

    4. 循环依赖问题

      这么难的问题,留到后面再说吧!

  2. 数据结构

    首先需要一个全部的模块缓存对象,记录所有已经加载的&正在加载的模块;将模块的数据结构设计成如下:

    module[name] = {
        status: String,   // 记录模块的加载状态'loading' or 'loaded'
        export: Object  , // 记录该模块的输出结果
        onload: Arrray[function]    // 记录模块加载完成后的回调函数
    }
    

简单实现

小女不才,实现主要参考了叶小钗博客的实现,读懂了他/她(不确定性别)的实现之后,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值