Migración a Express 4
Overview
Express 4 es un cambio que rompe el código existente de Express 3, etc. Esto implica que una aplicación Express 3 existente no funcionará si actualiza la versión de Express en sus dependencias.
En este artículo se describen:
- Los cambios en Express 4.
- Un ejemplo de migración de una aplicación Express 3 a Express 4.
- La actualización al generador de aplicaciones Express 4.</li>
</ul>
Los cambios en Express 4
Se han realizado varios cambios importantes en Express 4:- Changes to Express core and middleware system. The dependencies on Connect and built-in middleware were removed, so you must add middleware yourself.
- Cambios en el sistema de direccionamiento.
- Otros cambios.
Cambios en el sistema principal y de middleware de Express
Express 4 ya no depende de Connect y elimina todo el middleware incorporado de su núcleo, excepto la función `express.static`. Esto significa que ahora Express es una infraestructura web de middleware y direccionamiento independiente, y que los releases y las versiones de Express no se ven afectados por las actualizaciones de middleware. Sin el middleware incorporado, debe añadir explícitamente todo el middleware necesario para ejecutar la aplicación. Sólo tiene que seguir estos pasos: 1. Instalar el módulo: `npm install --save` 2. En su aplicación, requerir el módulo: `require('module-name')` 3. Utilizar el módulo según su documentación: `app.use( ... )` En la tabla siguiente se lista el middleware de Express 3 y su contrapartida en Express 4. Express 3 Express 4 express.bodyParser
body-parser + multer express.compress
compression express.cookieSession
cookie-session express.cookieParser
cookie-parser express.logger
morgan express.session
express-session express.favicon
serve-favicon express.responseTime
response-time express.errorHandler
errorhandler express.methodOverride
method-override express.timeout
connect-timeout express.vhost
vhost express.csrf
csurf express.directory
serve-index express.static
serve-static
En la versión 4, puede utilizar un parámetro de variable para definir la vía de acceso donde se cargan las funciones de middleware y, a continuación, leer el valor del parámetro en el manejador de rutas. For example: ```js app.use('/book/:id', (req, res, next) => { console.log('ID:', req.params.id) next() }) ```app.use
accepts parametersEl sistema de direccionamiento
Ahora las aplicaciones cargan implícitamente el middleware de direccionamiento, por lo que ya no tiene que preocuparse del orden con el que se carga el middleware respecto al middleware de `router`. La forma en que define las rutas no varía, pero el sistema de direccionamiento tiene dos nuevas características que permiten organizar las rutas: {: .doclist } - Un nuevo método, `app.route()`, para crear manejadores de rutas encadenables para una vía de acceso de ruta. - Una nueva clase, `express.Router`, para crear manejadores de rutas montables modulares.
El nuevo método `app.route()` permite crear manejadores de rutas encadenables para una vía de acceso de ruta. Como la vía de acceso se especifica en una única ubicación, la creación de rutas modulares es muy útil, al igual que la reducción de redundancia y errores tipográficos. Para obtener más información sobre las rutas, consulte la [`documentación` de Router()](/en/4x/api.html#router). A continuación, se muestra un ejemplo de manejadores de rutas encadenados que se definen utilizando la función `app.route()`. ```js app.route('/book') .get((req, res) => { res.send('Get a random book') }) .post((req, res) => { res.send('Add a book') }) .put((req, res) => { res.send('Update the book') }) ```app.route()
method
La otra característica que permite organizar las rutas es una nueva clase, `express.Router`, que puede utilizar para crear manejadores de rutas montables modulares. Una instancia `Router` es un sistema de middleware y direccionamiento completo; por este motivo, a menudo se conoce como una "miniaplicación". El siguiente ejemplo crea un direccionador como un módulo, carga el middleware en él, define algunas rutas y lo monta en una vía de acceso en la aplicación principal. Por ejemplo, cree un archivo de direccionador denominado `birds.js` en el directorio de la aplicación, con el siguiente contenido: ```js var express = require('express') var router = express.Router() // middleware specific to this router router.use((req, res, next) => { console.log('Time: ', Date.now()) next() }) // define the home page route router.get('/', (req, res) => { res.send('Birds home page') }) // define the about route router.get('/about', (req, res) => { res.send('About birds') }) module.exports = router ``` A continuación, cargue el módulo de direccionador en la aplicación: ```js var birds = require('./birds') // ... app.use('/birds', birds) ``` La aplicación ahora podrá manejar solicitudes a las vías de acceso `/birds` y `/birds/about`, e invocará el middleware `timeLog` que es específico de la ruta.express.Router
classOther changes
En la tabla siguiente se muestran otros cambios pequeños pero importantes en Express 4:Object Description Node.js Express 4 requiere Node.js 0.10.x o posterior y deja de dar soporte a Node.js 0.8.x. http.createServer()
The
http
module is no longer needed, unless you need to directly work with it (socket.io/SPDY/HTTPS). La aplicación puede iniciarse utilizando la funciónapp.listen()
.app.configure()
La función
app.configure()
se ha eliminado. Utilice la funciónprocess.env.NODE_ENV
oapp.get('env')
para detectar el entorno y configure la aplicación según corresponda.json spaces
La propiedad de aplicación
json spaces
está inhabilitada de forma predeterminada en Express 4.req.accepted()
Utilice
req.accepts()
,req.acceptsEncodings()
,req.acceptsCharsets()
yreq.acceptsLanguages()
.res.location()
Ya no resuelve los URL relativos.
req.params
Era una matriz, ahora es un objeto.
res.locals
Era una función, ahora es un objeto.
res.headerSent
Se ha cambiado por
res.headersSent
.app.route
Ahora está disponible como
app.mountpath
.res.on('header')
Se ha eliminado.
res.charset
Se ha eliminado.
res.setHeader('Set-Cookie', val)
La funcionalidad está ahora limitada a establecer el valor de cookie básico. Utilice
res.cookie()
para obtener la funcionalidad adicional.Migración de aplicación de ejemplo
A continuación, se muestra un ejemplo de migración de una aplicación Express 3 a Express 4. The files of interest are `app.js` and `package.json`.Aplicación versión 3
Consider an Express v.3 application with the following `app.js` file: ```js var express = require('express') var routes = require('./routes') var user = require('./routes/user') var http = require('http') var path = require('path') var app = express() // all environments app.set('port', process.env.PORT || 3000) app.set('views', path.join(__dirname, 'views')) app.set('view engine', 'pug') app.use(express.favicon()) app.use(express.logger('dev')) app.use(express.methodOverride()) app.use(express.session({ secret: 'your secret here' })) app.use(express.bodyParser()) app.use(app.router) app.use(express.static(path.join(__dirname, 'public'))) // development only if (app.get('env') === 'development') { app.use(express.errorHandler()) } app.get('/', routes.index) app.get('/users', user.list) http.createServer(app).listen(app.get('port'), () => { console.log('Express server listening on port ' + app.get('port')) }) ```app.js
El archivo `package.json` de la versión 3 correspondiente será similar al siguiente: ```json { "name": "application-name", "version": "0.0.1", "private": true, "scripts": { "start": "node app.js" }, "dependencies": { "express": "3.12.0", "pug": "*" } } ```package.json
Proceso
Para empezar el proceso de migración, instale el middleware necesario para la aplicación Express 4 y actualice Express y Pug a su versión respectiva más reciente con el siguiente mandato: ```bash $ npm install serve-favicon morgan method-override express-session body-parser multer errorhandler express@latest pug@latest --save ``` Realice los cambios siguientes en `app.js`: 1. Las funciones de middleware de Express incorporadas `express.favicon`, `express.logger`, `express.methodOverride`, `express.session`, `express.bodyParser` y `express.errorHandler` ya no están disponibles en el objeto `express`. Debe instalar sus alternativas manualmente y cargarlas en la aplicación. 2. Ya no es necesario cargar la función `app.router`. No es un objeto de aplicación Express 4 válido, por lo que debe eliminar el código `app.use(app.router);`. 3. Asegúrese de que las funciones de middleware se cargan en el orden correcto: cargue `errorHandler` después de cargar las rutas de aplicación.Aplicación versión 4
La ejecución del mandato `npm` anterior actualizará `package.json` de la siguiente manera: ```json { "name": "application-name", "version": "0.0.1", "private": true, "scripts": { "start": "node app.js" }, "dependencies": { "body-parser": "^1.5.2", "errorhandler": "^1.1.1", "express": "^4.8.0", "express-session": "^1.7.2", "pug": "^2.0.0", "method-override": "^2.1.2", "morgan": "^1.2.2", "multer": "^0.1.3", "serve-favicon": "^2.0.1" } } ```package.json
A continuación, elimine el código no válido, cargue el middleware necesario y realice otros cambios según sea necesario. El archivo `app.js` será parecido al siguiente: ```js var http = require('http') var express = require('express') var routes = require('./routes') var user = require('./routes/user') var path = require('path') var favicon = require('serve-favicon') var logger = require('morgan') var methodOverride = require('method-override') var session = require('express-session') var bodyParser = require('body-parser') var multer = require('multer') var errorHandler = require('errorhandler') var app = express() // all environments app.set('port', process.env.PORT || 3000) app.set('views', path.join(__dirname, 'views')) app.set('view engine', 'pug') app.use(favicon(path.join(__dirname, '/public/favicon.ico'))) app.use(logger('dev')) app.use(methodOverride()) app.use(session({ resave: true, saveUninitialized: true, secret: 'uwotm8' })) app.use(bodyParser.json()) app.use(bodyParser.urlencoded({ extended: true })) app.use(multer()) app.use(express.static(path.join(__dirname, 'public'))) app.get('/', routes.index) app.get('/users', user.list) // error handling middleware should be loaded after the loading the routes if (app.get('env') === 'development') { app.use(errorHandler()) } var server = http.createServer(app) server.listen(app.get('port'), () => { console.log('Express server listening on port ' + app.get('port')) }) ```app.js
A menos que necesite trabajar directamente con el módulo
http
(socket.io/SPDY/HTTPS), no es necesario cargarlo y la aplicación puede iniciarse simplemente de la siguiente manera:app.listen(app.get('port'), () => { console.log('Express server listening on port ' + app.get('port')) })
Run the app
El proceso de migración está completo y la aplicación es ahora una aplicación Express 4. Para confirmarlo, inicie la aplicación utilizando el siguiente mandato: ```bash $ node . ``` Cargue [http://localhost:3000](http://localhost:3000) y vea la página de inicio que representa Express 4.La actualización al generador de aplicaciones Express 4
La herramienta de línea de mandatos para generar una aplicación Express continúa siendo `express`, pero para actualizar a la nueva versión, debe desinstalar el generador de aplicaciones Express 3 e instalar el nuevo `express-generator`.Instalación
Si ya ha instalado el generador de aplicaciones Express 3 en el sistema, debe desinstalarlo: ```bash $ npm uninstall -g express ``` Dependiendo de cómo se configuren los privilegios de archivos y directorios, deberá ejecutar este mandato con `sudo`. A continuación, instale el nuevo generador: ```bash $ npm install -g express-generator ``` Dependiendo de cómo se configuren los privilegios de archivos y directorios, deberá ejecutar este mandato con `sudo`. Ahora el mandato `express` en el sistema se actualiza al generador de Express 4.Cambios en el generador de aplicaciones
Las opciones de mandato y el uso continúan prácticamente iguales, con las siguientes excepciones: {: .doclist } - Removed the `--sessions` option. - Removed the `--jshtml` option. - Se ha añadido la opción `--hogan` para dar soporte a [Hogan.js](http://twitter.github.io/hogan.js/).Ejecute el siguiente mandato para crear una aplicación Express 4: ```bash $ express app4 ``` Si consulta el contenido del archivo `app4/app.js`, observará que todas las funciones de middleware (excepto `express.static`) que son necesarias para la aplicación se cargan como módulos independientes y que el middleware de `router` ya no se carga de forma explícita en la aplicación. También observará que el archivo `app.js` es ahora un módulo Node.js, a diferencia de la aplicación autónoma que generaba el antiguo generador. Después de instalar las dependencias, inicie la aplicación utilizando el siguiente mandato: ```bash $ npm start ``` Si consulta el script de inicio npm en el archivo `package.json`, observará que el mandato que inicia la aplicación es `node ./bin/www`, que antes era `node app.js` en Express 3. Como el archivo `app.js` que generaba el generador de Express 4 ahora es un módulo Node.js, ya no puede iniciarse independientemente como una aplicación (a menos que modifique el código). El módulo debe cargarse en un archivo Node.js e iniciarse utilizando el archivo Node.js. El archivo Node.js es `./bin/www` en este caso. Ni el directorio `bin` ni el archivo `www` sin extensión son obligatorios para crear una aplicación Express o iniciar la aplicación. Son sólo sugerencias realizadas por el generador, por lo que puede modificarlos según sus necesidades. Para eliminar el directorio `www` y dejarlo todo como en "Express 3", suprima la línea `module.exports = app;` al final del archivo `app.js` y pegue el siguiente código en su lugar: ```js app.set('port', process.env.PORT || 3000) var server = app.listen(app.get('port'), () => { debug('Express server listening on port ' + server.address().port) }) ``` Asegúrese de cargar el módulo `debug` encima del archivo `app.js` utilizando el código siguiente: ```js var debug = require('debug')('app4') ``` A continuación, cambie `"start": "node ./bin/www"` en el archivo `package.json` por `"start": "node app.js"`. Ahora ha devuelto la funcionalidad de `./bin/www` a `app.js`. Este cambio no se recomienda, pero el ejercicio permite entender cómo funciona el archivo `./bin/www` y por qué el archivo `app.js` ya no se inicia solo.