我从这里获得了一些AMD / CommonJS适配器代码: supporting both CommonJS and AMD
(function (name, definition) {
if (typeof module != 'undefined') {
module.exports = definition();
}
else if (typeof define == 'function' && typeof define.amd == 'object') {
define(name, [], definition);
}
else {
this[name] = definition();
}
}('modXyz', {
sayHi:function (name) {
console.log('Hi ' + name + '!');
}
}
));
我想将该代码与Curl一起使用,以使我的所有代码与AMD / CommonJS兼容。我期待能够做到的是:
greeter = curl(['modXyz']);
greeter.sayHi("Gracie");
但是curl
返回的对象不是我期望的对象。我能得到的最接近的是:
curl(['modXyz'], function(mod) { window.greeter = mod; });
greeter.sayHi("Gracie");
这似乎打败了AMD的目的。 curl能做这样的事吗?我是否必须使用require.js来实现它?
答案 0 :(得分:1)
CurlJS和RequireJS都支持AMD AND CommonJS需要的呼叫模式:
CJS和AMD之间的区别在于使用Array作为依赖项列表的包装器。另请注意,在CurlJS的配置中,您可以将curl
别名为require
,以使您的代码与AMD规范完全兼容。观察:
CJS需要通话模式:
var a = require('name')
仅:CurlJS AMD需要呼叫模式:
var promise = require(['name'])
promise.then(callbackFunction)
这通常可以缩短为:
require(['name']).then(callbackFunction)
注意,CurlJS返回的Promise对象不是AMD规范的一部分。 AMD规范似乎没有规定AMD式要求呼叫的返回值。
两者,RequireJS和CurlJS都支持标准的AMD需要呼叫模式:
require(['name'], callbackFunction)
再次注意,使用Array作为这是AMD风格要求的标志。这会触发返回值的不同逻辑。
为了让你的东西按照自己的意愿工作,在CurlJS上,你的代码必须在一个被包装好的模块里面,就像它是一个CommonJS模块一样,使用:
define(function(require) { ... });
我被告知,在这种情况下,require
表现得像CommonJS样式require
- 同步。实际上,幕后发生的事情是加载程序扫描工厂函数以获取所需的内容,并将它们折叠到该定义的需求列表中。然后,在工厂内你可以做到:
var greeter = require('modXyz');
greeter.sayHi("Gracie");
注意,“同步”行为仍然是一种错觉,因为实际发生的是预先加载检测到的所需资源。
在RequireJS上,即使全局require
也可以称为CJS样式:var resource = require('resource/path')
,但只有 之后才能加载它。
换句话说,在工厂函数运行之前,加载总是在CurlJS和RequireJS中发生异步,但在RequireJS中你几乎可以在任何地方使用它,而在CurlJS中它是非常非常小的场景。
答案 1 :(得分:1)
因为浏览器远离其资源,所以它必须在获取这些资源时阻塞主线程,或者必须异步获取它们。由于我们永远不应该阻止主线程(有效地使浏览器无响应),我们必须获取资源异步。 (任何AMD加载器,RequireJS,dojo等都是一样的)
因此,以下内容无法正常工作:
var foo = require('lib/foo');
嗯,它可能无法在浏览器中常用的全局空间中工作。然而,可以在受控环境中工作,例如在AMD模块内部。
第1步:在模块中编写代码。
第2步:编写引导程序模块以启动应用程序。
<script src="lib/curl/src/curl.js"><script>
<script src="myapp/run.js"><script>
内部run.js:
// curl 0.7.x requires a named module here ('myapp/run')
define('myapp/run', ['curl'], function (curl) {
curl.config(
baseUrl: '',
packages: [ /* configure your 3rd-party packages */ ],
paths: { /* configure any non-package 3rd-party libs here */ },
preloads: [ /* put modules that *must* be loaded first here (e.g. shims) */ ],
main: 'myapp/main'
});
});
&#34; MyApp的/主&#34;可能看起来像这样:
define(function (require) {
var view1 = require('myapp/view1/controller');
view1.render();
view1.placeAt('body');
});
在主模块(或任何AMD模块)中,require
的行为更像我认为你期待的。请注意,这是一个特殊的AMD签名。您无法在define
中指定依赖关系,并期望require
的行为如下所示。您必须以单向 指定依赖项。这不起作用:
define(['myapp/view1'], function (view1) {
var foo = require('foo');
});
希望这会有所帮助。
- 约翰
答案 2 :(得分:0)
curl函数是异步的,并返回一个promise。因此,您只能将结果作为传递给curl的回调,或者传递给您的回调(一旦履行承诺就会调用。
curl(['dep1', 'dep2', 'dep3' /* etc */], callback);
或
curl(['dep1', 'dep2', 'dep3' /* etc */])
.then(callback, errorback);