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

.hbs files are not copied to dist folder #42

Closed hug0b closed 5 years ago

hug0b commented 5 years ago

Node.js 10.16.0 @nest-modules/mailer 1.1.3 nestjs 6.5.2

When sending an email using handlebars I get the following error:

[Nest] 26182   - 2019-07-29 3:41 PM   [ExceptionsHandler] ENOENT: no such file or directory, open '/var/www/html/backend-api/dist/common/templates/emails/resetPassword.hbs' +1411ms
[0] Error: ENOENT: no such file or directory, open '/var/www/html/backend-api/dist/common/templates/emails/resetPassword.hbs'
[0]     at Object.openSync (fs.js:443:3)
[0]     at Object.readFileSync (fs.js:343:35)
[0]     at HandlebarsAdapter.compile (/var/www/html/backend-api/node_modules/@nest-modules/mailer/dist/adapters/handlebars.adapter.js:19:37)
[0]     at MailerService.transporter.use (/var/www/html/backend-api/node_modules/@nest-modules/mailer/dist/mailer.service.js:44:40)
[0]     at processPlugins (/var/www/html/backend-api/node_modules/nodemailer/lib/mailer/index.js:279:13)
[0]     at err (/var/www/html/backend-api/node_modules/nodemailer/lib/mailer/index.js:283:17)
[0]     at Mail._convertDataImages (/var/www/html/backend-api/node_modules/nodemailer/lib/mailer/index.js:387:20)
[0]     at Mail._defaultPlugins.compile.args (/var/www/html/backend-api/node_modules/nodemailer/lib/mailer/index.js:31:41)
[0]     at processPlugins (/var/www/html/backend-api/node_modules/nodemailer/lib/mailer/index.js:279:13)
[0]     at Mail._processPlugins (/var/www/html/backend-api/node_modules/nodemailer/lib/mailer/index.js:287:9)

Mailer config

MailerModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    transport: `smtps://${configService.get(
      'MAILER_EMAIL',
    )}:${configService.get('MAILER_PASSWORD')}@${configService.get(
      'MAILER_HOST',
    )}`,
    defaults: {
      from: '"nest-modules" <modules@nestjs.com>',
    },
    template: {
      dir: path.join(__dirname, 'common/templates/emails'),
      adapter: new HandlebarsAdapter(),
      options: {
        strict: true,
      },
    },
  }),
  inject: [ConfigService],
})
hug0b commented 5 years ago

Oh well I figured templates need to be outside of the src folder

humbertowoody commented 5 years ago

Hello! How did you structured your project for transpilation from /src/templates to /dist/templates or /templates/ to /dist/templates? Thanks in advance!

hug0b commented 5 years ago

@humbertowoody Like I wrote in my comment I put them in a folder outside of src, at the root of the project.

RenaldoV commented 4 years ago

Hi There, I put the templates folder in the root of the project and my app Module configures the mailer as follows:

imports: [
    MailerModule.forRootAsync({
      useFactory: () => ({
        transport: 'smtps://user@domain.com:pass@smtp.domain.com',
      defaults: {
        from:'"nest-modules" <modules@nestjs.com>',
      },
        template: {
          dir: __dirname + '/templates',
          adapter: new HandlebarsAdapter(),
          options: {
            strict: true,
          },
        },
      }),
    }),

I have a file in the Root/templates/mailer.hbs

Here is the code for sending the email:

mailerService .sendMail({ to: toMail, subject, template: 'mailer', // The.pugor.hbsextension is appended automatically. context: { // Data to be sent to template engine. body, link, btn, }, });

I'm still getting the error that implies that the templates folder is not transpiled to the dist folder.

What could the problem possibly be?

masza commented 4 years ago

@RenaldoV did you figure it out how to do this? I have similar issue.

bellib commented 4 years ago

Same problem !!

bellib commented 4 years ago

When Nestjs compiling files didn't copied template to dist

fransyozef commented 4 years ago

So I got it running. The trick is to copy the template files to the dist folder after it's compiled.

My steps

1) Add path to app.module.ts

import * as path from 'path';

2) my template object:

      template: {
        dir: path.join(__dirname, 'templates'),
        adapter: new HandlebarsAdapter(),
        options: {
          strict: true,
        },
      },

3) Created a folder "templates" in the "src" folder and put my .hbs in there

