Fuente validada
Lab_20_NodeJS_Copilot.docx
Esta pagina fue reconstruida desde el documento del ZIP entregado como fuente principal.
Laboratorio 20
Este laboratorio es para ayudar a entender el proyecto Demo para gestionar laboratorios que evalúen la viabilidad de Copilot.
Fuente validada
Esta pagina fue reconstruida desde el documento del ZIP entregado como fuente principal.
Conformidad visual
El archivo fuente contiene 0 imagenes embebidas. Para garantizar conformidad, no se publican imagenes heredadas de otros materiales.
Criterio GH-300
Ejecuta los comandos, captura evidencia propia y valida cada sugerencia de Copilot antes de aceptarla.
Certificación GH-300
Activar GitHub Copilot usando Node.js
Autor: Carlos Crudo
linkedin.com/in/carloscrudo
Uso de GitHub Copilot integrado en un proyecto Node.js completo: generación de código, tests, documentación y optimización de aplicaciones JavaScript/TypeScript.
Temas que cubre este laboratorio:
Node.js + GitHub Copilot setup
Generación de funciones y módulos
Express.js endpoints con Copilot
Tests con Jest usando Copilot Chat
Copilot para refactoring JS/TS
npm scripts y automatización
Este laboratorio es para ayudar a entender el proyecto Demo para gestionar laboratorios que evalúen la viabilidad de Copilot.
Antes de ejecutar este laboratorio, instalemos primero los paquetes de software necesarios y configuremos el entorno.
Necesitas descargar e instalar los siguientes paquetes de software para configurar el entorno que ejecute este laboratorio.
Abre el navegador de Edge.
En el campo URL del navegador, copia y pega el enlace para descargar los paquetes de software en la máquina virtual de tu laboratorio.
Ve a la carpeta Descargas (C:\Usuarios\Admin\Descargas) y haz doble clic node-v20.16.0-x64.msi.
En la ventana de "asistente de configuración de Node.js" haz clic en Siguiente.
Acepta el EULA y haz clic en Siguiente.
Mantén la carpeta de destino predeterminada y luego haz clic en Siguiente.
Haz clic en Añadir al CAMINO y luego en Siguiente.
En la ventana de Herramientas para Módulos nativos, selecciona la casilla y haz clic en Siguiente.
Haz clic en Instalar.
Haz clic en Terminar cuando termines.
Se abre la terminal del CMD. Pulsa cualquier tecla para continuar...
Haz clic en Sí para continuar en la ventana UAC.
Windows Powershell se abre mostrando los detalles de instalación.
Una vez completada la instalación, escribe Enter para salir de PowerShell.
Abre el símbolo de comandos
Primero ejecuta el siguiente comando.
Instalación de NPM --Global Mocha
A continuación, ejecuta el siguiente comando
Instalación de Axios de NPM
Ahora has terminado de instalar mocha. Cierra el terminal para continuar instalando otros paquetes.
Desde Visual Studio, abre nodeserver.js desde el nodo exercise files ->.
Tenemos que empezar a programar para el nodo... servidor JS que expondrá una llamada al método "get" que devolverá el valor de la clave pasada en la cadena de consulta. Usemos el Copilot para ayudarnos con esto.
Pulsa Ctrl+I y pega los comandos siguientes para que el Copilot genere el código y luego pulse Enviar.
*// write a nodejs server that will expose a method call "get" that will return the value of the key passed in the query string*
*// example: http://localhost:3000/get?key=hello*
*// if the key is not passed, return "key not passed"*
*// if the key is passed, return "hello" + key*
*// if the url has other methods, return "method not supported"*
*// when server is listening, log "server is listening on port 3000"*
El Copilot genera el código y lo muestra. Haz clic en Aceptar para aceptarlo.
Haz clic derecho en la carpeta del nodo y selecciona Abrir en Terminal Integrado.
Una vez que el terminal esté abierto, ejecuta el comando de abajo desde él.
mocha test.js
Deberías obtener un resultado como 1 Pasando, como en la captura de pantalla de abajo.
Esta es la prueba unitaria del método en el nodeserver.js y ha pasado.
Seguiremos añadiendo diferentes métodos al servidor usando el Copilot.
El ejercicio consiste en construir un servidor web usando Nodejs que atiende a las solicitudes de diversas funcionalidades.
Añadir la solicitud de funcionalidad DaysBetweenDates a la que el servidor debe asistir.
Pulsa Enter después de que termine la condición if - nombre de ruta == '/get'.
Pulsa Ctrl+I para abrir la función en línea de Copilot, introduce lo siguiente y haz clic en Enviar.
/DaysBetweenDates:
Calculate days between two dates
receive by query string 2 parameters date1 and date 2, and calculate the days between those two dates.
Reference Code:
if (req.url.startsWith('/DaysBetweenDates')) {
*//calculate days between two dates*
*//get dates from querystring*
var queryData = url.parse(req.url, true).query;
var date1 = queryData.date1;
var date2 = queryData.date2;
*//convert dates to milliseconds*
var date1_ms = Date.parse(date1);
var date2_ms = Date.parse(date2);
*//calculate difference in milliseconds*
var difference_ms = date2_ms - date1_ms;
*//convert to days and return*
res.end(Math.round(difference_ms / 86400000) + " days");
}
Copilot genera el código. Haz clic en Aceptar para aceptar el código. Ten en cuenta que el código generado es un bloque if de otro tipo donde en la solicitud es DíasEntreFechas.
Haz clic en Entrar después del bloque DíasEntreFechas.
Introduce el bloque de comentarios de abajo y pulsa Enter.
*/
Reference Code:
else if (req.url.startsWith('/Validatephonenumber')) {
*//get phoneNumber var from querystring*
var queryData = url.parse(req.url, true).query;
var phoneNumber = queryData.phoneNumber;
*//validate phoneNumber with Spanish format*
var regex = /^(\+34|0034|34)?[ -]*(6|7)[ -]*([0-9][ -]*){8}$/;
*//if phoneNumber is valid return "valid"*
if (regex.test(phoneNumber)) {
res.end("valid");
}
*//if phoneNumber is not valid return "invalid"*
else {
res.end("invalid");
}
}
El Copiloto genera el código. Haz clic en Aceptar para aceptar el código.
Haz clic en Enter después del bloque Validatephonenumber para añadir el siguiente bloque de código.
Copia y pega el texto de abajo en el archivo js.
*/
*/ValidateSpanishDNI:*
*Receive by querystring a parameter called dni*
*calculate DNI letter*
*if DNI is valid return "valid"*
*if DNI is not valid return "invalid"*
/*
Reference Code:
else if (req.url.startsWith('/ValidateSpanishDNI')) {
var queryData = url.parse(req.url, true).query;
var dni = queryData.dni;
*// calculate DNI letter*
var dniLetter = dni.charAt(dni.length - 1);
var dniNumber = dni.substring(0, dni.length - 1);
var dniLetterCalc = "TRWAGMYFPDXBNJZSQVHLCKE".charAt(dniNumber % 23);
*//if DNI is valid return "valid"*
if (dniLetter == dniLetterCalc) {
res.end("valid");
}
*//if DNI is not valid return "invalid"*
else {
res.end("invalid");
}
}
Una vez pegado el contenido anterior, el Copilot genera el código que se muestra justo debajo del comentario. Haz clic en Aceptar para aceptar el código.
Abre el chat de Copilot desde el panel de navegación izquierdo.
Pega el contenido de abajo en el chat y haz clic en el botón Enviar.
/ReturnColorCode:
Receive by querystring a parameter called color
read colors.json file and return the rgba field
get color var from querystring
iterate for each color in colors.json to find the color
return the code.hex field
Reference code:
else if (req.url.startsWith('/ReturnColorCode')) {
*//read colors.json file and return the rgba field*
var colors = fs.readFileSync('colors.json', 'utf-8');
var colorsObj = JSON.parse(colors);
*//get color var from querystring*
var queryData = url.parse(req.url, true).query;
var color = queryData.color;
var colorFound = "not found";
*//for each color in colors.json*
for (var i = 1; i < colorsObj.length; i++) {
*//if color is found return the color code*
if (colorsObj[i].color == color) {
colorFound = colorsObj[i].code.hex;
}
}
res.end(colorFound);
}
Mantén el cursor después del bloque ValidateSpanishDNI y haz clic en el icono Insertar en el cursor en el chat. Esto copia el código generado por Copilot desde el chat al archivo js del servidor en la ubicación mencionada.
Comprueba si hay errores, si es que hay alguno. En este código generado, hay un error ya que hay una declaración constante entre los bloques else.
Pulsa Ctrl+I para abrir el Copilot Inline, escribe y haz clic en el botón Enviar./fix
Copilot genera una solución si puede encontrar una. Acepta o descarta la solución según lo precisa que sea.
Aquí, estamos moviendo la declaración constante dentro del bloque else if de returncolors para resolver el error.
Importante: El código y la resolución pueden ser diferentes para ti según la que genere el Copilot.
Después del bloque añadido, pulsa Ctrl+I para abrir la función en línea de Copilot, pega el contenido de abajo y haz clic en Enviar.
/TellMeAJoke:
Make a call to the joke api and return a random joke using axios (https:*//official-joke-api.appspot.com/random_joke)*
Reference code:
else if (req.url.startsWith('/TellMeAJoke')) {
*//make a call to the joke api and return a random joke using axios*
const axios = require('axios');
axios.get('https://official-joke-api.appspot.com/random_joke')
.then(function (response) {
*// handle success*
res.end(response.data.setup + " " + response.data.punchline);
}
)
.catch(function (error) {
*// handle error*
console.log(error);
})
.then(function () {
*// always executed*
});
}
Haz clic en Aceptar para aceptar el código generado por el Copilot.
Después del bloque de código generado, pulsa Ctrl+I, introduce el texto de abajo y haz clic en el botón Enviar.
/MoviesByDirector:
Receive by querystring a parameter called director
Make a call to the movie api and return a list of movies of that director using axios
Return the full list of movies
Reference code:
*//method that gets the name of a director and retrieves from an api the list of movies of that director*
else if (req.url.startsWith('/MoviesByDirector')) {
*//get a director name from querystring*
var queryData = url.parse(req.url, true).query;
var director = queryData.director;
*//make a call to the movie api omdbapi.com and return a list of movies of that director using axios*
const axios = require('axios');
axios.get('http://www.omdbapi.com/?apikey=XXXXXXX&s=' + director)
.then(function (response) {
*//return the full list of movies*
var movies = "";
for (var i = 0; i < response.data.Search.length; i++) {
movies = movies + response.data.Search[i].Title + ", ";
}
res.end(movies);
}
)
.catch(function (error) {
*// handle error*
console.log(error);
}
)
.then(function () {
*// always executed*
}
);
}
Haz clic en Aceptar para aceptar el código.
Después del bloque de código generado, pulsa Ctrl+I, introduce el texto de abajo y haz clic en el botón Enviar.
/ParseUrl:
Retrieves a parameter from querystring called someurl
Parse the url and return the protocol, host, port, path, querystring and hash
Return the parsed host
Reference code:
*//If url equals to ParseUrl*
else if (req.url.startsWith('/ParseUrl')) {
*//retrieves a parameter from querystring called someurl*
var queryData = url.parse(req.url, true).query;
var someUrl = queryData.someurl;
*//parse the url and return the protocol, host, port, path, querystring and hash*
var urlObj = new URL(someUrl);
var protocol = urlObj.protocol;
var host = urlObj.host;
var port = urlObj.port;
var path = urlObj.pathname;
var querystring = urlObj.search;
var hash = urlObj.hash;
*//return the parsed host*
res.end("host: " + host);
}
Haz clic en Aceptar para aceptar el código.
Después del bloque de código generado, pulsa Ctrl+I, introduce el texto de abajo y haz clic en el botón Enviar.
/GetFullTextFile:
Read sample.txt` and return lines that contains the word "Fusce"
Reference code:
else if (req.url.startsWith('/GetFullTextFile')) {
//read sample.txt and return lines that contains the word "Fusce"
var text = fs.readFileSync('sample.txt', 'utf-8');
var lines = text.split("\r");
var linesFound = "";
for (var i = 1; i < lines.length; i++) {
if (lines[i].includes("Fusce")) {
linesFound = linesFound + lines[i] + ", ";
}
}
res.end(linesFound);
}
Haz clic en Aceptar para aceptar el código.
Después del bloque de código generado, pulsa Ctrl+I, introduce el texto de abajo y haz clic en el botón Enviar.
/GetLineByLinefromtTextFile:
Read sample.txt line by line
Create a promise to read the file line by line, and return a list of lines that contains the word "Fusce"
Return the list of lines
Reference code:
else if (req.url.startsWith('/GetLineByLinefromtTextFile')) {
*//read sample.txt line by line*
var lineReader = require('readline').createInterface({
input: require('fs').createReadStream('sample.txt')
});
*//create a promise to read the file line by line, and return a list of lines that contains the word "Fusce"*
var promise = new Promise(function (resolve, reject) {
var lines = [];
lineReader.on('line', function (line) {
if (line.includes("Fusce")) {
lines.push(line);
}
});
lineReader.on('close', function () {
resolve(lines);
});
});
*//return the list of lines*
promise.then(function (lines) {
res.end(lines.toString());
});
}
Haz clic en Aceptar para aceptar el código.
Después del bloque de código generado, pulsa Ctrl+I, introduce el texto de abajo y haz clic en el botón Enviar.
/CalculateMemoryConsumption:
Return the memory consumption of the process in GB, rounded to 2 decimals
Reference code:
else if (req.url.startsWith('/CalculateMemoryConsumption')) {
*//return the memory consumption of the process in GB, rounded to 2 decimals*
var memory = process.memoryUsage().heapUsed / 1024 / 1024;
res.end(memory.toFixed(2) + " GB");
}
Haz clic en Aceptar para aceptar el código.
Después del bloque de código generado, pulsa Ctrl+I, introduce el texto de abajo y haz clic en el botón Enviar.
/RandomEuropeanCountry:
Make an array of european countries and its iso codes
Return a random country from the array
Return the country and its iso code
Reference code:
else if (req.url.startsWith('/RandomEuropeanCountry')) {
*//make an array of european countries and its iso codes*
var countries = [
{ country: "Italy", iso: "IT" },
{ country: "France", iso: "FR" },
{ country: "Spain", iso: "ES" },
{ country: "Germany", iso: "DE" },
{ country: "United Kingdom", iso: "GB" },
{ country: "Greece", iso: "GR" },
{ country: "Portugal", iso: "PT" },
{ country: "Romania", iso: "RO" },
{ country: "Bulgaria", iso: "BG" },
{ country: "Croatia", iso: "HR" },
{ country: "Czech Republic", iso: "CZ" },
{ country: "Denmark", iso: "DK" },
{ country: "Estonia", iso: "EE" },
{ country: "Finland", iso: "FI" },
{ country: "Hungary", iso: "HU" },
{ country: "Ireland", iso: "IE" },
{ country: "Latvia", iso: "LV" },
{ country: "Lithuania", iso: "LT" },
{ country: "Luxembourg", iso: "LU" },
{ country: "Malta", iso: "MT" },
{ country: "Netherlands", iso: "NL" },
{ country: "Poland", iso: "PL" },
{ country: "Slovakia", iso: "SK" },
{ country: "Slovenia", iso: "SI" },
{ country: "Sweden", iso: "SE" },
{ country: "Belgium", iso: "BE" },
{ country: "Austria", iso: "AT" },
{ country: "Switzerland", iso: "CH" },
{ country: "Cyprus", iso: "CY" },
{ country: "Iceland", iso: "IS" },
{ country: "Norway", iso: "NO" },
{ country: "Albania", iso: "AL" },
{ country: "Andorra", iso: "AD" },
{ country: "Armenia", iso: "AM" },
{ country: "Azerbaijan", iso: "AZ" },
{ country: "Belarus", iso: "BY" },
{ country: "Bosnia and Herzegovina", iso: "BA" },
{ country: "Georgia", iso: "GE" },
{ country: "Kazakhstan", iso: "KZ" },
{ country: "Kosovo", iso: "XK" },
{ country: "Liechtenstein", iso: "LI" },
{ country: "Macedonia", iso: "MK" },
{ country: "Moldova", iso: "MD" },
{ country: "Monaco", iso: "MC" },
{ country: "Montenegro", iso: "ME" },
{ country: "Russia", iso: "RU" },
{ country: "San Marino", iso: "SM" },
{ country: "Serbia", iso: "RS" },
{ country: "Turkey", iso: "TR" },
{ country: "Ukraine", iso: "UA" },
{ country: "Vatican City", iso: "VA" }
];
*//return a random country from the array*
var randomCountry = countries[Math.floor(Math.random() * countries.length)];
*//return the country and its iso code*
res.end(randomCountry.country + " " + randomCountry.iso);
}
Haz clic en Aceptar para aceptar el código.
Documentar código siempre es una tarea aburrida y dolorosa. Sin embargo, podemos usar Copilot para documentarlo por nosotros. En el chat, pide a Copilot que documente el archivo nodeserver.js.
Selecciona todo en el archivo nodeserver.js.
Desde el chat de Copilot, entra y haz clic en enviar.document the nodeserver.js file
El Copilot genera una documentación detallada del archivo.
Crearemos pruebas automatizadas para comprobar que la funcionalidad de los endpoints anteriores está correctamente implementada. Las pruebas deberían estar juntas en el archivo test.js.
Puedes aprovechar Copilot para hacer las pruebas. Hay un comando /tests que puedes ejecutar directamente desde Copilot Chat o seleccionando el fragmento de código para el que quieres crear pruebas y usando la función en línea de Copilot.
Abre el archivo test.js.
Haz clic en Enter después del bloque it existente.
Introduce el texto siguiente y haz clic en Enter.
add test to test DaysBetweenDates
Esto genera el bloque de pruebas unitario para DíasEntreFechas. Haz clic en Aceptar para aceptar el código.
Desde el terminal, ejecuta el siguiente comando mocha test.js
Introduce el texto siguiente y haz clic en Enter.*//add test to check validatephoneNumber*
Haz clic en Aceptar para aceptar el código generado por el Copilot.
Desde el terminal, ejecuta el comando, . Comprueba que el número de teléfono validado haya pasado.mocha test.js
Introduce el texto de abajo y pulsa Enter.
*//write test to validate validateSpanishDNI*
Acepta el texto generado por Copilot.
Desde el terminal, ejecuta y comprueba que el ValidateSpanishDNI ha pasado.mocha test.js
Reference Code:
*//write npm command line to install mocha*
*//npm install --global mocha*
*//command to run this test file*
*//mocha test.js*
const assert = require('assert');
const http = require('http');
const server = require('./nodeserver');
describe('Node Server', () => {
it('should return "key not passed" if key is not passed', (done) => {
http
.get('http://localhost:3000/Get' , (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
assert.equal(data, 'key not passed');
done();
});
});
});
it('should return the value of the key if key is found', (done) => {
http.get('http://localhost:3000/Get?key=world', (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
assert.equal(data, 'hello world');
done();
});
});
});
*//add test to check validatephoneNumber*
it('should return "valid" if phoneNumber is valid', (done) => {
http.get('http://localhost:3000/Validatephonenumber?phoneNumber=34666666666', (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
assert.equal(data, 'valid');
done();
});
});
});
*//write test to validate spanish DNI*
it('should return "valid" if spanish DNI 86471508H is valid', (done) => {
http.get('http://localhost:3000/ValidateSpanishDNI?dni=86471508H', (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
assert.equal(data, 'valid');
done();
});
});
});
*//write test to validate spanish DNI*
it('should return "valid" if spanish DNI 24153149K is valid', (done) => {
http.get('http://localhost:3000/ValidateSpanishDNI?dni=24153149K', (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
assert.equal(data, 'valid');
done();
});
});
});
*//write test to validate spanish DNI*
it('should return "valid" if spanish DNI 12345678A is invalid', (done) => {
http.get('http://localhost:3000/ValidateSpanishDNI?dni=12345678A', (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
assert.equal(data, 'invalid');
done();
});
});
});
*//write test for returnColorCode*
it('should return "red" if color is red', (done) => {
http.get('http://localhost:3000/ReturnColorCode?color=red', (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
assert.equal(data, '#FF0000');
done();
});
});
});
*//write test for daysBetweenDates*
it('should return "1" if dates are 2020-01-01 and 2020-01-02', (done) => {
http.get('http://localhost:3000/DaysBetweenDates?date1=2020-01-01&date2=2020-01-02', (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
assert.equal(data, '1 days');
done();
});
});
});
});
Abre el dockerfile desde la carpeta node.
El archivo consistirá en comentarios sobre cómo debe poblarse.
Pulsa Ctrl+I y escribe . Haz clic en el icono de enviar./fix
El Copilot generará el contenido del archivo Docker. Haz clic en Aceptar.
Desde el terminal, ejecuta el siguiente comando
docker build -t mynodeapp .
Esto es para construir la imagen y etiquetarla como mynodeapp.
Ejecuta el docker en el puerto 4000 usando el comando de abajo.
docker run -p 4000:3000 -d mynodeapp
Abre el demonio Docker para ver que la aplicación ha sido contenedora y está ejecutándose en él.
En este laboratorio, hemos aprendido a usar el Copilot en un proyecto de nodo