Yabble入门 - 浏览器端CommonJS模块加载

时间:2011-03-09 18:29:40

标签: javascript node.js code-reuse commonjs

是否有人熟悉Yabble或其他浏览器端的CommonJS加载器?

我正在尝试使用Node.js,并且非常希望创建可在服务器端和客户端互换使用的Javascript模块。这可能最终成为一种“因为它太棒了”的事情,而不是“因为它是实用和有用的”。

因此,我基本上试图让CommonJS require()方法在浏览器端工作,这正是Yabble应该做的。我不知道从哪里开始。除了Yabble's Github readme中的内容之外,我似乎无法找到任何其他文档,而且这些文档没有多大帮助。

基本上我所做的就是将它放在HTML页面中......

<script src="yabble.js"></script>

<!-- Uses require -->
<script>
    require.setModuleRoot('http://localhost:8030/')
    my_module = require('my_module')
</script>

但是无论何时我调用require()函数,我都会抛出Synchronous require() is not supported.异常。

有人可以帮助我开始吗?我应该在哪里加载yabble.js我应该在哪里调用require?有没有一种特殊的方式来运行我的Javascript模块?

2 个答案:

答案 0 :(得分:6)

当加载需要在浏览器中使用require()函数的Javascript代码时,该代码的入口点必须是require.run()函数。

例如,好:

<script src="yabble.js"></script>

<script>
    require.setModuleRoot('http://localhost:8030/')
    require.run('my_module') // <-- Uses require() function somewhere
</script>

例如,Bad(会得到Synchronous require() is not supported错误):

<script src="yabble.js"></script>
<script src="http://localhost:8030/my_module.js"></script> <!-- <== Use's require function somewhere -->

仅供参考,Yabble如何做到这一点非常漂亮。它实际上将静态分析您的Javascript源代码,我认为基本上只是使用正则表达式来查找require()方法,然后尝试从服务器中提取.js脚本,然后它也会这样做对.js脚本进行静态分析,然后依次进行。

这可能特别令人困惑,因为它实际上会加载那些.js脚本,即使控制逻辑意味着程序流永远不会到达require()函数。例如,如果你有......

if (False) { require('some_module'); }

... Yabble将仍然加载此模块。

答案 1 :(得分:2)

浏览器中模块的同步加载存在问题。像:

这样的结构
var x = require('something_remote.js')

意味着浏览器将暂停您的代码(即阻止),转移并获取远程文件,解析它,然后返回导出。但这并不适用于单线程浏览器环境 - 我们将在网络性能上停止主JavaScript线程(以及用户的页面交互性)。因此,浏览器已经针对这种情况进行了演变,以支持按照自己的计划进行异步加载。这里有一些很好的讨论:

http://www.sitepen.com/blog/2010/07/16/asynchronous-commonjs-modules-for-the-browser-and-introducing-transporter/

这里可能有效的一种模式是require()实现同步阻塞,通过XHR获取文件然后逐出它,但这似乎针对基于异步文件的加载的所有浏览器支持/基础结构运行。此外,我很好奇对浏览器安全的跨域原语会产生什么影响。

因此,为了适应浏览器异步加载模型,我们需要使用如下的回调机制:

require("something.js", function () { // called later, after something.js has loaded! })

似乎RequireJS正在这样做:

http://requirejs.org/docs/start.html

或许可以试一试?

像NodeJS之类的JavaScript环境 - 通过从磁盘而不是外部网络主机加载“本地”模块而构建 - 可以进行同步加载。

我非常感谢JS专家的任何更正: - )