4) Install npm module: cpx

5) Create a npm run command to copy the templates in package.json

"copy:templates": "cpx './src/templates/**' 'dist/templates'"

6) run the copy command after the the build

"build": "rimraf dist && tsc -p tsconfig.build.json && npm run copy:templates",

Now when I do npm run build , the templates are copied in the dist folder. yay!

Armanoide commented 4 years ago

I found a easy way to use without copy to dist folder.

 const path = `${__dirname.split('dist')[0]}/x/src/common/templates`;
    this
      .mailerService
      .sendMail({
        to: 'x@x.com',
        from: 'noreply@x.com',
        subject: 'test', 
        template: `${path}/test.hbs`,
        context: {
          code: 'cf1a3f828287',
          username: 'john doe',
        },
      })
      .then(() => {})
      .catch((e) => {
        Logger.error(e);
      });
fransyozef commented 4 years ago

I found a easy way to use without copy to dist folder.

 const path = `${__dirname.split('dist')[0]}/x/src/common/templates`;
    this
      .mailerService
      .sendMail({
        to: 'x@x.com',
        from: 'noreply@x.com',
        subject: 'test', 
        template: `${path}/test.hbs`,
        context: {
          code: 'cf1a3f828287',
          username: 'john doe',
        },
      })
      .then(() => {})
      .catch((e) => {
        Logger.error(e);
      });

Hmm I will try this. Not sure if it will work on Zeit Now. In order to make it work on Zeit Now, I need to build the Nest application first before uploading to Zeit Now and then Zeit Now will serve from dist/ folder.

But the problem is that when building the dist package on local, the templates are not copied into the dist package therefore they are not uploaded (even if I put it in src/ )

ghost commented 4 years ago

Actually there is an easier way to handle this.

nest comes with its own cli that can handle these kind of processes.

So in my configuration, I am using .hbs which is staying inside src/templates/[container]/[some-example-template].hbs

with modifying nest-cli.json file as given below, when the code is compiled templates folder structure is transfered to dist folder as intended.

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "assets": ["**/*.hbs"]
  }
}
fransyozef commented 4 years ago

@musyilmaz oh nice!!!! this works like a charm!

ghost commented 4 years ago

@fransyozef nice that it worked :) I think, adding this to readme and expanding the documentation might be a correct way.

VictorAssis commented 4 years ago

Just complementing @musyilmaz solution (thanks for that), for default the compiler just copy the files to dist folder only when start. So if you change a template (when the project is runing in dev mode), its necessary to stop the compiler and start again to update the file in dist folder.

To enable the assets copy in watch mode, add the flag "watchAssets" to compilerOptions in nest-cli.json:

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "assets": ["**/*.hbs"],
    "watchAssets": true
  }
}

If you have more than one asset and don't want to turn on watch mode to all, its possible to turn on just in the templates:

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "assets": [
      { "include": "**/*.hbs", "watchAssets": true },
      { "include": "**/*.txt" }
    ]
  }
}

Like @musyilmaz said, I think this is important to be in documentation too.

My reference: https://docs.nestjs.com/cli/monorepo#assets

ruslanguns commented 4 years ago

@VictorAssis Watch mode does hear the changes from the .hbs files ? because it is not in my case, only if I create new files it hears but not the changes in self.

VictorAssis commented 4 years ago

@ruslanguns By default Watch mode does not update .hbs files as they are changed. I managed to solve this by adding the above settings to nest-cli.json.

ruslanguns commented 4 years ago

yes, I actually have modified the nest-cli.json in order to add them, however typescript only updates/watch when I create a new file with extension .hbs BUT NOT the code changes in the files. Do you have the same issue or it's only me?

VictorAssis commented 4 years ago

I am not having this problem here. Can you send your nest-cli.json and your package.json here?

SamiSammour commented 4 years ago

@VictorAssis I'm having the same issue with .ejs files.. when I update the contents of a .ejs file it does not detects it and it does not restart the app. Here's the contents of my nest-cli.json:

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "assets": ["**/*.ejs"]
  },
  "watchAssets": true
}

and here's the contents for my package.json:

