神奇的 require
首先还是看一段代码吧:
1
2
3
4
5
6
|
var http = require( 'http' );
http.createServer( function (req, res) {
res.writeHead(200, { 'Content-Type' : 'text/plain' });
res.end( 'Hello World\n' );
}).listen(1337, "127.0.0.1" );
console.log( 'Server running at http://127.0.0.1:1337/' );
|
这是NodeJS首页上的一段代码,我们注意看一下require
这个函数的用法,这里的代码需要http这个模块,因此就var http = require('http');
但是令我比较疑惑的就是明明require
函数是个异步的调用,因为http的模块文件不可能同步在这里堵塞加载执行(当然可能有人会说使用同步的AJAX请求,但是我们同样需要支持跨域问题),虽然这段代码是NodeJS的代码,其主要是运行在服务器端,使用V8引擎驱动,可以使用一些手段让requrie的模块同步加载执行,但是对于一个Web应用看到这样的代码一定会疑惑为什么这里不需要一个回调函数~好吧,就此认为这就是NodeJS在服务器端的神奇之处~~~那么继续看下面一段代码:
1
2
3
4
5
6
7
8
9
|
define( function (require, exports, module) {
// 获取依赖的模块:
var $ = require( 'jquery' );
// 向外提供接口:
exports.someMethod = someFunction;
}); |
这段代码是来自SeaJS首页的一段代码(额,我们的主角终于现身了~)这里再次出现了var $ = require('jquery');
这样一段 require 函数,这里同样会有刚刚上述的问题,明明是个异步的需求怎么在这里可以使用同步的写法呢?一种假设是 require 函数在这里已经事先准备好了 jquery 的对象(加载和执行 jquery.js ),但是这有什么策略么?不可能所有支持的模块都必须这样提前加载,况且以后根本无法方便扩展,添加自己的模块啊;第二种假设就是 jquery 对象真是在这里第一次出现,然后下载文件,执行文件的~但是据我所知,只能使用同步的 AJAX 才能做到这样,但是跨域的问题是最致命的问题,这里不可能没有处理啊??!!纠结啊,甚是纠结啊~一个require竟然有如此神奇的功力~
拨开 require 的神秘外衣
介于NodeJS的代码性质以及难度,这里暂时没有去研究其 require 的实现方法,限制着重谈谈SeaJS。关于SeaJS是什么,建议首先访问其网站,大致了解一下,在其中自然也提到了不少CommonJS的规范问题。
为了更好地探究这个神奇的require
函数,我首先从github上拉到了最新的SeaJS源代码。大致看下 seajs 代码执行后会产生些什么,如下图:
是的,没看错,seajs 这个对象暴露出来的接口就这么简单几个,但是不能仅仅因为暴露的接口简单精巧就忽视了其丰富的内涵。我们打开其源代码,大致看一下整个项目结构,这里主要把目光集中在 src 目录下:
文件命名主要是以 sea 开头的总引导文件以及 api 文件,fn 开头的辅助函数文件,util 开头的工具文件。通过 build.xml 可以了解整个SeaJS发布文件的构成方式。打开 sea.js 文件,可以看到刚刚我提到的辅助函数、工具在项目整个解构中都是以私有方式保存在暴露的 seajs 对象中,但是为什么实际看不到这些私有属性呢,愿意可以在 sea-api.js 中发现,具体看代码吧,这里不细说了~总的来说,整个 seajs 充分运用闭包的优势,把私有变量均保存在闭包中方便使用,在最终的 api 接口中删除暴露的私有属性接口,但是由于闭包特性,其内部值仍得以保留,这种方式个人感觉十分新颖,尤其实在做这样一个多文件项目时,在最终的 api 发布阶段再清除不必要的私有接口,既保证了开发时的灵活方便,又保证了数据的安全性。
好像越说离题越远,那现在回到神秘的 require 函数,那么这个接口是暴露的哪个内部辅助函数呢?看名字以为是在 fn-require.js 中,实则不然,我们再把眼光看远一些,原来 require 函数的最外层是一个 define 函数,那么打开 fn-define.js,代码看得云里来雾里去的,但是明确一下现在的目标时找到 require 相关的实现,但是首先,再岔开一下话题,看下 CommonJS 里面的这段规范说明 Modules/Wrappings,哈哈,说到的问题是不是正中下怀啊,正是我们现在关注的方向,继续看代码,注意到这样一个函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
deps = parseDependencies(factory.toString()); /* ------------------------------------------ */ function parseDependencies(code) {
var pattern = /\brequire\s*\(\s*[ '"]?([^' ")]*)/g;
var ret = [], match;
while ((match = pattern.exec(code))) {
if (match[1]) {
ret.push(match[1]);
}
}
return ret;
} |
哈,原来如此!define 函数中的倚赖关系(实际就是 require 函数的作用),是通过硬解析函数代码,观察其中 require 使用情况来决定的啊~虽然没有想象中的那么神奇,但是也是一种解决方案嘛,说到这里看看上马的假设,更符合假设一的情况,只是这里自然用不着全部加载其他模块,通过代码的“硬解析”来完成依赖需求,在 define 阶段即可有机会首先异步加载 require 的模块,然后当真正 require 时自然也就是同步方式了,这招还真是挺绝妙的啊~
好了,这次已经大致了解了SeaJS的一些基本情况了,也终于解惑了一个一直困扰我的问题,至于源代码的进一步分析和解读就等下次吧~
相关推荐
Seajs是中国开源社区推出的一款浏览器端的模块加载器,它借鉴了CommonJS的规范,但针对浏览器环境进行了优化,使得JavaScript在浏览器端也能实现模块化的开发。本教程将带你快速了解并掌握Seajs的使用,让你在5分钟...
SeaJS 是一款专为Web端设计的JavaScript模块加载器,它的出现是为了解决JavaScript在浏览器环境中的组织和管理问题。随着Web应用的复杂度不断提升,JavaScript代码的组织和依赖管理变得至关重要,SeaJS 提供了一种...
**Seajs 官方小实例详解** Seajs 是一个用于浏览器端的模块加载器,它遵循 CommonJS 规范,让 JavaScript 开发者能够在浏览器环境中实现模块化开发,提高代码的可维护性和复用性。Seajs 的核心理念是通过模块化解决...
Seajs是中国开源社区推出的一款基于模块化开发的前端加载器,它借鉴了CommonJS的模块化思想,但针对浏览器环境进行了优化。Seajs的核心理念是让JavaScript模块化变得简单,帮助开发者解决在大型Web项目中代码组织、...
Seajs是中国开源社区非常受欢迎的一款JavaScript模块加载器,它的出现为Web开发引入了CommonJS规范,使得前端开发更加模块化,便于代码管理和维护。Seajs 2.3.0是该库的一个稳定版本,提供了丰富的功能和优化。 一...
Seajs是中国开源社区发展出来的一款轻量级的前端模块化加载器,它的出现是为了应对JavaScript在浏览器端组织和管理代码的复杂性。本手册将详细阐述Seajs的核心概念、使用方法以及如何通过它来构建高效的前端应用。 ...
Seajs 是一个轻量级的前端模块加载器,它的出现是为了在浏览器端实现 CommonJS 规范,使得 JavaScript 的组织和开发变得更加模块化。Seajs 版本 2.3.0 是其稳定的一个版本,提供了更完善的特性和优化。 在...
Seajs-2.2.3 是一个开源的 JavaScript 模块加载器,旨在为开发者提供简单、极致的模块化开发体验。它强调的是简洁、自然的代码书写和组织方式,使得项目管理和协同工作变得更加高效。Seajs 在JavaScript社区中扮演着...
Seajs 是一个基于浏览器的模块加载器,它遵循 CommonJS 规范,使得在浏览器环境中可以实现模块化开发。这个“seajs入门完整案例”针对初学者提供了学习资源,帮助他们快速掌握Seajs的基本用法和特性。 1. **模块化...
Seajs是中国著名的前端模块加载器,它借鉴了CommonJS的规范,使得JavaScript在浏览器环境中也能实现模块化的开发。本文将深入解析Seajs 2.2.0版本的源码,探讨其核心机制、设计理念以及如何使用它来组织和管理前端...
**Seajs源码阅读** Seajs是一款轻量级的JavaScript模块加载器,它遵循CommonJS规范,使得在浏览器端也能实现模块化的开发。通过阅读Seajs的源码,我们可以深入理解JavaScript模块化的工作原理,以及如何实现一个...
Seajs是中国开源社区发展出来的一款模块化加载器,它的出现是为了应对JavaScript在浏览器环境中缺乏一个标准的模块化解决方案的问题。Seajs的设计理念是基于CMD(Common Module Definition)规范,它鼓励开发者采用...
CMD规范之Seajs Seajs是一款轻量级的前端模块加载器,它遵循CommonJS规范,使得JavaScript在浏览器端也能实现模块化的开发。这个规范主要包含模块定义、模块加载和模块化开发的思想,大大提高了代码的可维护性和...
SeaJS 是一个轻量级的前端模块加载器,它的出现是为了改善JavaScript在浏览器环境中的组织和加载方式。本文将深入探讨SeaJS的基本概念、工作原理以及如何通过一个完整的例子来理解其用法。 SeaJS的核心理念是遵循 ...
Seajs是一款轻量级的JavaScript模块加载器,它遵循CommonJS规范,旨在解决浏览器环境中的模块化问题。在深入理解seajs源代码之前,我们首先需要了解模块化的基本概念和CommonJS规范。 模块化是软件开发中的一种组织...
**SeaJS 和 RequireJS 是两种广泛使用的 JavaScript 模块加载器和依赖管理工具,它们的主要目的是解决 JavaScript 在浏览器端的异步加载和模块化问题。** **SeaJS** SeaJS 是一个轻量级的模块加载器,由中国淘宝...
"grunt-react-seajs"就是一个这样的工具,它是一个专门为前端开发者设计的Grunt插件,旨在帮助开发者将React组件转换为SeaJS模块,使得在不支持ES6模块语法的环境中也能顺利地使用React组件。下面我们将深入探讨这个...
【前端项目-seajs.zip】是一个包含前端开发工具的压缩包,主要关注的是Seajs模块加载器,这是一个专为Web设计的模块化解决方案。Seajs在前端开发领域扮演着重要角色,因为它提供了一种组织和管理JavaScript代码的...
seajs-css.js 用于seajs加载css文件,上课用的课件资源,大家有需要的可以随时下载。版本是非常好用的,作为一个学习模块化我们必须的知识插件
总的来说,"knockout seajs .net中实战应用"意味着在.NET开发中,利用Knockout.js的强大数据绑定能力和Sea.js的模块化管理,可以构建出高效、响应式的前端应用。通过Ajax通信,前端和后端能够无缝协作,提供流畅的...