¿Cómo puedo compartir código entre Node.js y el navegador?

Resuelto Simon Cave asked hace 14 años • 16 respuestas

Estoy creando una pequeña aplicación con un cliente JavaScript (ejecutado en el navegador) y un servidor Node.js, comunicándome mediante WebSocket.

Me gustaría compartir código entre el cliente y el servidor. Recién comencé con Node.js y mi conocimiento del JavaScript moderno está un poco oxidado, por decir lo menos. Así que todavía estoy entendiendo la función require() de CommonJS. Si estoy creando mis paquetes usando el objeto 'exportar', entonces no veo cómo podría usar los mismos archivos JavaScript en el navegador.

Quiero crear un conjunto de métodos y clases que se utilicen en ambos extremos para facilitar la codificación y decodificación de mensajes y otras tareas reflejadas. Sin embargo, los sistemas de empaquetado Node.js/CommonJS parecen impedirme crear archivos JavaScript que puedan usarse en ambos lados.

También intenté usar JS.Class para obtener un modelo OO más estricto, pero lo dejé porque no podía entender cómo hacer que los archivos JavaScript proporcionados funcionaran con require(). ¿Hay algo que me falta aquí?

Simon Cave avatar Jul 12 '10 07:07 Simon Cave
Aceptado

Si desea escribir un módulo que pueda usarse tanto en el lado del cliente como en el del servidor, tengo una breve publicación en el blog sobre un método rápido y fácil: Escribir para Node.js y el navegador , esencialmente lo siguiente (donde thises lo mismo que window) :

(function(exports){

    // Your code goes here

   exports.test = function(){
        return 'hello world'
    };

})(typeof exports === 'undefined'? this['mymodule']={}: exports);

Alternativamente, hay algunos proyectos que apuntan a implementar la API de Node.js en el lado del cliente, como Gemini de Marak .

También podría interesarte DNode , que te permite exponer una función de JavaScript para que pueda llamarse desde otra máquina usando un protocolo de red simple basado en JSON.

Caolan avatar Jul 12 '2010 08:07 Caolan

Epeli tiene una buena solución aquí http://epeli.github.com/piler/ que incluso funciona sin la biblioteca, simplemente colóquela en un archivo llamado share.js

(function(exports){

  exports.test = function(){
       return 'This is a function from shared module';
  };

}(typeof exports === 'undefined' ? this.share = {} : exports));

En el lado del servidor simplemente use:

var share = require('./share.js');

share.test();

Y en el lado del cliente simplemente cargue el archivo js y luego use

share.test();
broesch avatar Dec 07 '2011 18:12 broesch

Consulte el código fuente de jQuery que hace que esto funcione en el patrón del módulo Node.js, el patrón del módulo AMD y global en el navegador:

(function(window){
    var jQuery = 'blah';

    if (typeof module === "object" && module && typeof module.exports === "object") {

        // Expose jQuery as module.exports in loaders that implement the Node
        // module pattern (including browserify). Do not create the global, since
        // the user will be storing it themselves locally, and globals are frowned
        // upon in the Node module world.
        module.exports = jQuery;
    }
    else {
        // Otherwise expose jQuery to the global object as usual
        window.jQuery = window.$ = jQuery;

        // Register as a named AMD module, since jQuery can be concatenated with other
        // files that may use define, but not via a proper concatenation script that
        // understands anonymous AMD modules. A named AMD is safest and most robust
        // way to register. Lowercase jquery is used because AMD module names are
        // derived from file names, and jQuery is normally delivered in a lowercase
        // file name. Do this after creating the global so that if an AMD module wants
        // to call noConflict to hide this version of jQuery, it will work.
        if (typeof define === "function" && define.amd) {
            define("jquery", [], function () { return jQuery; });
        }
    }
})(this)
wlingke avatar May 20 '2014 03:05 wlingke