{
  "name": "coachspace-backend",
  "version": "0.0.1",
  "private": true,
  "license": "UNLICENSED",
  "scripts": {
    "prebuild": "rimraf dist",
    "build": "nest build",
    "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
    "start": "nest start",
    "start:dev": "nest start --watch",
    "start:debug": "nest start --debug --watch",
    "start:prod": "node dist/main",
    "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:cov": "jest --coverage",
    "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
    "test:e2e": "jest --config ./test/jest-e2e.json"
  },
  "dependencies": {
    "@alphaapps/nestjs-auth": "^1.2.93",
    "@alphaapps/nestjs-common": "^1.2.97",
    "@alphaapps/nestjs-config": "^1.2.68",
    "@alphaapps/nestjs-db": "^1.2.68",
    "@hapi/joi": "^17.1.1",
    "@nestjs/common": "^7.3.2",
    "@nestjs/core": "^7.3.2",
    "@nestjs/jwt": "^7.1.0",
    "@nestjs/passport": "^7.1.0",
    "@nestjs/platform-express": "^7.3.2",
    "@nestjs/sequelize": "^0.1.0",
    "@nestjs/swagger": "^4.5.12",
    "@nestjsx/crud": "^4.6.2",
    "@nestjsx/crud-request": "^4.6.2",
    "@sentry/node": "^5.20.1",
    "@shelf/winston-datadog-logs-transport": "^2.0.0",
    "accesscontrol": "^2.2.1",
    "aws-sdk": "^2.721.0",
    "axios": "^0.20.0",
    "bcrypt": "^5.0.0",
    "class-transformer": "^0.2.3",
    "class-validator": "^0.12.2",
    "config": "^3.3.1",
    "debug": "^4.1.1",
    "ejs": "^3.1.5",
    "express-rate-limit": "^5.1.3",
    "firebase-admin": "^9.0.0",
    "google-libphonenumber": "^3.2.10",
    "hashids": "^2.2.1",
    "lodash": "^4.17.19",
    "mime-types": "^2.1.27",
    "moment": "^2.27.0",
    "nest-access-control": "^2.0.2",
    "nest-router": "^1.0.9",
    "nest-winston": "^1.3.6",
    "passport": "^0.4.1",
    "passport-anonymous": "^1.0.1",
    "passport-jwt": "^4.0.0",
    "pg": "^8.3.0",
    "rate-limit-redis": "^2.0.0",
    "reflect-metadata": "^0.1.13",
    "rxjs": "^6.6.0",
    "sequelize": "5.21.12",
    "sequelize-typescript": "^1.1.0",
    "swagger-ui-express": "^4.1.4",
    "twilio": "^3.49.0",
    "winston": "^3.3.3",
    "winston-daily-rotate-file": "^4.5.0",
    "winston-transport": "^4.4.0"
  },
  "devDependencies": {
    "@nestjs/cli": "^7.5.1",
    "@nestjs/schematics": "^7.0.1",
    "@nestjs/testing": "^7.3.2",
    "@types/bcrypt": "^3.0.0",
    "@types/express": "^4.17.7",
    "@types/google-libphonenumber": "^7.4.19",
    "@types/hapi__joi": "^17.1.4",
    "@types/jest": "26.0.7",
    "@types/jsonwebtoken": "^8.5.0",
    "@types/mime-types": "^2.1.0",
    "@types/node": "^14.0.26",
    "@types/sequelize": "^4.28.8",
    "@types/supertest": "^2.0.10",
    "@typescript-eslint/eslint-plugin": "3.7.1",
    "@typescript-eslint/parser": "3.7.1",
    "chalk": "^4.1.0",
    "chalk-table": "^1.0.2",
    "eslint": "7.5.0",
    "eslint-config-airbnb-base": "^14.2.0",
    "eslint-plugin-import": "^2.22.0",
    "jest": "26.1.0",
    "prettier": "^2.0.5",
    "nestjs-command": "^1.5.0",
    "rimraf": "^3.0.2",
    "sequelize-cli": "^5.5.1",
    "supertest": "^4.0.2",
    "ts-jest": "26.1.3",
    "ts-loader": "^8.0.1",
    "ts-node": "^8.10.2",
    "tsc-watch": "^4.2.9",
    "tsconfig-paths": "^3.9.0",
    "typescript": "^3.9.7"
  },
  "jest": {
    "moduleFileExtensions": [
      "js",
      "json",
      "ts"
    ],
    "rootDir": "src",
    "testRegex": ".spec.ts$",
    "transform": {
      "^.+\\.(t|j)s$": "ts-jest"
    },
    "coverageDirectory": "../coverage",
    "testEnvironment": "node"
  }
}

