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 ​​en 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 *