C贸mo usar module.exports en Node.js

    El uso de m贸dulos es una parte esencial de la creaci贸n de aplicaciones y sistemas de software completos con Node.js. En ausencia de m贸dulos, su c贸digo estar铆a fragmentado y ser铆a dif铆cil de ejecutar, y mucho menos mantenerlo con el tiempo. Pero, 驴qu茅 es un m贸dulo? 驴Y c贸mo se supone que debes usar module.exports para construir sus programas Node.js?

    Un m贸dulo es un programa discreto, contenido en un solo archivo en Node.js. Por lo tanto, los m贸dulos est谩n vinculados a archivos, con un m贸dulo por archivo. Los m贸dulos est谩n disponibles en otros lenguajes de programaci贸n. Node.JS usa el sistema de m贸dulos CommonJS, pero hay otros tipos de m贸dulos usados 鈥嬧媏n el ecosistema JavaScript. Los m谩s destacados de estos otros sistemas de m贸dulos son los sistemas de m贸dulo Asynchronous Module Definition (AMD) y (ECMAScript 6) ES6.

    Como veremos, module.exports es un objeto que el m贸dulo actual devuelve cuando es “requerido” en otro programa o m贸dulo.

    Puede incluir funcionalidad de otros m贸dulos en cualquier otro m贸dulo. Hacerlo se conoce como “requerir” el m贸dulo, que simplemente requiere un determinado objeto especial que representa la funcionalidad del m贸dulo.

    Compartiendo c贸digo con module.exports

    Para el uso diario, los m贸dulos nos permiten componer programas m谩s grandes a partir de piezas m谩s peque帽as. M贸dulos se convierten en los bloques de construcci贸n b谩sicos de la pieza de software m谩s grande que, colectivamente, definen.

    Debajo de las cubiertas, el m贸dulo se rastrea a s铆 mismo a trav茅s de un objeto llamado module. Dentro de cada m贸dulo, por lo tanto, “m贸dulo” se refiere al objeto que representa el m贸dulo actual. Este objeto contiene metadatos sobre el m贸dulo, como el nombre de archivo del m贸dulo, as铆 como la identificaci贸n del m贸dulo.

    Aqu铆 hay un peque帽o fragmento de c贸digo que puede ejecutar para ver los valores de estas propiedades de ejemplo en un m贸dulo:

    // module1.js
    
    console.log(module.filename);
    console.log(module.id);
    console.log(module.exports);
    

    Puedes ejecutar esto usando el comando node module1.js. Ver谩, por ejemplo, que el module.filename La propiedad se establece en una ruta de archivo que termina con el nombre correcto del archivo en el que existe este m贸dulo, que es module1.js. Aqu铆 hay un resultado de ejemplo para el c贸digo anterior:

    $ node module1.js
    /Users/scott/projects/sandbox/javascript/module-test/module1.js
    .
    {}
    

    En Node.js, la pr谩ctica de hacer que el c贸digo de un m贸dulo est茅 disponible para que lo usen otros m贸dulos se denomina “exportar” valores.

    Pero si se va a construir una pieza de software complejo a partir de m贸dulos individuales, es posible que ya est茅 pensando en las siguientes preguntas:

    Pregunta importante n. 掳 1: 驴C贸mo identifica Node.js el m贸dulo “principal” para comenzar a ejecutar el programa?

    Node.js identifica el m贸dulo principal a ejecutar por los argumentos que se pasan al node ejecutable. Por ejemplo, si tenemos un m贸dulo contenido en el archivo server.js, junto con otras partes de nuestro programa contenidas en archivos login.js y music_stream.js, invocando el comando node server.js identifica el servidor m贸dulo como el principal. Ese m贸dulo principal, a su vez, solicitar谩 la funcionalidad de los otros m贸dulos “requiri茅ndolos”.

    Pregunta importante n. 掳 2: 驴C贸mo comparte un m贸dulo su c贸digo con otros m贸dulos?

    los module El objeto tiene una propiedad especial, llamada exports, que es responsable de definir lo que un m贸dulo pone a disposici贸n para que lo utilicen otros m贸dulos. En la terminolog铆a de Node.js, module.exports define los valores que exporta el m贸dulo. Recuerde que “exportar” es simplemente hacer que los objetos o valores est茅n disponibles para que otros m贸dulos los importen y usen.

    Por lo tanto, podemos exportar cualquier valor o funci贸n u otro objeto que nos gustar铆a exportar adjunt谩ndolo como una propiedad del module.exports objeto. Por ejemplo, si quisi茅ramos exportar una variable llamada temperature, podr铆amos ponerlo a disposici贸n para su uso fuera del m贸dulo simplemente agreg谩ndolo como una nueva propiedad de module.exports como sigue:

    module.exports.temperature = temperature; 
    

    Exportaci贸n y solicitud de funciones y variables con module.exports

    Ahora que hemos visto el significado conceptual de un m贸dulo, as铆 como por qu茅 usamos m贸dulos, pongamos en pr谩ctica estas ideas creando un m贸dulo, definiendo funciones y luego exportando esas funciones para que puedan ser utilizadas por otros m贸dulos.

    Como ejemplo, aqu铆 hay un nuevo m贸dulo que brinda recomendaciones de libros. En el siguiente c贸digo, he definido una variable y algunas funciones. Posteriormente, accederemos a la funcionalidad de estas recomendaciones de libros desde otro m贸dulo.

    // book_recommendations.js
    
    // stores the favorite author in a constant variable
    const favoriteAuthor = { name: "Ken Bruen", genre: "Noir", nationality: "Irish" };
    
    // returns the favorite book
    function favoriteBook() {
        return { title: "The Guards", author: "Ken Bruen" };
    }
     
    // returns a list of good books
    function getBookRecommendations() {
        return [
            {id: 1, title: "The Guards", author: "Ken Bruen"},
            {id: 2, title: "The Stand", author: "Steven King"},
            {id: 3, title: "The Postman Always Rings Twice", author: "James M. Cain"}
        ];
    }
     
    // exports the variables and functions above so that other modules can use them
    module.exports.favoriteAuthor = favoriteAuthor;
    module.exports.favoriteBook = favoriteBook;
    module.exports.getBookRecommendations = getBookRecommendations;
    

    Hemos agregado todas las variables y funciones a las que nos gustar铆a exportar module.exports como propiedades del objeto. Acabamos de lograr nuestro objetivo de exportar estas funciones y variables desde el book_recommendations m贸dulo.

    Ahora veamos c贸mo podr铆amos importar este m贸dulo y acceder a su funcionalidad desde otro m贸dulo.

    Para importar el m贸dulo, necesitamos usar una palabra clave especial que se usa para importar cosas, y se llama exigir. D贸nde module.exports vamos a configurar las cosas para la exportaci贸n, require nos permite especificar los m贸dulos que se importar谩n al m贸dulo actual.

    La funcionalidad para importar m贸dulos se proporciona en un m贸dulo llamado require, disponible en el 谩mbito global. La exportaci贸n principal de este m贸dulo es una funci贸n a la que pasamos la ruta del m贸dulo que nos gustar铆a importar. Por ejemplo, para importar un m贸dulo definido en music.js, lo har铆amos require('./music'), donde hemos especificado la ruta relativa.

    Ahora podemos ver lo f谩cil que es importar cualquier cosa usando require. Volviendo a nuestro book_recommendations m贸dulo, podemos importarlo y acceder a las funciones que exporta. Esto se muestra en la siguiente lista de c贸digos. Este m贸dulo imprime un mensaje que describe los regalos de cumplea帽os recomendados. Obtiene libros recomendados del m贸dulo de recomendaciones de libros importados y los combina con recomendaciones musicales.

    Cree un nuevo m贸dulo como se muestra a continuaci贸n, luego ejec煤telo como se mostr贸 anteriormente para verlo usando las funciones definidas en el importado book_recommendations m贸dulo.

    // birthday_gifts.js
    
    // import the book recommendations module
    let books = require('./book_recommendations');
    
    // gets some music recommendations as well
    let musicAlbums = [
        { artist: "The Killers", title: "Live From The Royal Albert Hall" },
        { artist: "Eminem", title: "The Marshall Mathers LP" }
    ];
    
    // the two best items from each category
    let topIdeas = function() {
        return [musicAlbums[0], books.favoriteBook()];
    }
     
    // outputs a message specifying the customer's recommended gifting items
    let gifts = function() {
        console.log("Your recommended gifts are:n");
        console.log("######MUSIC######");
    
        for (let i = 0, len = musicAlbums.length; i < len; i++) {
            console.log(musicAlbums[i].title + " by " + musicAlbums[i].artist);
        }
    
        console.log("######BOOKS######");
    
        let recommendedBooks = books.getBookRecommendations();
    
        for (let i = 0, len = recommendedBooks.length; i < len; i++) {
            console.log(recommendedBooks[i].title + " by " + recommendedBooks[i].author);
        }
    
        console.log("nnYours");
        console.log("Shop Staffn*************");
        console.log("P.S. If you have a limited budget, you should just get the music album " + topIdeas()[0].title + " and the book " + topIdeas()[1].title + ".");
    }
    
    console.log("Welcome to our gift shop.n");
    
    // Get the gifts
    gifts();
    

    Como puede ver, usamos require para importar el book_recommendations m贸dulo. Dentro del nuevo m贸dulo, pudimos acceder a variables y funciones que se hab铆an exportado agreg谩ndolas a module.exports.

    Con ambos m贸dulos completos, invocando node birthday_gifts.js imprime un mensaje ordenado con las recomendaciones completas de regalos del cliente. Puedes ver el resultado en la siguiente imagen.

    Welcome to our gift shop.
    
    Your recommended gifts are:
    
    ######MUSIC######
    Live From The Royal Albert Hall by The Killers
    The Marshall Mathers LP by Eminem
    ######BOOKS######
    The Guards by Ken Bruen
    The Stand by Steven King
    The Postman Always Rings Twice by James M. Cain
    
    
    Yours
    Shop Staff
    *************
    P.S. If you have a limited budget, you should just get the music album Live From The Royal Albert Hall and the book The Guards.
    

    Este patr贸n de componer programas Node.js a partir de m贸dulos m谩s peque帽os es algo que ver谩 a menudo, como con el middleware Express, por ejemplo.

    Exportar y requerir clases con module.exports

    Adem谩s de funciones y variables, tambi茅n podemos usar module.exports para exportar otros objetos complejos, como clases. Si no est谩 familiarizado con el uso de clases u otros fundamentos de Node.js, puede echar un vistazo a nuestra gu铆a de Node.js para principiantes.

    En el siguiente ejemplo, creamos una clase Cat que contiene un nombre y una edad para los objetos Cat. Luego exportamos la clase Cat adjunt谩ndola como una propiedad del module.exports objeto. Como puede ver, esto no es tan diferente de c贸mo export谩bamos funciones y variables antes.

    // cat.js
    
    // constructor function for the Cat class
    function Cat(name) {
        this.age = 0;
        this.name = name;
    }
     
    // now we export the class, so other modules can create Cat objects
    module.exports = {
        Cat: Cat
    }
    

    Ahora podemos acceder a esta clase Cat importando el cat m贸dulo. Una vez hecho esto, podemos crear nuevos objetos Cat y usarlos en el m贸dulo de importaci贸n como se muestra en el siguiente ejemplo. Nuevamente, deber铆a intentar ejecutar este c贸digo con node cat_school.js para ver los nombres y edades de los nuevos gatos en el s铆mbolo del sistema.

    // cat_school.js
    
    // import the cat module
    let cats = require('./cat');
    let Cat = cats.Cat;
    
    // creates some cats
    let cat1 = new Cat("Manny");
    let cat2 = new Cat("Lizzie");
    
    // Let's find out the names and ages of cats in the class
    console.log("There are two cats in the class, " + cat1.name + " and " + cat2.name + ".");
    console.log("Manny is " + cat1.age + " years old " +  " and Lizzie is " + cat2.age + " years old.");
    

    Como acabamos de ver, se puede exportar una clase adjuntando la clase como una propiedad de la module.exports objeto. Primero, creamos una clase usando una funci贸n constructora. Luego exportamos la clase usando module.exports. Para usar la clase, la solicitamos en otro m贸dulo y luego creamos instancias de la clase.

    Para ver un ejemplo de la exportaci贸n de una clase que se cre贸 con la sintaxis de ES6, consulte la Book clase a continuaci贸n.

    Una alternativa: usar el m贸dulo VS de exportaciones taquigr谩ficas.

    Si bien podemos seguir asignando cosas para exportar como propiedades de module.exports, existe una forma abreviada de exportar cosas desde el m贸dulo. Esta forma abreviada implica usar solo exports en vez de module.exports. Hay algunos diferencias entre los dos. Sin embargo, la clave a notar aqu铆 es que debe asigne sus nuevos valores como propiedades del acceso directo export objeto, y no asignar objetos directamente para sobrescribir el valor de export s铆 mismo.

    Aqu铆 hay un ejemplo en el que utilizo esta forma abreviada de exportar un par de objetos de un m贸dulo llamado escuela de Cine.

    // film_school.js
    
    // a beginner film course
    let film101 = {
        professor: 'Mr Caruthers',
        numberOfStudents: 20,
        level: 'easy'
    }
     
    // an expert film course
    let film102 = {
        professor: 'Mrs Duguid',
        numberOfStudents: 8,
        level: 'challenging' 
    }
     
    // export the courses so other modules can use them
    exports.film101 = film101;
    exports.film102 = film102;
    

    Observe c贸mo estamos asignando los objetos como, por ejemplo, exports.film101 = ... en vez de exports = film101. Esa asignaci贸n posterior no exportar铆a la variable, sino que estropear铆a por completo las exportaciones de atajos.

    La exportaci贸n realizada de la forma abreviada anterior, podr铆a haberse logrado en la forma larga que hemos utilizado con module.exports utilizando las siguientes l铆neas para la exportaci贸n.

    // export the courses so other modules can use them
    module.exports.film101 = film101;
    module.exports.film102 = film102;
    

    Tambi茅n podr铆amos exportar los dos objetos asignando un objeto directamente a module.exports pero esto no funcionar铆a con exports.

    // export the courses so other modules can use them
    module.exports = {
        film101: film101,
        film102: film102
    }
    

    Los dos son muy similares, y con raz贸n. Estas son dos formas de lograr lo mismo, pero exports puede hacerle tropezar si asigna un objeto a las exportaciones de la forma en que lo asignar铆a a module.exports.

    Diferencias entre los m贸dulos Node.js y los m贸dulos ES6

    Los m贸dulos utilizados en Node.js siguen una especificaci贸n de m贸dulo conocida como CommonJS especificaci贸n. Las actualizaciones recientes del lenguaje de programaci贸n JavaScript, en forma de ES6, especifican cambios en el lenguaje, agregando cosas como una nueva sintaxis de clase y una sistema de m贸dulo. Este sistema de m贸dulos es diferente de los m贸dulos de Node.js. Un m贸dulo en ES6 se parece a lo siguiente:

    // book.js
    const favoriteBook = {
        title: "The Guards",
        author: "Ken Bruen"
    }
    
    // a Book class using ES6 class syntax
    class Book {
        constructor(title, author) {
            this.title = title;
            this.author = author;
        }
    
        describeBook() {
            let description = this.title + " by " + this.author + ".";
            return description;
        }
    }
    
    // exporting looks different from Node.js but is almost as simple
    export {favoriteBook, Book};
    

    Para importar este m贸dulo, usar铆amos el ES6 import funcionalidad, como sigue.

    // library.js
    
    // import the book module
    import {favoriteBook, Book} from 'book';
    
    // create some books and get their descriptions
    let booksILike = [
        new Book("Under The Dome", "Steven King"),
        new Book("Julius Ceasar", "William Shakespeare")
    ];
    
    console.log("My favorite book is " + favoriteBook + ".");
    console.log("I also like " + booksILike[0].describeBook() + " and " + booksILike[1].describeBook());
    

    Los m贸dulos de ES6 parecen casi tan simples como los m贸dulos que hemos usado en Node.js, pero son incompatibles con los m贸dulos de Node.js. Esto tiene que ver con la forma en que los m贸dulos se cargan de manera diferente entre los dos formatos. Si usa un compilador como Babel, puede mezclar y combinar formatos de m贸dulo. Sin embargo, si tiene la intenci贸n de codificar en el servidor solo con Node.js, puede ce帽irse al formato del m贸dulo para Node.js que cubrimos anteriormente.

    Aprende m谩s

    驴Quiere obtener m谩s informaci贸n sobre los fundamentos de Node.js? Personalmente, recomendar铆a un curso en l铆nea, como Aprender Node.js de Wes Bos ya que los videos son mucho m谩s f谩ciles de seguir y podr谩s crear una aplicaci贸n para el mundo real.

    Conclusi贸n

    El uso de module.exports nos permite exportar valores, objetos y estilos desde los m贸dulos de Node.js. Junto con el uso de require Para importar otros m贸dulos, tenemos un ecosistema completo para componer grandes programas a partir de partes m谩s peque帽as. Cuando combinamos varios m贸dulos que se ocupan de partes 煤nicas de la funcionalidad, podemos crear aplicaciones y sistemas de software m谩s grandes, m谩s 煤tiles, pero f谩ciles de mantener.

     

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *