在javascript是没有类似java或其他语言的模块概念的,因此也不可能通过import或using等关键字来引用模块,这样造成了复杂项目中前端代码混乱,变量互相影响等。

因此在复杂项目中引入AMD的概念,AMD:全称是Asynchronous Module Definition,即异步模块加载机制。通过AMD可以不需要在页面中手动添加<script>来引用脚本,而通过定义依赖自动加载模块脚本,接下来的代码将讲解如何实现建议的AMD模块,如果需要查看比较详细的实现可以下载requirejs源码。

简易实现整体思路:

1.将模块名及模块文件地址存入内存

2.通过define方法将模块名及模块依赖关系以及模块实现代码存入内存

3.require方法通过loadscript方法将需要依赖的模块代码导入并执行define方法存入内存,模块通过入参传入实际代码中,从而完成模块加载。

1.定义模块:

实现模块的定义,并将模块定义存储。

           /**
*
* @param id 模块名
* @param deps 依赖模块
* @param factory 模块实现
*/
define: function (id, deps, factory) {

在定义模块中,需要将模块名,模块依赖,模块代码存储至内存中

           /**
*
* @param id 模块名
* @param deps 依赖模块
* @param factory 模块实现
*/
define: function (id, deps, factory) {
// 模块是否存在
if (modules[id]) throw new Error("module:" + id + "已经存在!");
if (arguments.length > 2) {
modules[id] = {
id: id,
deps: deps,
factory: factory
}
}
else if (arguments.length == 2) {
modules[id] = {
id: id,
factory: deps
}
}
else {
throw new Error("module:参数有误!");
}
},

2.引用模块:

输入依赖模块名,执行代码,代码示例如下:

           /**
* 异步导入模块
* @param deps 依赖模块
* @param callback
* @returns {{}}
*/
require: function (deps, callback) {
// 插入脚本
deps = [].slice.call(deps);
// 获取依赖脚本
loadScript(deps, buildModule, callback);
},

详细步骤:

首先需要从依赖的文件夹中导入脚本,

        /**
* 从外部加载js
* @param deps 依赖模块
* @param buildModule 创建模块方法
* @param callback
*/
function loadScript(deps, buildModule, callback) {
var depJsCounter = 0;
deps.forEach(function (dep) {
var script = document.createElement("script")
script.type = "text/javascript";
script.src = configs[dep];
document.getElementsByTagName("head")[0].appendChild(script);
script.onload = function () {
// 依赖js加载计数标记
depJsCounter++;
if (depJsCounter == deps.length) {
buildModule(deps, callback)();
}
};
}); }

构建模块,从全局module中取出依赖模块,将依赖模块作为入参注入到现有模块,最后执行现有模块

        /**
* 创建模块
* @param deps 依赖模块
* @param callback
* @returns {Function}
*/
var buildModule = function (deps, callback) {
return function () {
// 获取依赖模块
var args = [];
deps = [].slice.call(deps);
deps.forEach(function (dep) {
var module = modules[dep]
if (typeof module.factory === 'function')
module.factory = module.factory();
args.push(module.factory)
})
// 将依赖模块注入到callback中
var temp = {};
callback.apply(temp, args);
return temp
}
}

3.注册模块

注册模块主要将名字与文件路径关联起来,便于从路径中下载js,代码清单如下:

           /**
* 注册模块
* @param obj
*/
config: function (obj) {
var path = obj.paths;
for (var el in path) {
Object.defineProperty(configs, el, {
enumerable: false,
configurable: false,
writable: true,
value: path[el]
})
}
}
}

4.执行实例

编写模块

define('module1', function () {
var module1 = {};
module1.sayhello = function () {
return 'hello module1';
}
return module1;
});

将代码保存js文件并取名module1

新建html文件,在html中先注册模块,通过require 导入模块,并利用模块编写代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<script src="/demo/01Requirejs/require.js"></script>
</head>
<body> </body>
</html>
<script> require.config({
paths:{
module1:'/demo/01Requirejs/module1.js'
}
}); require(['module1'],function(module1){
alert(module1.sayhello());
}) </script>

