是否有人熟悉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模块?
答案 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线程(以及用户的页面交互性)。因此,浏览器已经针对这种情况进行了演变,以支持按照自己的计划进行异步加载。这里有一些很好的讨论:
这里可能有效的一种模式是require()实现同步阻塞,通过XHR获取文件然后逐出它,但这似乎针对基于异步文件的加载的所有浏览器支持/基础结构运行。此外,我很好奇对浏览器安全的跨域原语会产生什么影响。
因此,为了适应浏览器异步加载模型,我们需要使用如下的回调机制:
require("something.js", function () { // called later, after something.js has loaded! })
似乎RequireJS正在这样做:
http://requirejs.org/docs/start.html
或许可以试一试?
像NodeJS之类的JavaScript环境 - 通过从磁盘而不是外部网络主机加载“本地”模块而构建 - 可以进行同步加载。
我非常感谢JS专家的任何更正: - )