Cómo escribir un módulo que funcione con Node.js, RequireJS y sin ellos

Estoy trabajando en una biblioteca de JavaScript paraProcesamiento JSON / XML. Mi biblioteca funciona tanto en el navegador como en Node.js (conxmldom yxmlhttprequest módulos).

Uno de los usuarios solicitó recientemente el soporte de RequireJS. He echado un vistazo a la cosa RequireJS / AMD y creo que es un buen enfoque, así que me gustaría proporcionar esto.

Sin embargo, me gustaría conservar la portabilidad: mi biblioteca debe funcionar en navegadores (con y sin RequireJS) así como en Node.js. Y en el entorno del navegador no dependo dexmldom oxmlhttprequest ya que estas cosas son proporcionadas por el navegador mismo.

Mi pregunta es: ¿cómo puedo implementar mi biblioteca para que funcione tanto en los navegadores como en Node.js con y sin RequireJS?

Un poco de historia y mi solución actual

Inicialmente escribí mi biblioteca para navegadores. Por lo tanto, acaba de crear un objeto de alcance global y poner todo dentro de él:

var Jsonix = { ... };

Más tarde, los usuarios solicitaron el soporte de Node.js. Entonces agregué:

if(typeof require === 'function'){
    module.exports.Jsonix = Jsonix;
}

También tuve que importar algunos módulos mencionados anteriormente. Lo hice condicionalmente, dependiendo de si elrequire la función está disponible o no:

if (typeof require === 'function')
{
    var XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest;
    return new XMLHttpRequest();
}

Ahora hay esta historia con RequireJS. Si RequireJS está presente, entonces elrequire La función también está presente. Pero la carga del módulo funciona de manera diferente, tengo que usar eldefine función, etc. Tampoco puedo simplementerequire cosas desderequire tiene una API asíncrona en RequireJS. Además, si mi biblioteca se carga a través de RequireJS, parece procesar el código fuente y detectarequire('something') incluso si lo hago condicionalmente como

if (typeof require === 'function' && typeof require.specified !== 'function) ...

RequireJS todavía detectarequire('xmlhttprequest') An intenta cargar el archivo JS correspondiente.

Actualmente estoy llegando a la siguiente solución.

// 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();
}

Y así es como verifico las dependencias ahora:

if (typeof _jsonix_xmlhttprequest !== 'undefined')
{
    var XMLHttpRequest = _jsonix_xmlhttprequest.XMLHttpRequest;
    return new XMLHttpRequest();
}

Si tengorequire pero nodefine entonces supongo que este es un entorno Node.js. yo sueloamdefine para definir el módulo y pasar las dependencias requeridas.

Si tengorequire ydefine supongo que este es un entorno RequireJS, así que solo uso eldefine función. Actualmente también supongo que este es un entorno de navegador, por lo que dependencias comoxmldom yxmlhttprequest no están disponibles y no los requieren. (Esto probablemente no sea correcto).

Si no tengo elrequire funciono, entonces supongo que este es un entorno de navegador sin el soporte de RequireJS / AMD, así que invoco la fábrica de módulos_jsonix directamente y exportar el resultado como un objeto global.

Entonces, este es mi enfoque hasta ahora. Me parece un poco incómodo y, como novato en RequireJS / AMD, estoy buscando asesoramiento. ¿Es el enfoque correcto? ¿Hay mejores formas de abordar el problema? Agradecería tu ayuda.

Respuestas a la pregunta(3)

Su respuesta a la pregunta