Este material concluye la serie de traducción manual Node.js. Hoy hablaremos sobre os, eventos y módulos http, discutiremos el trabajo con flujos y bases de datos, y discutiremos el uso de Node.js en el desarrollo y producción de aplicaciones.

[Le aconsejamos que lea] Otras partes del cicloParte 1:
Información general y primeros pasosParte 2:
JavaScript, V8, algunos trucos de desarrolloParte 3:
Hosting, REPL, trabajar con la consola, módulosParte 4:
archivos npm, package.json y package-lock.jsonParte 5:
npm y npxParte 6:
bucle de eventos, pila de llamadas, temporizadoresParte 7:
Programación asincrónicaParte 8:
protocolos HTTP y WebSocketParte 9:
trabajar con el sistema de archivosParte 10:
módulos estándar, hilos, bases de datos, NODE_ENVPDF completo de la guía Node.js Node.js os module
El módulo
os
proporciona acceso a muchas funciones que se pueden utilizar para obtener información sobre el sistema operativo y el hardware de la computadora que ejecuta Node.js. Este es un módulo estándar, no necesita instalarlo, para trabajar con él desde el código, solo conéctelo:
const os = require('os')
Aquí hay varias propiedades útiles que, en particular, pueden ser útiles al trabajar con archivos.
Entonces, la propiedad
os.EOL
permite encontrar el separador de línea utilizado en el sistema (un
os.EOL
línea). En Linux y macOS, esto es
\n
, en Windows,
\r\n
.
Cabe señalar que cuando mencionamos "Linux y macOS" aquí, estamos hablando de plataformas compatibles con POSIX. En aras de la brevedad, no mencionamos plataformas menos populares aquí.
La propiedad
os.constants.signals
proporciona información sobre las constantes utilizadas para procesar señales de proceso como
SIGHUP
,
SIGKILL
, etc.
Aquí puedes encontrar detalles sobre ellos.
La propiedad
os.constants.errno
contiene las constantes utilizadas para los mensajes de error, como
EADDRINUSE
,
EOVERFLOW
.
Ahora considere los métodos principales del módulo
os
.
▍os.arch ()
Este método devuelve una cadena que identifica la arquitectura del sistema, por ejemplo,
arm
,
x64
,
arm64
.
▍os.cpus ()
Devuelve información sobre los procesadores disponibles en el sistema. Por ejemplo, esta información puede verse así:
[ { model: 'Intel(R) Core(TM)2 Duo CPU P8600 @ 2.40GHz', speed: 2400, times: { user: 281685380, nice: 0, sys: 187986530, idle: 685833750, irq: 0 } }, { model: 'Intel(R) Core(TM)2 Duo CPU P8600 @ 2.40GHz', speed: 2400, times: { user: 282348700, nice: 0, sys: 161800480, idle: 703509470, irq: 0 } } ]
▍os.endianness ()
Devuelve
BE
o
LE
dependiendo de qué
orden de bytes (Big Engian o Little Endian) se utilizó para compilar el archivo binario Node.js.
▍os.freemem ()
Devuelve la cantidad de memoria libre del sistema en bytes.
▍os.homedir ()
Devuelve la ruta al directorio de inicio del usuario actual. Por ejemplo,
'/Users/flavio'
.
▍os.hostname ()
Devuelve el nombre del host.
▍os.loadavg ()
Devuelve, en una matriz, los datos de carga promedio calculados por el sistema operativo. Esta información solo tiene sentido en Linux y macOS. Puede verse así:
[ 3.68798828125, 4.00244140625, 11.1181640625 ]
▍os.networkInterfaces ()
Devuelve información sobre las interfaces de red disponibles en el sistema. Por ejemplo:
{ lo0: [ { address: '127.0.0.1', netmask: '255.0.0.0', family: 'IPv4', mac: 'fe:82:00:00:00:00', internal: true }, { address: '::1', netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', family: 'IPv6', mac: 'fe:82:00:00:00:00', scopeid: 0, internal: true }, { address: 'fe80::1', netmask: 'ffff:ffff:ffff:ffff::', family: 'IPv6', mac: 'fe:82:00:00:00:00', scopeid: 1, internal: true } ], en1: [ { address: 'fe82::9b:8282:d7e6:496e', netmask: 'ffff:ffff:ffff:ffff::', family: 'IPv6', mac: '06:00:00:02:0e:00', scopeid: 5, internal: false }, { address: '192.168.1.38', netmask: '255.255.255.0', family: 'IPv4', mac: '06:00:00:02:0e:00', internal: false } ], utun0: [ { address: 'fe80::2513:72bc:f405:61d0', netmask: 'ffff:ffff:ffff:ffff::', family: 'IPv6', mac: 'fe:80:00:20:00:00', scopeid: 8, internal: false } ] }
▍os.platform ()
Devuelve información sobre la plataforma para la que se compiló Node.js. Estos son algunos de los posibles valores de retorno:
- Darwin
- freebsd
- linux
- openbsd
- win32
▍os.release ()
Devuelve una cadena que identifica el número de versión del sistema operativo.
▍os.tmpdir ()
Devuelve la ruta al directorio especificado en el sistema para almacenar archivos temporales.
▍os.totalmem ()
Devuelve la cantidad total de memoria del sistema en bytes.
▍os.type ()
Devuelve información que identifica el sistema operativo. Por ejemplo:
Linux
- Linux.Darwin
- macOS.Windows_NT
: Windows.
▍os.uptime ()
Devuelve el tiempo de actividad del sistema en segundos desde el último reinicio.
Módulo de eventos Node.js
El módulo de
events
nos proporciona la clase
EventEmitter
, que está diseñada para trabajar con eventos en la plataforma Node.js. Ya hablamos un poco sobre este módulo en el
séptimo de esta serie de materiales.
Aquí está la documentación para ello. Aquí nos fijamos en la API de este módulo. Recuerde que para usarlo en el código necesita conectarlo, como suele ser el caso con los módulos estándar. Después de eso, debe crear un nuevo objeto
EventEmitter
. Se ve así:
const EventEmitter = require('events') const door = new EventEmitter()
El objeto de la clase
EventEmitter
utiliza mecanismos estándar, en particular, los siguientes eventos:
newListener
: este evento se newListener
cuando se agrega un controlador de eventos.removeListener
: se llama cuando se elimina el controlador.
Considere los métodos más útiles de los objetos de la clase
EventEmitter
(un objeto similar en los nombres de los métodos se indica como
emitter
).
▍emitter.addListener ()
Un alias para el método
emitter.on()
.
▍emitter.emit ()
Genera un evento. Invoca a todos los controladores de eventos sincrónicamente en el orden en que se registraron.
▍emitter.eventNames ()
Devuelve una matriz que contiene los eventos registrados.
▍emitter.getMaxListeners ()
Devuelve el número máximo de controladores que se pueden agregar a un objeto de la clase
EventEmitter
. El valor predeterminado es 10. Si es necesario, este parámetro se puede aumentar o disminuir utilizando el método
setMaxListeners()
.
▍emitter.listenerCount ()
Devuelve el número de controladores de eventos cuyo nombre se pasa a este método como parámetro:
door.listenerCount('open')
▍emitter.listeners ()
Devuelve una matriz de controladores de eventos para el evento correspondiente, cuyo nombre se pasa a este método:
door.listeners('open')
▍emitter.off ()
Un alias para el método
emitter.removeListener()
, introducido en el Nodo 10.
▍emitter.on ()
Registre una devolución de llamada que se llama cuando se genera un evento. Aquí se explica cómo usarlo:
door.on('open', () => { console.log('Door was opened') })
▍emitter.once ()
Registra una devolución de llamada que se llama solo una vez, en la primera aparición de un evento para el que se registra esta devolución de llamada. Por ejemplo:
const EventEmitter = require('events') const ee = new EventEmitter() ee.once('my-event', () => {
▍emitter.prependListener ()
Al registrar un controlador utilizando los métodos
on()
o
addListener()
, este controlador se agrega al final de la cola del controlador y se llama al último para controlar el evento correspondiente. Cuando se usa el método
prependListener()
, el controlador se agrega al frente de la cola, lo que hace que se llame primero para procesar el evento.
▍emitter.prependOnceListener ()
Este método es similar al anterior. Es decir, cuando un controlador destinado a una sola llamada se registra utilizando el método
once()
, resulta ser el último en la cola de controladores y el último en ser llamado. El método
prependOnceListener()
permite agregar dicho controlador al frente de la cola.
▍emitter.removeAllListeners ()
Este método elimina todos los controladores para un evento dado registrado en el objeto correspondiente. Lo usan así:
door.removeAllListeners('open')
▍emitter.removeListener ()
Elimina el controlador especificado que se pasará a este método. Para guardar el controlador para su posterior eliminación, la devolución de llamada correspondiente se puede asignar a una variable. Se ve así:
const doSomething = () => {} door.on('open', doSomething) door.removeListener('open', doSomething)
▍emitter.setMaxListeners ()
Este método le permite especificar el número máximo de controladores que se pueden agregar a un solo evento en una instancia de la clase
EventEmitter
. De manera predeterminada, como ya se mencionó, puede agregar hasta 10 controladores para un evento en particular. Este valor puede ser cambiado. Use este método de la siguiente manera:
door.setMaxListeners(50)
Módulo http Node.js
En la
octava parte de esta serie de materiales, ya hemos hablado sobre el módulo
http
estándar Node.js. Pone a disposición de los mecanismos de desarrollo diseñados para crear servidores HTTP. Es el módulo principal utilizado para resolver los problemas de intercambio de datos a través de la red en Node.js. Puede conectarlo en el código de esta manera:
const http = require('http')
Consiste en propiedades, métodos y clases. Hablemos de ellos.
▍Propiedades
http.METHODS
Esta propiedad enumera todos los métodos HTTP admitidos:
> require('http').METHODS [ 'ACL', 'BIND', 'CHECKOUT', 'CONNECT', 'COPY', 'DELETE', 'GET', 'HEAD', 'LINK', 'LOCK', 'M-SEARCH', 'MERGE', 'MKACTIVITY', 'MKCALENDAR', 'MKCOL', 'MOVE', 'NOTIFY', 'OPTIONS', 'PATCH', 'POST', 'PROPFIND', 'PROPPATCH', 'PURGE', 'PUT', 'REBIND', 'REPORT', 'SEARCH', 'SUBSCRIBE', 'TRACE', 'UNBIND', 'UNLINK', 'UNLOCK', 'UNSUBSCRIBE' ]
http.STATUS_CODES
Contiene los códigos de estado HTTP y sus descripciones:
> require('http').STATUS_CODES { '100': 'Continue', '101': 'Switching Protocols', '102': 'Processing', '200': 'OK', '201': 'Created', '202': 'Accepted', '203': 'Non-Authoritative Information', '204': 'No Content', '205': 'Reset Content', '206': 'Partial Content', '207': 'Multi-Status', '208': 'Already Reported', '226': 'IM Used', '300': 'Multiple Choices', '301': 'Moved Permanently', '302': 'Found', '303': 'See Other', '304': 'Not Modified', '305': 'Use Proxy', '307': 'Temporary Redirect', '308': 'Permanent Redirect', '400': 'Bad Request', '401': 'Unauthorized', '402': 'Payment Required', '403': 'Forbidden', '404': 'Not Found', '405': 'Method Not Allowed', '406': 'Not Acceptable', '407': 'Proxy Authentication Required', '408': 'Request Timeout', '409': 'Conflict', '410': 'Gone', '411': 'Length Required', '412': 'Precondition Failed', '413': 'Payload Too Large', '414': 'URI Too Long', '415': 'Unsupported Media Type', '416': 'Range Not Satisfiable', '417': 'Expectation Failed', '418': 'I\'ma teapot', '421': 'Misdirected Request', '422': 'Unprocessable Entity', '423': 'Locked', '424': 'Failed Dependency', '425': 'Unordered Collection', '426': 'Upgrade Required', '428': 'Precondition Required', '429': 'Too Many Requests', '431': 'Request Header Fields Too Large', '451': 'Unavailable For Legal Reasons', '500': 'Internal Server Error', '501': 'Not Implemented', '502': 'Bad Gateway', '503': 'Service Unavailable', '504': 'Gateway Timeout', '505': 'HTTP Version Not Supported', '506': 'Variant Also Negotiates', '507': 'Insufficient Storage', '508': 'Loop Detected', '509': 'Bandwidth Limit Exceeded', '510': 'Not Extended', '511': 'Network Authentication Required' }
http.globalAgent
Esta propiedad apunta a la instancia global de la clase
http.Agent
. Se usa para administrar conexiones. Se puede considerar un componente clave del subsistema HTTP Node.js. Hablaremos más sobre la clase
http.Agent
continuación.
▍Métodos
http.createServer ()
Devuelve una nueva instancia de la clase
http.Server
. Aquí se explica cómo usar este método para crear un servidor HTTP:
const server = http.createServer((req, res) => {
http.request ()
Le permite realizar una solicitud HTTP al servidor creando una instancia de la clase
http.ClientRequest
.
http.get ()
Este método es similar a
http.request()
, pero establece automáticamente el método HTTP en
GET
y llama automáticamente a un comando del formulario
req.end()
.
▍ Clases
El módulo HTTP proporciona 5 clases:
Agent
,
ClientRequest
,
Server
,
ServerResponse
e
IncomingMessage
. Considéralos.
http.Agent
La instancia global de la clase
http.Agent
creada por Node.js se usa para administrar conexiones. Se utiliza como valor predeterminado para todas las solicitudes HTTP y proporciona colas y reutilización de sockets. Además, admite un grupo de sockets, que permite un alto rendimiento del subsistema de red Node.js. Si es necesario, puede crear su propio objeto
http.Agent
.
http.ClientRequest
Un objeto de la clase
http.ClientRequest
, que es una solicitud en ejecución, se crea cuando se
http.request()
los
http.request()
o
http.get()
. Cuando se recibe una respuesta a una solicitud, se
http.IncomingMessage
el evento de respuesta, en el que se transmite la respuesta, una instancia de
http.IncomingMessage
. Los datos obtenidos después de completar la consulta se pueden procesar de dos maneras:
- Puede llamar al método
response.read()
. - En el controlador de eventos de
response
, puede configurar un escucha para el evento de data
, que le permite trabajar con la transmisión de datos.
http.Server
Las instancias de esta clase se utilizan para crear servidores utilizando el
http.createServer()
. Después de tener un objeto de servidor, podemos usar sus métodos:
- El método
listen()
se utiliza para iniciar el servidor y organizar la espera y el procesamiento de las solicitudes entrantes. - El método
close()
detiene el servidor.
http.ServerResponse
Este objeto es creado por la clase
http.Server
y se pasa como el segundo parámetro al evento de
request
cuando ocurre. Por lo general, a tales objetos en el código se les asigna el nombre
res
:
const server = http.createServer((req, res) => {
En dichos controladores, una vez que la respuesta del servidor está lista para enviarse al cliente, se llama al método
end()
, que completa la respuesta. Este método debe llamarse después de completar cada respuesta.
Estos son los métodos utilizados para trabajar con encabezados HTTP:
getHeaderNames()
: devuelve una lista de nombres de encabezados instalados.getHeaders()
: devuelve una copia de los encabezados HTTP establecidos.setHeader('headername', value)
: establece el valor para el encabezado especificado.getHeader('headername')
: devuelve el encabezado establecido.removeHeader('headername')
: elimina el encabezado instalado.hasHeader('headername')
: devuelve true
si la respuesta ya tiene un encabezado cuyo nombre se pasa a este método.headersSent()
: devuelve true
si los encabezados ya se han enviado al cliente.
Después de procesar los encabezados, se pueden enviar al cliente llamando al método
response.writeHead()
, que, como primer parámetro, toma un código de estado. Como segundo y tercer parámetro, se le puede pasar un mensaje correspondiente al código de estado y los encabezados.
Para enviar datos al cliente, el método
write()
se usa en el cuerpo de la respuesta. Envía datos almacenados en el búfer a la secuencia de respuesta HTTP.
Si los encabezados aún no se han configurado con el comando
response.writeHead()
, los encabezados con el código de estado y el mensaje especificado en la solicitud se enviarán primero. Puede establecer sus valores estableciendo valores para las
statusMessage
statusCode
y
statusMessage
:
response.statusCode = 500 response.statusMessage =
http.IncomingMessage
Se
http.IncomingMessage
un objeto de la clase
http.IncomingMessage
en el curso de los siguientes mecanismos:
http.Server
: al procesar el evento de request
.http.ClientRequest
: cuando se maneja el evento de response
.
Se puede usar para trabajar con datos de respuesta. A saber:
- Para averiguar el código de estado de respuesta y el mensaje correspondiente, se utilizan las propiedades
statusCode
y statusMessage
. - Puede ver los
headers
respuesta rawHearders
headers
o la rawHearders
(para obtener una lista de encabezados sin formato). - Puede averiguar el método de solicitud utilizando la propiedad del
method
. - Para averiguar qué versión de HTTP se está utilizando, use la propiedad
httpVersion
. - Para obtener la URL, se pretende la propiedad
url
. - La propiedad de
socket
permite obtener el objeto net.Socket
asociado con la conexión.
Los datos de respuesta se presentan como una secuencia ya que el objeto
http.IncomingMessage
implementa la interfaz
Readable Stream
.
Trabajar con secuencias en Node.js
Los hilos son uno de los conceptos fundamentales utilizados en las aplicaciones Node.js. Los flujos son herramientas que le permiten leer y escribir archivos, organizar la interacción de red entre sistemas y, en general, implementar de manera efectiva las operaciones de intercambio de datos.
El concepto de hilos no es exclusivo de Node.js. Aparecieron en la familia de sistemas operativos Unix hace décadas. En particular, los programas pueden interactuar entre sí, transmitiendo flujos de datos usando tuberías (usando el carácter de tubería -
|
).
Si imaginamos, digamos, leer un archivo sin usar secuencias, entonces, durante la ejecución del comando correspondiente, el contenido del archivo se leerá completamente en la memoria, después de lo cual será posible trabajar con estos contenidos.
Gracias al uso del mecanismo de flujo, los archivos se pueden leer y procesar en partes, lo que elimina la necesidad de almacenar grandes cantidades de datos en la memoria.
El módulo de
transmisión Node.js es la base sobre la cual se construyen todas las API que admiten transmisión.
▍Acerca de las fortalezas del uso de flujos
Las secuencias, en comparación con otros métodos de procesamiento de datos, tienen las siguientes ventajas:
- Uso eficiente de la memoria. Trabajar con una secuencia no implica almacenar en la memoria grandes cantidades de datos cargados allí por adelantado, antes de que sea posible procesarlos.
- Ahorro de tiempo Los datos recibidos de la transmisión se pueden procesar mucho más rápido que cuando tiene que esperar a que se carguen por completo para comenzar a procesarlos.
▍ Ejemplo de trabajo con flujos
Un ejemplo tradicional de trabajar con secuencias demuestra la lectura de un archivo desde el disco.
Primero, considere el código en el que no se usan hilos. El módulo estándar Node.js
fs
permite leer un archivo, después de lo cual puede transferirse a través de HTTP en respuesta a una solicitud recibida por un servidor HTTP:
const http = require('http') const fs = require('fs') const server = http.createServer(function (req, res) { fs.readFile(__dirname + '/data.txt', (err, data) => { res.end(data) }) }) server.listen(3000)
El método
readFile()
utilizado aquí le permite leer todo el archivo. Cuando se completa la lectura, llama a la devolución de llamada correspondiente.
El
res.end(data)
, llamado en la devolución de llamada, envía el contenido del archivo al cliente.
Si el tamaño del archivo es grande, entonces esta operación llevará mucho tiempo. Aquí está el mismo ejemplo reescrito usando secuencias:
const http = require('http') const fs = require('fs') const server = http.createServer((req, res) => { const stream = fs.createReadStream(__dirname + '/data.txt') stream.pipe(res) }) server.listen(3000)
En lugar de esperar el momento en que el archivo se lee por completo, comenzamos a transferir sus datos al cliente inmediatamente después de que la primera parte de estos datos esté lista para enviar.
Método ipePipe ()
En el ejemplo anterior, utilizamos una construcción de la forma
stream.pipe(res)
, en la que se llama al método de flujo de archivos
pipe()
. Este método toma datos de su origen y los envía al destino.
Se llama para una secuencia que representa una fuente de datos. En este caso, esta es la secuencia de archivos que se envía a la respuesta HTTP.
El valor de retorno del método
pipe()
es la secuencia de destino. Esto es muy conveniente, ya que le permite encadenar varias llamadas al método
pipe()
:
src.pipe(dest1).pipe(dest2)
Esto es equivalente a dicho diseño:
src.pipe(dest1) dest1.pipe(dest2)
▍API Node.js que usan flujos
Las secuencias son un mecanismo útil; como resultado, muchos módulos del núcleo Node.js proporcionan capacidades estándar para trabajar con secuencias. Enumeramos algunos de ellos:
process.stdin
: devuelve un hilo conectado a stdin
.process.stdout
- Devuelve el hilo conectado a stdout
.process.stderr
: devuelve un hilo conectado a stderr
.fs.createReadStream()
: crea una secuencia legible para trabajar con un archivo.fs.createWriteStream()
: crea una secuencia de escritura para trabajar con un archivo.net.connect()
: inicia una conexión basada en transmisión.http.request()
: devuelve una instancia de la clase http.ClientRequest
que proporciona acceso a la secuencia que se está escribiendo.zlib.createGzip()
: comprime los datos utilizando el algoritmo gzip
y los envía a la secuencia.zlib.createGunzip()
: descomprime una secuencia de gzip
.zlib.createDeflate()
: comprime los datos utilizando el algoritmo de deflate
y los envía a la secuencia.zlib.createInflate()
: descomprime una secuencia de deflate
.
▍Varios tipos de corrientes
Hay cuatro tipos de transmisiones:
- Una secuencia legible es una secuencia desde la que se pueden leer los datos. No puede escribir datos en dicha secuencia. Cuando los datos llegan a ese flujo, se almacenan en el búfer hasta que el consumidor de datos comienza a leerlos.
- Una secuencia para escribir (
Writable
) es una secuencia en la que puede enviar datos. No puede leer datos de él. - Flujo dúplex (
Duplex
): en este flujo puede enviar datos y leerlos. Esencialmente, esta es una combinación de una secuencia para leer y una secuencia para escribir. - Transformar flujo (
Transform
): tales flujos son similares a los flujos dúplex, la diferencia es que lo que llega a la entrada de estos flujos transformará lo que se puede leer de ellos.
▍ Crear una secuencia de lectura
,
stream
:
const Stream = require('stream') const readableStream = new Stream.Readable()
, :
readableStream.push('hi!') readableStream.push('ho!')
▍
Writable
_write()
. :
const Stream = require('stream') const writableStream = new Stream.Writable()
_write()
:
writableStream._write = (chunk, encoding, next) => { console.log(chunk.toString()) next() }
, :
process.stdin.pipe(writableStream)
▍
, , :
const Stream = require('stream') const readableStream = new Stream.Readable() const writableStream = new Stream.Writable() writableStream._write = (chunk, encoding, next) => { console.log(chunk.toString()) next() } readableStream.pipe(writableStream) readableStream.push('hi!') readableStream.push('ho!') readableStream.push(null)
readableStream.push(null)
.
,
readable
:
readableStream.on('readable', () => { console.log(readableStream.read()) })
▍
write()
:
writableStream.write('hey!\n')
▍ ,
, ,
end()
:
writableStream.end()
. , , .
MySQL Node.js
MySQL . Node.js , MySQL-, — , .
mysqljs/mysql . , , 12000 GitHub. , MySQL-.
▍
:
npm install mysql
▍
:
const mysql = require('mysql')
:
const options = { user: 'the_mysql_user_name', password: 'the_mysql_user_password', database: 'the_mysql_database_name' } const connection = mysql.createConnection(options)
:
connection.connect(err => { if (err) { console.error('An error occurred while connecting to the DB') throw err } }
▍
options
:
const options = { user: 'the_mysql_user_name', password: 'the_mysql_user_password', database: 'the_mysql_database_name' }
. — :
host
— , MySQL-, — localhost
.port
— , — 3306
.socketPath
— Unix .debug
— , .trace
— , .ssl
— SSL- .
▍ SELECT
SQL- .
query
, . — , . . :
connection.query('SELECT * FROM todos', (error, todos, fields) => { if (error) { console.error('An error occurred while executing the query') throw error } console.log(todos) })
, :
const id = 223 connection.query('SELECT * FROM todos WHERE id = ?', [id], (error, todos, fields) => { if (error) { console.error('An error occurred while executing the query') throw error } console.log(todos) })
, , :
const id = 223 const author = 'Flavio' connection.query('SELECT * FROM todos WHERE id = ? AND author = ?', [id, author], (error, todos, fields) => { if (error) { console.error('An error occurred while executing the query') throw error } console.log(todos) })
▍ INSERT
INSERT
. , :
const todo = { thing: 'Buy the milk' author: 'Flavio' } connection.query('INSERT INTO todos SET ?', todo, (error, results, fields) => { if (error) { console.error('An error occurred while executing the query') throw error } })
, ,
auto_increment
,
results.insertId
:
const todo = { thing: 'Buy the milk' author: 'Flavio' } connection.query('INSERT INTO todos SET ?', todo, (error, results, fields) => { if (error) { console.error('An error occurred while executing the query') throw error }} const id = results.resultId console.log(id) )
▍
—
end()
:
connection.end()
.
-
Node.js -.
Node.js . , -,
NODE_ENV
:
NODE_ENV=production
. Linux, , :
export NODE_ENV=production
, ,
.bash_profile
( Bash), .
, :
NODE_ENV=production node app.js
Node.js.
NODE_ENV
production
:
,
Pug — , Express, ,
NODE_ENV
production
. Express, , . - . .
Express . , ,
NODE_ENV
:
app.configure('development', () => { //... }) app.configure('production', () => { //... }) app.configure('production', 'staging', () => { //... })
, :
app.configure('development', () => { app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); }) app.configure('production', () => { app.use(express.errorHandler()) })
▍
, , Node.js , . , , , Node.js, - ,
Node.js.
Estimados lectores! , Node.js, , .