I'm calling the npm run start:dev command in dev mode.

VictorAssis commented 4 years ago

@SamiSammour your "watchAssets" option is out of "compilerOptions", maybe this is the reason. Try this:

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "assets": ["**/*.ejs"],
    "watchAssets": true
  },
}
Yurko-Fedoriv commented 3 years ago

In case anyone lands here: As of now for "@nestjs-modules/mailer": "^1.6.0" even with properly configured watchAssets you won't see changes in templates. The reason is here:

So templates are only compiled once per application run and currently, there is no way to change this behaviour. And the application does not reload on assets change. I did not go the route of figuring out how to make it reload. Instead, I have yielded this possible solution with a minimal hack:

import { HandlebarsAdapter } from '@nestjs-modules/mailer/dist/adapters/handlebars.adapter';
import { MailerOptions } from '@nestjs-modules/mailer';

export class CustomEmailHandlebarsAdapter extends HandlebarsAdapter {
  compile(mail: any, callback: any, mailerOptions: MailerOptions) {
    super.compile(
      mail,
      (res) => {
        if (mailerOptions.template.options.disableTemplateCache) {
          //@ts-ignore
          this.precompiledTemplates = {}
        }

        if (typeof callback === 'function') {
          callback(res)
        }
      },
      mailerOptions
    );
  }
}

Afterwards, it is possible to configure mailer template sections as such:

template: {
  adapter: new CustomEmailHandlebarsAdapter(),
  options: {
    strict: true,
    disableTemplateCache: config.get('NODE_ENV') === 'development'
  },
},
ldulcic commented 3 years ago

I had a problem where templates where copied to dist folder instead of dist/src. I updated nest-cli.json to make it work:

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

outDir tells compiler to copy templates to dist/src folder, it works now.

sharon-asana commented 3 years ago

i'm using serverless and the templates are not included in the deployment package that is copied to AWS.

i've updated the nest-cli.json to look like this:

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

what am i doing wrong?

nzediegwu1 commented 3 years ago

The problem I discovered is that SOMETIMES nest build command doesn't read the include path correctly when it ends with a file extension. So instead of doing:

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "plugins": ["@nestjs/swagger"],
    "assets": [
      {
        "include": "**/mail/template/**/*.hbs",
        "outDir": "dist/src",
        "watchAssets": true
      }
    ]
  }
}

Do

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

In my observation, when it ends with .hbs, it copied the files successfully some times, but when I removed the .hbs, the files are copied successfully all times

tamirazrab commented 3 years ago

I had no nest-cli.json by default using NX monorepo, Created json file manually, tried everything. Then I ended up manually copying the template to dist folder and it worked. I don't know if it's right approach or not.

florianmartens commented 2 years ago

This is quite ugly code but might be helpful to some. I've reverted to simply using two paths for my template directories. During development, I will use my non-dist folder and for production purposes, I will use the corresponding dist folder. Of course, this comes with its own caveats (Can we guarantee that dev and prod will match?).

This way it works for me and I find it ugly but manageable:

Example use

const compiledFunction = compileFile(
            process.env.NODE_ENV === 'development'
                ? `${process.cwd()}/src/digest/templates/editor.content-list.pug`
                : path.join(
                      path.dirname(path.dirname(__dirname)),
                      'digest/templates/editor.content-list.pug',
                  ),
        );

nest-cli.json

{
    "collection": "@nestjs/schematics",
    "sourceRoot": "src",
    "compilerOptions": {
        "assets": ["**/*.pug"],
        "watchAssets": true
    }
}
RamenSayami commented 2 years ago

Actually there is an easier way to handle this.

nest comes with its own cli that can handle these kind of processes.

So in my configuration, I am using .hbs which is staying inside src/templates/[container]/[some-example-template].hbs

with modifying nest-cli.json file as given below, when the code is compiled templates folder structure is transfered to dist folder as intended.

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "assets": ["**/*.hbs"]
  }
}

