我正在开发一个JavaScript库,用于JSON/XML处理。我的库可以在浏览器和Node.js中使用(使用
最近,有一位用户要求添加RequireJS支持。我查看了RequireJS/AMD的相关内容,并认为这是一个很好的方法,因此我想提供此功能。
然而,我希望保留可移植性:我的库必须在浏览器中工作(有或没有RequireJS),以及在Node.js中工作。在浏览器环境中,我不依赖于
我最初为浏览器编写了我的库。所以它只是创建了一个全局对象,并将所有内容放在其中:
现在有一个关于RequireJS的故事。如果存在RequireJS,则
如果我有
如果我有
如果我没有
所以,这是我的方法。对我来说似乎有点笨拙,作为RequireJS / AMD的新手,我正在寻求建议。这是正确的方法吗?有更好的方法来解决问题吗?感谢您的帮助。
xmldom
和xmlhttprequest
模块)。最近,有一位用户要求添加RequireJS支持。我查看了RequireJS/AMD的相关内容,并认为这是一个很好的方法,因此我想提供此功能。
然而,我希望保留可移植性:我的库必须在浏览器中工作(有或没有RequireJS),以及在Node.js中工作。在浏览器环境中,我不依赖于
xmldom
或xmlhttprequest
,因为这些功能由浏览器本身提供。
我的问题是:如何实现我的库,使其可以在浏览器和Node.js中使用,无论是否使用RequireJS?
一点历史和我的当前解决方案我最初为浏览器编写了我的库。所以它只是创建了一个全局对象,并将所有内容放在其中:
var Jsonix = { ... };
后来用户要求添加对Node.js的支持。因此我添加了:
if(typeof require === 'function'){
module.exports.Jsonix = Jsonix;
}
我还需要导入一些上述提到的模块。我根据require
函数是否可用进行条件导入:
if (typeof require === 'function')
{
var XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest;
return new XMLHttpRequest();
}
现在有一个关于RequireJS的故事。如果存在RequireJS,则
require
函数也存在。但是模块加载方式不同,我必须使用define
函数等。我也不能只是require
一些东西,因为require
在RequireJS中具有异步API。此外,如果我的库通过RequireJS加载,它似乎会处理源代码并检测require('something')
,即使我按条件执行。if (typeof require === 'function' && typeof require.specified !== 'function) ...
RequireJS仍然会检测require('xmlhttprequest')
并尝试加载相应的JS文件。
目前,我采用以下解决方案。
// Module factory function, AMD style
var _jsonix = function(_jsonix_xmldom, _jsonix_xmlhttprequest, _jsonix_fs)
{
// Complete Jsonix script is included below
var Jsonix = { ... };
// Complete Jsonix script is included above
return { Jsonix: Jsonix };
};
// If require function exists ...
if (typeof require === 'function') {
// ... but define function does not exists, assume we're in the Node.js environment
// In this case, load the define function via amdefine
if (typeof define !== 'function') {
var define = require('amdefine')(module);
define(["xmldom", "xmlhttprequest", "fs"], _jsonix);
}
else {
// Otherwise assume we're in the RequireJS environment
define([], _jsonix);
}
}
// Since require function does not exists,
// assume we're neither in Node.js nor in RequireJS environment
// This is probably a browser environment
else
{
// Call the module factory directly
var Jsonix = _jsonix();
}
现在我是这样检查依赖关系的:
if (typeof _jsonix_xmlhttprequest !== 'undefined')
{
var XMLHttpRequest = _jsonix_xmlhttprequest.XMLHttpRequest;
return new XMLHttpRequest();
}
如果我有
require
但没有define
,那么我假设这是一个Node.js环境。我使用amdefine
来定义模块并传递所需的依赖项。如果我有
require
和define
,那么我假设这是一个RequireJS环境,因此我只需使用define
函数。目前,我还假设这是一个浏览器环境,因此像xmldom
和xmlhttprequest
这样的依赖项不可用,也不需要它们。(这可能是不正确的。)如果我没有
require
函数,则我假设这是一个不支持RequireJS / AMD的浏览器环境,因此直接调用模块工厂_jsonix
并将结果导出为全局对象。所以,这是我的方法。对我来说似乎有点笨拙,作为RequireJS / AMD的新手,我正在寻求建议。这是正确的方法吗?有更好的方法来解决问题吗?感谢您的帮助。