作者:zccst
一、先来点最重要的
后端:CommonJS(原来叫ServerJS)
前端:RequireJS(AMD),Seajs(CMD)
CommonJS:JavaScript 并没有内置模块系统,CommonJS 致力于提高 JavaScript 程序的可移植性和可交换性,无论是在服务端还是浏览器端。
缺点:由于require是同步的。模块系统需要同步读取模块文件内容,并编译执行以得到模块接口。然而在浏览器端困难多多。因为script天生异步,传统CommonJS 模块在浏览器环境无法正常加载。
解决思路一:开发服务器端组件,对模块代码静态分析,将模块与它的依赖一起返回给浏览器端。
解决思路二:用一套标准模板来封装模块定义,这套模板代码为模块加载器提供了机会,使其能在模块代码之前,对模块代码进行静态分析,并动态生成依赖列表。(为了让静态分析可行,需要遵守一些简单的规则,即CMD规范)
Sea.js 的初衷是为了让 CommonJS Modules/1.1 的模块能运行在浏览器端,但由于浏览器和服务器的实质差异,实际上这个梦无法完全达成,也没有必要去达成。
更好的一种方式是,Sea.js 专注于 Web 浏览器端,CommonJS 则专注于服务器端,但两者有共通的部分。对于需要在两端都可以跑的模块,可以 有便捷的方案来快速迁移。
目前 Sea.js 的模块,如果没有用到浏览器环境下的特有属性,可以很方便跑在 NodeJS 端。只要在入口文件处,引入 Sea.js 的 Node.js 版本即可:
// 让 Node 环境可以加载执行 CMD 模块
require('seajs');
var a = require('./a');
这样,a.js 就可以是一个用 define 包裹起来的 CMD 模块了。
CommonJS 的模块需要跑在浏览器端时,通过简单封装就行:
a.js
define(function(require, exports, module) {
// a.js 原来的代码
});
这样 a.js 就可以在浏览器端通过 Sea.js 加载运行。当然前提是 a.js 没有利用到服务器特有属性和模块,比如 __dirname、process 等。
通过上面的方案,我们就实现了 CommonJS 与 Sea.js 两个生态圈的融合,可以彼此互通,让我们书写的 JavaScript 模块可移植,可在不同平台上运行。
二、seajs的历史
https://github.com/seajs/seajs/issues/588
大概 09 年 - 10 年期间,CommonJS 社区大牛云集。CommonJS 原来叫 ServerJS,推出 Modules/1.0 规范后,在 Node.js 等环境下取得了很不错的实践。
09年下半年这帮充满干劲的小伙子们想把 ServerJS 的成功经验进一步推广到浏览器端,于是将社区改名叫 CommonJS,同时激烈争论 Modules 的下一版规范。分歧和冲突由此诞生,逐步形成了三大流派:
Modules/1.x 流派。这个观点觉得 1.x 规范已经够用,只要移植到浏览器端就好。要做的是新增 Modules/Transport (传输 There are a variety of ways to transport a module from a server to a browser.) 规范,即在浏览器上运行前,先通过转换工具将模块转换为符合 Transport 规范的代码。主流代表是服务端的开发人员。现在值得关注的有两个实现:越来越火的 component 和走在前沿的 es6 module transpiler。
Modules/Async 流派。这个观点觉得浏览器有自身的特征,不应该直接用 Modules/1.x 规范。这个观点下的典型代表是 AMD 规范及其实现 RequireJS。这个稍后再细说。
Modules/2.0 流派。这个观点觉得浏览器有自身的特征,不应该直接用 Modules/1.x 规范,但应该尽可能与 Modules/1.x 规范保持一致。这个观点下的典型代表是 BravoJS 和 FlyScript 的作者。BravoJS 作者对 CommonJS 的社区的贡献很大,这份 Modules/2.0-draft 规范花了很多心思。FlyScript 的作者提出了 Modules/Wrappings 规范,这规范是 CMD 规范的前身。可惜的是 BravoJS 太学院派,FlyScript 后来做了自我阉割,将整个网站(flyscript.org)下线了。这个故事有点悲壮,下文细说。
三、seajs与nodejs
原文:
https://github.com/seajs/seajs/issues/275
1,让 Sea.js 的模块跑在 Node 上
首先 $npm install seajs -g
然后,在需要调用seajs模块的入口文件里,require下seajs
a.js
define(function(require, module, exports){
exports.name = "A";
});
main.js
require("seajs");
var a = require("./a");
console.log(a.name);
最后,运行 $node main.js
#打印 A
2,让 node 模块跑在浏览器端
这个也很简单,将 Node 的模块封装成 CMD 模块即可:
a.js
exports.name = 'A';
封装成
define(function(require, exports) {
exports.name = 'A';
});
这样在浏览器端就可以通过 Sea.js 来加载使用了:
seajs.use('./a', function(a) {
console.log(a.name);
});
3,通用的前提条件
通过上面的例子可以看出,只要遵循 CMD 规范来书写模块代码,就可以非常方便的同时运行在浏览器端和服务器端。这是 CMD 中 C 字母的含义:Common(通用)。
这比 RequireJS 的 AMD 规范好很多。
但是,无论是 CMD 还是 AMD 规范,或者是未来的某个 Modules/Cool 规范,一个模块要想同时在不同环境下执行,就得遵循以下前提条件:
不能调用浏览器端的私有特性。比如 attachEvent 之类的,除非你在 Node 端提前模拟好。
不能调用服务器端的私有特性。比如 process 对象,除非你在浏览器端自己实现一个类似的 process 对象。
只用不同规范中的交集。比如 CMD 中有 module.uri 属性,但 Node 中没有,要通用,就不能去调用这些有差异的接口。类似的,Node 端的 __filename 在浏览器端不存在,要通用的话,也不能调用。
其实上面这些严格要求,是 非常自然的。这就如浏览器兼容一样,要写出所有浏览器下都能跑的代码,最好的方式是只用那些所有浏览器都支持的特性,不然你就得用 if ... else ... 去搞啦。
4,附录 Node.js 与 Sea.js 在模块接口上的主要差异如下:
Node.js 里,模块文件里的 this === module.exports;Sea.js 里,this === window。
Node.js 里,模块文件里的 return xx 会被忽略;Sea.js 里,return xx 等价 module.exports = xx。
Node.js 里,require 是懒加载 + 懒执行的。在 Sea.js 里是提前加载好 + 懒执行。
Sea.js 里,require(id) 中的 id 必须是字符串直接量。Node.js 里没这个限制。
四、seajs与requireJS
相同:
RequireJS 和 Sea.js 都是模块加载器,倡导模块化开发理念,核心价值是让 JavaScript 的模块化开发变得简单自然。
不同之处 两者的主要区别如下:
定位有差异。RequireJS 想成为浏览器端的模块加载器,同时也想成为 Rhino / Node 等环境的模块加载器。Sea.js 则专注于 Web 浏览器端,同时通过 Node 扩展的方式可以很方便跑在 Node 环境中。
遵循的规范不同。RequireJS 遵循 AMD(异步模块定义)规范,Sea.js 遵循 CMD (通用模块定义)规范。规范的不同,导致了两者 API 不同。Sea.js 更贴近 CommonJS Modules/1.1 和 Node Modules 规范。
推广理念有差异。RequireJS 在尝试让第三方类库修改自身来支持 RequireJS,目前只有少数社区采纳。Sea.js 不强推,采用自主封装的方式来“海纳百川”,目前已有较成熟的封装策略。
对开发调试的支持有差异。Sea.js 非常关注代码的开发调试,有 nocache、debug 等用于调试的插件。RequireJS 无这方面的明显支持。
插件机制不同。RequireJS 采取的是在源码中预留接口的形式,插件类型比较单一。Sea.js 采取的是通用事件机制,插件类型更丰富。
还有不少差异,涉及具体使用方式和源码实现,欢迎有兴趣者研究并发表看法。
总之,如果说 RequireJS 是 Prototype 类库的话,则 Sea.js 致力于成为 jQuery 类库。
如果您觉得本文的内容对您的学习有所帮助,您可以微信:
分享到:
相关推荐
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源码阅读** Seajs是一款轻量级的JavaScript模块加载器,它遵循CommonJS规范,使得在浏览器端也能实现模块化的开发。通过阅读Seajs的源码,我们可以深入理解JavaScript模块化的工作原理,以及如何实现一个...
Seajs是中国著名的前端模块加载器,它借鉴了CommonJS的规范,使得JavaScript在浏览器环境中也能实现模块化的开发。本文将深入解析Seajs 2.2.0版本的源码,探讨其核心机制、设计理念以及如何使用它来组织和管理前端...
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通信,前端和后端能够无缝协作,提供流畅的...