Aquí hay un ejemplo: https://middy.js.org/docs/intro/getting-started
import middy from '@middy/core' import middleware1 from 'sample-middleware1' import middleware2 from 'sample-middleware2' import middleware3 from 'sample-middleware3' const lambdaHandler = (event, context) => { /* your business logic */ } export const handler = middy(lambdaHandler) handler .use(middleware1()) .use(middleware2()) .use(middleware3()) ¿Por qué exportar el handler primero y luego configurarlo en el mismo archivo en el que se definió?
Por extraño que parezca, usan diferentes patrones en diferentes ejemplos. Aqui hay otro más:
// import core import middy from '@middy/core' // esm Node v14+ //const middy = require('@middy/core') // commonjs Node v12+ // import some middlewares import jsonBodyParser from '@middy/http-json-body-parser' import httpErrorHandler from '@middy/http-error-handler' import validator from '@middy/validator' // This is your common handler, in no way different than what you are used to doing every day in AWS Lambda const lambdaHandler = async (event, context) => { // we don't need to deserialize the body ourself as a middleware will be used to do that const { creditCardNumber, expiryMonth, expiryYear, cvc, nameOnCard, amount } = event.body // do stuff with this data // ... const response = { result: 'success', message: 'payment processed correctly'} return {statusCode: 200, body: JSON.stringify(response)} } // Notice that in the handler you only added base business logic (no deserialization, // validation or error handler), we will add the rest with middlewares const eventSchema = { type: 'object', properties: { body: { type: 'object', properties: { creditCardNumber: { type: 'string', minLength: 12, maxLength: 19, pattern: '\\d+' }, expiryMonth: { type: 'integer', minimum: 1, maximum: 12 }, expiryYear: { type: 'integer', minimum: 2017, maximum: 2027 }, cvc: { type: 'string', minLength: 3, maxLength: 4, pattern: '\\d+' }, nameOnCard: { type: 'string' }, amount: { type: 'number' } }, required: ['creditCardNumber'] // Insert here all required event properties } } } // Let's "middyfy" our handler, then we will be able to attach middlewares to it const handler = middy() .use(jsonBodyParser()) // parses the request body when it's a JSON and converts it to an object .use(validator({eventSchema})) // validates the input .use(httpErrorHandler()) // handles common http errors and returns proper responses .handler(lambdaHandler)Dondequiera que aparezca la declaración de export para un identificador en un archivo dado, no tiene ningún efecto en nada, incluso en cómo/cuándo otros módulos interactúan con él. No hay diferencia entre
export const handler = middy(lambdaHandler) handler .use(middleware1()) .use(middleware2()) .use(middleware3())y
const handler = middy(lambdaHandler) handler .use(middleware1()) .use(middleware2()) .use(middleware3()) export { handler };excepto que el segundo requiere un poco más de código (por lo que algunos prefieren el primer enfoque).
Es un poco similar a var . No importa dónde var <someVarName> en un bloque dado, lo único que le importa al motor es que se haya declarado someVarName en el bloque, no dónde está la línea con var . De manera similar, con las exportaciones, todo lo que le importa al motor es si algo se exportó, no dónde se encuentra la palabra clave de export .
¿Node de alguna manera asegura que todas las exportaciones ocurran después de todo lo demás?
Sí, en su mayoría. Después de importar, un script de módulo siempre ejecutará todo su código (de nivel superior) hasta el final antes de que cualquier otro módulo comience a ejecutar su código (de nivel superior). Si hay
console.log('1'); // 5000 lines of code export const foo = 'foo'; // 500 lines of code console.log('2'); Cualquier otro módulo que use foo solo lo hará después de que se hayan registrado 1 y 2 .
(La única excepción para garantizar que todo se haya exportado correctamente antes de que otros módulos los usen son las dependencias circulares, que estropean las cosas: con las dependencias circulares, si un módulo importa otro y ese otro módulo importa el primero, uno de esos no lo hará). se inicializará cuando el otro comience a ejecutar su código de nivel superior, pero la ubicación de la palabra clave de export aún no tiene impacto)
La declaración de
exportse utiliza al crear módulos de JavaScript para exportar enlaces en vivo a funciones, objetos o valores primitivos. MDN: exportar
Live bindings es un concepto introducido en los módulos ES. Significa que cuando el módulo de exportación cambia un valor, el cambio será visible desde el lado del importador. ASI QUE
En mi opinión, es como hacer una referencia a un objeto y luego editar el objeto original. Cualquier cambio se reflejará al llamar a la referencia:
const a = {foo:'foo'} const c = a; // Imagine this is the export and import in another file a.foo = 'bar'; console.log(c.foo) // 'bar' - the change is reflected in the import La cosa aquí es que la export no es como el return que finaliza la ejecución. El código después de la exportación aún se ejecuta. Ejemplo de JSBin.
El objeto exportado se puede considerar global dondequiera que se importe, por lo que si nuestro script de importación modifica aún más los objetos, estos cambios también se reflejarán en el objeto global.
Podría ser útil pensar en ello como un singleton .