javascript 异步模块加载 简易实现的更多相关文章

  1. Dojo初探之1:AMD规范,编写符合AMD规范(异步模块加载机制)的模块化JS(其中dojo采用1.11.2版本)

    一.AMD规范探索 1.AMD规范(即异步模块加载机制) 我们在接触js的时候,一般都是通过各种function来定义一些方法,让它们帮我们做一些事情,一个js可以包含很多个js,而这些functio ...

  2. Angularjs 异步模块加载项目模板

    ng-lazy-module-seed(Angularjs 异步模块加载项目模板) 相信做过SPA项目的朋友都遇到过这个问题:页面初始化时需要加载文件太大或太多了,许多文件加载后很可能不会运行到,这是 ...

  3. javascript异步延时加载及判断是否已加载js/css文件

    <html> <head> <script type="text/javascript"> /**======================= ...

  4. JavaScript AMD 模块加载器原理与实现

    关于前端模块化,玉伯在其博文 前端模块化开发的价值 中有论述,有兴趣的同学可以去阅读一下. 1. 模块加载器 模块加载器目前比较流行的有 Requirejs 和 Seajs.前者遵循 AMD规范,后者 ...

  5. [JavaScript] 前端模块加载简单实现(require)

    模块加载的简单实现 (function(win) { var baseUrl; var paths; var script_cache = {}; var script_queue = []; var ...

  6. javascript之模块加载方案

    前言 主要学习一下四种模块加载规范: AMD CMD CommonJS ES6 模块 历史 前端模块化开发那点历史 require.js requirejs 为全局添加了 define 函数,你只要按 ...

  7. 抛砖引玉:探讨网站性能优化之Javascript异步懒加载技术

    懒加载技术是现在许多大型网站的都使用的提高网站性能的方式,它的核心思想是当用户想看页面某个区域时,再加载该区域的数据.这在一定程度上减轻了服务器端的压力,也加快了页面的呈现速度. 其实国内很多网站都用 ...

  8. requirejs解决异步模块加载方案

    他首先会遍历enableRegistry取出其中定义的模块,并且将没有加载成功的模块标识注入noLoads数组,如果过期了这里就会报错 如果上述没问题还会做循环依赖的判断,主要逻辑在breakCycl ...

  9. 关于javascript模块加载技术的一些思考

    前不久有个网友问我在前端使用requireJs和seajs的问题,我当时问他你们公司以前有没有自己编写的javascript库,或者javascript框架,他的回答是什么都没有,他只是听说像requ ...

随机推荐

  1. asp.net mvc笔记一,最小的MVC工程

    Asp.net MVC项目默认会引用很多第三方插件,特别是现在的5.0,默认示例项目就几十M,搞得都不知道那些才是MVC必须的,是重点,那些是可有可无的. 今天我们就来试验一下,看看一个最小的MVC工 ...

  2. 推荐一个算法编程学习中文社区-51NOD【算法分级,支持多语言,可在线编译】

    最近偶尔发现一个算法编程学习的论坛,刚开始有点好奇,也只是注册了一下.最近有时间好好研究了一下,的确非常赞,所以推荐给大家.功能和介绍看下面介绍吧.首页的标题很给劲,很纯粹的Coding社区....虽 ...

  3. Prim算法(一)之 C语言详解

    本章介绍普里姆算法.和以往一样,本文会先对普里姆算法的理论论知识进行介绍,然后给出C语言的实现.后续再分别给出C++和Java版本的实现. 目录 1. 普里姆算法介绍 2. 普里姆算法图解 3. 普里 ...

  4. tomcat对请求路径的匹配过程(原创)

    1.匹配服务 如果有两个应用,一个应用只能通过80端口访问,另一个应用只能通过8080端口访问,这种情况下,可以分开两个服务,然后分别创建80端口和8080端口的连接器. 2.匹配主机 一个服务下配置 ...

  5. C#预处理器指令 ,你造吗??? (●'◡'●)

    什么是c#预处理指令?? 用于在 C# 源代码中嵌入的编译器命令. C#预处理器指令有哪些?? ↓↓↓这些就是预处理器指令啦 下面我们一一道来(●'◡'●) 1.#if ,#elif,#else,en ...

  6. Spring学习总结(二)——静态代理、JDK与CGLIB动态代理、AOP+IoC

    一.为什么需要代理模式 假设需实现一个计算的类Math.完成加.减.乘.除功能,如下所示: package com.zhangguo.Spring041.aop01; public class Mat ...

  7. redis学习之三配置文件redis.conf 的含义

    摘自http://www.runoob.com/redis/redis-conf.html 安装redis之后的第一件事,我就开始配置密码,结果总是不生效,而我居然还没想到原因.今天突然用命令行设置了 ...

  8. Auto Mapper03

      经过上一篇博客的学习,大体了解了Auto Mapper的运行机制和操作流程.我们下来学习下,AutoMapper里面具体的一些东西. 一:规则       当我们使用AutoMapper创建实体和 ...

  9. .Net Framework源码

    http://referencesource.microsoft.com/

  10. css异常

    1.0 样式的引用顺序不对会导致样式显示不正常.个人推荐:把别人写好的样式引用在最前面,自己写的放在后面. 2.0 UC手机浏览器 UC手机浏览器在识别到页面文字很多的情况下会自动放大字体优化阅读体验 ...