JS模块加载器加载原理是怎么样的?
路人一:
原理一:id即路径 原则。
通常我们的入口是这样的: require( [ 'a', 'b' ], callback ) 。这里的 'a'、'b' 都是 ModuleId。通过 id 和路径的对应原则,加载器才能知道需要加载的 js 的路径。在这个例子里,就是 baseUrl + 'a.js' 和 baseUrl + 'b.js'。
但 id 和 path 的对应关系并不是永远那么简单,比如在 AMD 规范里就可以通过配置 Paths 来给特定的 id 指配 path。
原理二:createElement('script') & appendChild
知道路径之后,就需要去请求。一般是通过 createElement('script') & appendChild 去请求。这个大家都知道,不多说。有时候有的加载器也会通过 AJAX 去请求脚本内容。
一般来说,需要给 <script> 设置一个属性用来标识模块 id, 作用后面会提到。
原理三:document.currentScript
a.js 里可能是 define( id, factory ) 或者是 define( factory ),后者被称为匿名模块。那么当 define(factory) 被执行的时候,我们怎么知道当前被定义的是哪个模块呢,具体地说,这个匿名模块的实际模块 id 是什么? 答案是通过 document.currentScript 获取当前执行的<script>,然后通过上面给 script 设置的属性来得到模块 id。
需要注意的是,低级浏览器是不支持 currentScript 的,这里需要进行浏览器兼容。在高级浏览器里面,还可以通过 script.onload 来处理这个事情。
原理四:依赖分析
在继续讲之前,需要先简单介绍下模块的生命周期。模块在被 Define 之后并不是马上可以用了,在你执行它的 factory 方法来生产出最终的 export 之前,你需要保证它的依赖是可用的。那么首先就要先把依赖分析出来。
简单来说,就是通过 toString 这个方法得到 factory 的内容,然后用正则去匹配其中的 require( 'moduleId' )。当然也可以不用正则。
这就是为什么 require( var ); 这种带变量的语句是不被推荐的,因为它会影响依赖分析。如果一定要用变量,可以用 require( [ var ] ) 这种异步加载的方式。
原理五:递归加载
在分析出模块的依赖之后,我们需要递归去加载依赖模块。
上面的代码只是表达一个意思,实际上 load 方法很可能是异步的,所以递归的返回要特殊处理下。
实现一个可用的加载器并没有那么简单,比如你要处理循环依赖,还有各种各样的牵一发动全身的细节。但要说原理,大概就是这么几条。个人觉得,比起照着规范实现一个加载器,更加吸引人的是 AMD 或者 CommonJS 这些规范的完善和背后的设计思路。
路人二:
Require、Seajs模块器加载的原理是怎么样的?
1. 定义一套依赖规则, 如AMD CMD CommonJS Modules规范,规范即规则
2. 加载入口文件及其依赖,原理即按依赖关系递归执行 document.createElement('script')
3. 维护模块从初始到销毁的生命周期
模块加载都有什么方式?
1. 手动模式 - 人肉管理
2. 自动模式- 模块加载器管理
3. 混合模式 - 1,2结合
不同方式各有什么利弊?
1. 首先千万别拿着锤子看啥都是钉子,依场景使用
2. 基于约定的模块依赖管理相比人肉是更好实践,但谨记1
3. 使用了模块管理器后,必然会引入复杂度,这是复杂度的转移,如何驾驭这些也是成为优秀工程师的修炼之路
4. 使用模块加载器后最头疼的是构建发布问题,使用seajs的童鞋应该深有体会吧
JS模块加载器加载原理是怎么样的?的更多相关文章
- JavaScript AMD 模块加载器原理与实现
关于前端模块化,玉伯在其博文 前端模块化开发的价值 中有论述,有兴趣的同学可以去阅读一下. 1. 模块加载器 模块加载器目前比较流行的有 Requirejs 和 Seajs.前者遵循 AMD规范,后者 ...
- 【模块化编程】理解requireJS-实现一个简单的模块加载器
在前文中我们不止一次强调过模块化编程的重要性,以及其可以解决的问题: ① 解决单文件变量命名冲突问题 ② 解决前端多人协作问题 ③ 解决文件依赖问题 ④ 按需加载(这个说法其实很假了) ⑤ ..... ...
- AngularJs2与AMD加载器(dojo requirejs)集成
现在是西太平洋时间凌晨,这个问题我鼓捣了一天,都没时间学英语了,英语太差,相信第二天我也看不懂了,直接看结果就行. 核心原理就是require在AngularJs2编译过程中是关键字,而在浏览器里面运 ...
- dojo1.7 加载器
原文地址:http://dojotoolkit.org/documentation/tutorials/1.7/modules/ dojo现在支持在异步模块异步(AMD)定义中加入模块写入功能了,这使 ...
- Java提高篇——JVM加载class文件的原理机制
在面试java工程师的时候,这道题经常被问到,故需特别注意. 1.JVM 简介 JVM 是我们Javaer 的最基本功底了,刚开始学Java 的时候,一般都是从“Hello World ”开始的,然后 ...
- JVM加载class文件的原理机制(转)
JVM加载class文件的原理机制 1.Java中的所有类,必须被装载到jvm中才能运行,这个装载工作是由jvm中的类装载器完成的,类装载器所做的工作实质是把类文件从硬盘读取到内存中 2.java中的 ...
- jvm(1)类的加载(三)(线程上下文加载器)
简介: 类加载器从 JDK 1.0 就出现了,最初是为了满足 Java Applet 的需要而开发出来的. Java Applet 需要从远程下载 Java 类文件到浏览器中并执行. 现在类加载器在 ...
- Day18 (一)类的加载器
一个运行时的Java虚拟机(JVM)负责运行一个Java程序. 当启动一个Java程序时,一个虚拟机实例诞生:当程序关闭退出,这个虚拟机实例也就随之消亡. 如果在同一台计算机上同时运行多个Java程序 ...
- JVM类加载(4)—加载器
定义: 虚拟机设计团队把类加载阶段中“通过一个类的全限定名来获取描述此类的二进制字节流”这个动作放到虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类.实现这个动作的代码模块称之为“类加载器 ...
随机推荐
- Operfire/XMPP
Operfire/XMPP 关于Openfire.XMPP协议.IM相关知识 基于开源 Openfire 聊天服务器 - 开发聊天记录插件 posted @ 2013-03-29 11:03 hooj ...
- [Node.js] Exporting Modules in Node
In this lesson, you will learn the difference between the exports statement and module.exports. Two ...
- a href=#与 a href=javascript:void(0) 的差别
a href="#"> 点击链接后,页面会向上滚到页首,# 默认锚点为 #TOP <a href="javascript:void(0)" onCl ...
- ViewPager的用法和实现过程
看图先: 页面中填充内容是随机关键词飞入和飞出动画效果,随后会更新,如今请先无视吧 首先是 导入jar包 下载地址:android-support-v4.jar 布局文件中加入v ...
- Java 线程池的原理与实现(转)
这几天主要是狂看源程序,在弥补了一些以前知识空白的同时,也学会了不少新的知识(比如 NIO),或者称为新技术吧.线程池就是其中之一,一提到线程,我们会想到以前<操作系统>的生产者与消费者, ...
- 用C语言扩展Python的功能
https://www.ibm.com/developerworks/cn/linux/l-pythc/
- AOP 的利器:ASM 3.0 介绍
引言 什么是 ASM ? ASM 是一个 Java 字节码操控框架.它能被用来动态生成类或者增强既有类的功能.ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态 ...
- popupWindow使用详解
popupWindow说起来简单,但是使用略麻烦,今天带大家来看看怎么使用,先来看看效果图: 先来看看布局文件吧: <RelativeLayout xmlns:android="htt ...
- Big Data 應用:第二季(4~6月)台湾地区Game APP 变动分布趋势图
图表简介: 该示意图表示了台湾地区第二季内所有Game APP类别的分布情形,经由该图表我们可以快速的了解到在这三个月内,哪类型的APP是很稳定:抑或者哪类型的APP是非常不稳定的. 名词解释: 类别 ...
- php错误处理和异常处理
PHP错误处理有两种:标准的错误处理和异常(OOP语法新出现的错误处理机制)