SOLVED: The problem was that webpack changes the default behavior of __dirname and you have to configure it so that the routes work for me. I added this:
context: __dirname,
node:{
__dirname: true //The "dirname" of the input file relative to the
context option.
},
The problem is this:
I have created a class to facilitate the use of nodemailer with nodejs. Everything works fine, but when loading the template with the node's fs module, it tells me that the path does not exist. I have tried it using simply the node module "fs" with the file I want to load, in a separate file and it works correctly. I leave the class to see if you can help me out.
class Mailer {
constructor({ subject }){
this.emailOptions = {}
this.emailOptions.subject = subject
this.emailOptions.from = 'Yo <[email protected]>'
}
/*
* Seteamos el transport por defecto
*/
setAdminTransport(){
//Configuracion del Transport GMAIL
let transport = nodemailer.createTransport({
service: 'Gmail',
auth: {
type: 'OAuth2',
user: '[email protected]',//Email de Gmail
clientId: key.GMAIL_CLIENT_ID,
clientSecret: key.GMAIL_CLIENT_SECRET,
refreshToken: key.GMAIL_REFRESH_TOKEN
}
})
this.transport = transport
return this
}
/*
* Seteamos la template y sustituimos las variables
* tplName - String
* vars - { }
*/
setTemplate(tpl, variables = ''){
//Leemos el HTML de la template'verify_email.html'. esta template
//esta al mismo nivel que la clase Mailer.
fs.readFile(path.resolve(__dirname, 'verify_email.html'), 'utf8', (err, data) => {
if (err) console.log(err);
let vars = { name:'Daniella', telefono:'61229333' }
//sustituir las variables en la template -> {{ variable }}
for(var key in vars){
var data = data.replace('{{${key}}}', vars[key])
}
//Seteamos la template con las variables seteadas
this.template = data
})
return this;
}
getTemplate(){
return this.template
}
/*
* Un Array con todos los recipients que queremos enviar el email
* recipients - []
*
*/
setRecipients(recipients = []){
// [ { name: '', address:'' } ]
this.recipients = recipients
return this;
}
getRecipients(){
return this.recipients
}
/*
* Enviamos el Email por cada recipient
* tplName - String
* vars - { }
*/
send(){
//Por cada recipient tenemos que enviar un email
let recipients = this.getRecipients()
//Por cada Recipient, enviamos un Email
recipients.forEach(recipient => {
//seteamos this.emailOptions
this.emailOptions.to = recipient.address
this.emailOptions.html = this.template //cargamos la Template HTML
//enviamos el email
this.transport.sendMail(this.emailOptions, (err, info) => {
if (err) throw new Error(err)
console.log('Email enviado a ${this.emailOptions.to} con exito!')
})
})
this.transport.close()
}
}
export default Mailer
This class I call from a route like this:
router.get('/test', (req, res) => {
let mail = new Mailer({subject: 'Test Nodemailer 2.0'})
mail.setAdminTransport()
.setTemplate('verify_email', {name:'Daniella', telefono:'6173333'})
.setRecipients([ { name: 'Yo', address:'[email protected]' } ])
.send()
res.json({ok:'ok'})
})
This is the error that gives me:
GET /email/test 200 17.660 ms - 11
[0] { Error: ENOENT: no such file or directory, open '/verify_email.html'
[0] errno: -2,
[0] code: 'ENOENT',
[0] syscall: 'open',
[0] path: '/verify_email.html' }
[0] webpack:///./services/mailer.js?:78
[0] var data = data.replace('{{' + key + '}}', vars[key]);
[0] ^
[0]
[0] TypeError: Cannot read property 'replace' of undefined
[0] at ReadFileContext.eval [as callback]
(webpack:///./services/mailer.js?:78:21)
[0] at FSReqWrap.readFileAfterOpen [as oncomplete] (fs.js:336:13)
WHEN CREATING THIS SCRIPT IN AN ARCHIVE, IT WORKS PERFECTLY: The complete path of my project is: app / services / mailer / template / verify_email.html this file that works for me is in the root
const fs = require('fs')
fs.readFile('./services/mailer/template/verify_email.html','utf8',(err, data) => {
if (err) console.log(err);
var vars = {
nombre: 'MI NOMBRE',
telefono: '629648643432'
}
for(var key in vars){
var data = data.replace('{{${key}}}', vars[key])
}
//ESTO FUNCIONA PERFECTAMENTE Y ME CARGA LA TEMPLATE SUSTITUYENDO LAS VARIABLES
console.log(data)
})