That worked for a fresh monolith project.. Do you have any idea about a monorepo application?. it is not working there :(

BetterLuke commented 2 years ago

实际上有一种更简单的方法来处理这个问题。 nest 带有自己的 cli 可以处理这些类型的进程。 所以在我的配置中,我使用的是留在里面的 .hbssrc/templates/[container]/[some-example-template].hbs 通过如下所示修改 nest-cli.json 文件,当编译代码时,模板文件夹结构按预期传输到 dist 文件夹。

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "assets": ["**/*.hbs"]
  }
}

这适用于一个新的单体项目。你对 monorepo 应用程序有任何想法吗?它在那里不起作用:(

Hi, bro, Have you solved this problem?

RamenSayami commented 2 years ago

实际上有一种更简单的方法来处理这个问题。 nest 带有自己的 cli 可以处理这些类型的进程。 所以在我的配置中,我使用的是留在里面的 .hbssrc/templates/[container]/[some-example-template].hbs 通过如下所示修改 nest-cli.json 文件,当编译代码时,模板文件夹结构按预期传输到 dist 文件夹。

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "assets": ["**/*.hbs"]
  }
}

这适用于一个新的单体项目。你对 monorepo 应用程序有任何想法吗?它在那里不起作用:(

Hi, bro, Have you solved this problem?

I could not get nest to do the auto copy into the dist folder for monorepo applications. So, I instead made a workaround writing scripts in package.json like so:

{
  "name": "someProject",
  "version": "0.0.1",
  "scripts": {
    "start:all": "concurrently \"nest start admin --watch\" \"nest start customer --watch\" \"npm run copy:admin\" \"npm run copy:customer\"", ## call copy:admin and copy:customer from scripts below

    "copy:admin": "mkdir .\\dist\\apps\\admin\\templates && cp.exe -R libs/common/src/email/templates/* dist/apps/admin/templates/  ", ## actual workaround to make directory and copy files from templates folder to dist folder
    "copy:customer": "mkdir .\\dist\\apps\\customer\\templates && cp.exe -R libs/common/src/email/templates/* dist/apps/customer/templates/" ## actual workaround to make directory and copy files from templates folder to dist folder

    "start:customer": "nest start customer --watch",
    "start:admin": "nest start admin --watch",

    "build": " npm run build:customer && npm run build:admin",
    "build:customer": "nest build customer && cp.exe package.json dist/apps/customer/ && npm run copy:customer",
    "build:admin": "nest build admin && cp.exe package.json dist/apps/admin/ && npm run copy:admin",

  },
  "dependencies": {
    "@nestjs/common": "^8.0.0",
    "@nestjs/core": "^8.0.0",
    "concurrently": "^7.1.0"  ## Added concurrently to run admin/customer module concurrently
  }
}
BetterLuke commented 2 years ago

@RamenSayami Hi, bro, I may have found an easier way:

we should update workspace.json to make nx auto copy assets files to dist folder . Please try it :D

image

inspired by: https://nx.dev/nx-plugin/overview#including-assets

RaiMX commented 2 years ago

For those of you who get error that file not found error.

So, I'll try to put some clarifications too, because it took me 3 hours to figure out!!! Here is what worked for me.

For example you have following structure

.
├── project
│   └── src
│       └── mymodule
│           ├── templates
│           │   └── myemail.hbs
│           └── app.module.ts <== here you import MailerModule
└── ...

nest-cli.json

{
    "collection": "@nestjs/schematics",
    "sourceRoot": "src",
    "compilerOptions": {
        "assets": ["**/*.hbs"],
        "watchAssets": true
    }
}
//app.module.ts

...
MailerModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: (configService: ConfigService) => ({
        ...
        template: {
          // __dirname = is current COMPILED JS file directory, for example /app/dist
          // put email templates (*.hbs) in template root directory, no SUBDIRECTORIES in templates root directory!!!
          // when sending emails, template name must be just 'templatename' (without ./ or /)
          dir: __dirname + '/mymodule/templates',
          adapter: new HandlebarsAdapter(),
          options: {
            strict: true,
          },
        },
      }),
      inject: [ConfigService],
    }),
...

Somewhere in your service

this.mailerService.sendMail({
...
    template: 'myemail', // NO preceding "./"
...
})
kaykhan commented 2 years ago

Now i get this

error TS5023: Unknown compiler option 'assets'.

Looks like we can no longer use assets in the tsconfig compileroptions?

alxestevam commented 2 years ago

