nest-modules / mailer

📨 A mailer module for Nest framework (node.js)
https://nest-modules.github.io/mailer/
MIT License
846 stars 177 forks source link

"no such file or directory" when trying to read a template #494

Closed RRGT19 closed 10 months ago

RRGT19 commented 3 years ago

The same issue as this one, this issue is closed so, I'm creating a new one.

Error: UnhandledPromiseRejectionWarning: Error: ENOENT: no such file or directory, open '/my-awesome-project/dist/assets/templates/welcome.hbs'

package.json

{
  "scripts": {
    "prebuild": "rimraf dist",
    "build:dev": "NODE_ENV=dev nest build",
    "start": "nest start",
    "start:dev": "NODE_ENV=dev nest start --watch",
  },
  "dependencies": {
    "@nestjs-modules/mailer": "^1.5.1",
    "@nestjs/common": "^7.5.1",
    "@nestjs/config": "^0.6.1",
    "@nestjs/core": "^7.5.1",
    "@nestjs/mapped-types": "^0.1.1",
    "@nestjs/platform-express": "^7.5.1",
    "@nestjs/typeorm": "^7.1.5",
    "dotenv": "^8.2.0",
    "handlebars": "^4.7.6",
    "nodemailer": "^6.4.17",
    "reflect-metadata": "^0.1.13",
    "rimraf": "^3.0.2",
    "rxjs": "^6.6.3",
    "typeorm": "^0.2.29"
  },
  "devDependencies": {
    "@nestjs/cli": "^7.5.1",
    "@nestjs/schematics": "^7.1.3",
    "@nestjs/testing": "^7.5.1",
    "@types/express": "^4.17.8",
    "@types/jest": "^26.0.15",
    "@types/node": "^14.14.6",
    "@types/nodemailer": "^6.4.0",
    "@types/supertest": "^2.0.10",
    "@typescript-eslint/eslint-plugin": "^4.6.1",
    "@typescript-eslint/parser": "^4.6.1",
    "eslint": "^7.12.1",
    "eslint-config-prettier": "7.1.0",
    "eslint-plugin-prettier": "^3.1.4",
    "jest": "^26.6.3",
    "prettier": "^2.1.2",
    "supertest": "^6.0.0",
    "ts-jest": "^26.4.3",
    "ts-loader": "^8.0.8",
    "ts-node": "^9.0.0",
    "tsconfig-paths": "^3.9.0",
    "typescript": "^4.0.5"
  },
}

nest-cli.json

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "assets": [ // <= I receive error here: Incompatible types. Required: string. Actual: object.
      {
        "include": "**/*.hbs",
        "watchAssets": true
      }
    ]
  }
}

application structure

|-- my-awesome-app
     |-- dist
     |-- env
     |-- node_modules
     |-- src
     |-- templates
          |-- account
               |-- welcome.hbs
          |-- transaction
               |-- new-transaction.hbs

MailerOptions

  createMailerOptions(): Promise<MailerOptions> | MailerOptions {
    return {
      transport: {
        host: 'smtp.gmail.com',
        port: 587,
        secure: false,
        auth: {
          user: 'bla@gmail.com',
          pass: '123456',
        },
      },
      defaults: {
        from:'"nest-modules" <modules@nestjs.com>',
      },
      template: {
        // I have tried with all these:
        // dir: __dirname + '/templates',
        // dir: path.resolve(__dirname, '..', '..', 'templates'),
        // dir: process.cwd() + '/templates/',
        // dir: resolve(process.cwd(), 'dist/templates'),
        adapter: new HandlebarsAdapter(),
        options: {
          strict: true,
        },
      },
    };
  }

Send email method:

  sendNewAccountCreated(to: string, subject: string): Promise<any> {
    return this.mailerService.sendMail({
      to: to,
      from: 'bla@gmail.com,
      subject: subject,
      template: 'welcome', // The `.hbs` extension is appended automatically.
      context: {  // Data to be sent to template engine.
        code: 'cf1a3f828287',
        username: 'john doe',
      },
    });
  }

My issues:

  1. The .hbs files are not copied to the dist folder.
  2. Watch mode is not reacting to changes (creation of new templates).
  3. The path to read the template from is always weird and I cannot get it right.

Any help would be appreciated.

Gargamil commented 3 years ago

Got it working by setting the correct dir in template options.

To copy the email-templates to dist: Search in your project config for the assets folder. This will be copied to dist. Add to the config also the your email-template folder.

GerkinDev commented 3 years ago

Seeing code from https://github.com/nest-modules/mailer/blob/1df331559aced871d18354d7ad6f976ee6aa6496/lib/adapters/handlebars.adapter.ts#L38-L41, templates inside the directory pointed by the template.dir options are expected to be prefixed with ./. This is actually a bug with fix pending in 9bee48b0e630c71c3702b83747dc41152670947e, that will be shipped in version >=1.6.1

Nightbr commented 3 years ago

any idea when we could have a release to get the fix? Thanks for your help!

ghost commented 2 years ago

I got it to work by stating the full path to template mailService like this

this.mailerService.sendMail({
  to: to,
  from: 'bla@gmail.com,
  subject: subject,
  template: path.join(process.cwd(), 'dist', 'mail', 'templates', `${template}.ejs`),
  context: {
    otp: generatedOTP,
  },
});

But I'm still looking for a way to make it work using the dir option in module.

miladezzat commented 2 years ago

I got it to work by stating the full path to template mailService like this

this.mailerService.sendMail({
  to: to,
  from: 'bla@gmail.com,
  subject: subject,
  template: path.join(process.cwd(), 'dist', 'mail', 'templates', `${template}.ejs`),
  context: {
    otp: generatedOTP,
  },
});

But I'm still looking for a way to make it work using the dir option in module.

This Works with me

SyedAsimAliSE commented 2 years ago

Is any one still having this issue, I resolved it by adding "$schema": "https://json.schemastore.org/nest-cli", non of the other solutions worked until I added this tag.

{
  "$schema": "https://json.schemastore.org/nest-cli",
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "assets": [{ "include": "config/mail/templates/**/*", "outDir": "dist" }],
    "watchAssets": true
  }
}
mortocks commented 2 years ago

Can confirm that using the full path works, however would like to see a real fix for this

MazueraAlvaro commented 1 year ago

I managed to solve it setting the outDir to dist/src

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "assets": [{ "include": "config/mail/templates/**/*", "outDir": "dist/src" }],
    "watchAssets": true
  }
}
joelorzet commented 1 year ago

I managed to solve it setting the outDir to dist/src

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "assets": [{ "include": "config/mail/templates/**/*", "outDir": "dist/src" }],
    "watchAssets": true
  }
}

This worked for me! thx :D

pryme0 commented 1 year ago
process.cwd(),

This worked for me

YacineSteeve commented 2 months ago

I managed to solve it setting the outDir to dist/src

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "assets": [{ "include": "config/mail/templates/**/*", "outDir": "dist/src" }],
    "watchAssets": true
  }
}

Worked perfectly fine 💯