Now i get this

error TS5023: Unknown compiler option 'assets'.

Looks like we can no longer use assets in the tsconfig compileroptions?

I think you are using the wrong file to add the compilerOptions configuration. You have to put the configuration inside of nest-cli.json file

kaykhan commented 2 years ago

yes im using tsconfig.json does it not work there?

alxestevam commented 2 years ago

yes im using tsconfig.json does it not work there?

No, It has to be in nest-cli.json 🙁 . Are you using NestJS right?

SyedAsimAliSE commented 2 years ago

It hit me in the face today when I moved one of our mailing micro service.

here's how I solved it.

nestcli.json to copy the folder to dist location.

{
  "$schema": "https://json.schemastore.org/nest-cli",
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "assets": [{ "include": "concerns/mail/templates/**/*", "outDir": "dist/src/" }],
    "watchAssets": true
  }
}
template: {
// For some reason this stopped working don't know why 
//path.resolve(__dirname, "templates"),
// i have to manually resolve path
  dir: join(__dirname, '..', 'mail', 'templates'),
  adapter: new HandlebarsAdapter(),
  options: {
     strict: true
  },
},
joaowillamy commented 1 year ago

I was using a NX monorepo with nestjs and I have to configure the webpack using a plugin for it

const { composePlugins, withNx } = require('@nrwl/webpack'); const path = require("path"); const HandlebarsPlugin = require("handlebars-webpack-plugin");

thats solve my problem

// Nx plugins for webpack.
module.exports = composePlugins(withNx(), (config) => {
  // Update the webpack config as needed here.
  // e.g. `config.plugins.push(new MyPlugin())`
  config.plugins.push(new HandlebarsPlugin({
    // path to hbs entry file(s). Also supports nested directories if write path.join(process.cwd(), "app", "src", "**", "*.hbs"),
    entry: path.join(process.cwd(), "apps", "api", "src", "app", "mailer", "templates", "*.hbs"),
    // output path and filename(s). This should lie within the webpacks output-folder
    // if ommited, the input filepath stripped of its extension will be used
    output: path.join(process.cwd(), "dist", "apps", "api", "templates", "[name].hbs"),
    // you can also add a [path] variable, which will emit the files with their relative path, like
    // output: path.join(process.cwd(), "build", [path], "[name].html"),
  }))
  return config;
});
Shrawak commented 1 year ago

I think you need to change the nest-cli.json file. You need to specify the output directory in the assets to let nest know where to output your templates files.

"compilerOptions": {
    "deleteOutDir": true,
    "assets": [{ "include": "templates/**/*", "outDir": "dist/" }],
    "watchAssets": true
  }

My whole nest-cli.json file is like this

{
  "$schema": "https://json.schemastore.org/nest-cli",
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "deleteOutDir": true,
    "assets": [{ "include": "templates/**/*", "outDir": "dist/" }],
    "watchAssets": true
  }
}
ramusarithak commented 1 year ago

@ghost worked! { "collection": "@nestjs/schematics", "sourceRoot": "src", "compilerOptions": { "assets": ["*/.hbs"] } }

waqarilyas commented 3 months ago

adding ../ in the beginning worked for me


{
  "$schema": "https://json.schemastore.org/nest-cli",
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "deleteOutDir": true,
    "assets": [
      {
        "include": "../src/custom-mailer/templates/**/*",
        "outDir": "dist/custom-mailer/templates",
        "watchAssets": true
      }
    ]
  }
}
codejunky commented 3 weeks ago

So I got it running. The trick is to copy the template files to the dist folder after it's compiled.

My steps

  1. Add path to app.module.ts

import * as path from 'path';

  1. my template object:
      template: {
        dir: path.join(__dirname, 'templates'),
        adapter: new HandlebarsAdapter(),
        options: {
          strict: true,
        },
      },
  1. Created a folder "templates" in the "src" folder and put my .hbs in there
  2. Install npm module: cpx
  3. Create a npm run command to copy the templates in package.json

"copy:templates": "cpx './src/templates/**' 'dist/templates'"

  1. run the copy command after the the build

"build": "rimraf dist && tsc -p tsconfig.build.json && npm run copy:templates",

Now when I do npm run build , the templates are copied in the dist folder. yay!

Thanks man! That was quite helpful. I wasted hours trying to fix this issue