Mjml: TypeError: Cannot read property 'replace' of undefined

Created on 5 Mar 2021  Â·  16Comments  Â·  Source: mjmlio/mjml

Describe the bug
After install the package with the command npm install -g mjml, and run a simple file only with mj-section mj-column mj-text, the following error show:

➜  mjml index.mjml
File: index.mjml
TypeError: Cannot read property 'replace' of undefined

Command line error:
Input file(s) failed to render

PS: the version of mjml 4.7.1 is working.

To Reproduce
Steps to reproduce the behavior:

  1. With node version 12.19.0 and npm version 6.14.8 install globally the mjml npm install -g mjml.
  2. Create a file with this MJML code:
<mj-section>
    <mj-column>
        <mj-text> Some text </mj-text>
    </mj-column>
</mj-section>
  1. Render it to HTML by running: mjml index.mjml
  2. See error

Expected behavior
A clear and concise description of what you expected to happen.

MJML environment (please complete the following information):

  • OS: MacOS Catalina 10.15.7
  • MJML Version 4.8.2
  • MJML tool used: MJML CLI

Email sending environment(for rendering issues):

  • Platform used to send the email [e.g Putsmail]

Affected email clients (for rendering issues):

  • Email Client [e.g Gmail]
  • OS: [e.g. Windows]
  • Browser [e.g. Google Chrome]

Screenshots
If applicable, add screenshots to help explain your problem.

image

Additional context
Add any other context about the problem here.

All 16 comments

Can you try to remove every global install and use a local install instead ?

I'm getting the same error when trying to compile through node.

Strict validation and compilation works on the command line with the local install.

This is on macOS Catalina 10.15.7

$ which mjml
mjml not found

$ ./node_modules/.bin/mjml --version
mjml-core: 4.9.0
mjml-cli: 4.9.0

$ ./node_modules/.bin/mjml -l strict -v mjml/*.mjml

$ node index.js 
/Users/garrettc/sandbox/LWE/email-templates/node_modules/mjml-core/lib/helpers/minifyOutlookConditionnals.js:9
content.replace(/(<!--\[if\s[^\]]+]>)([\s\S]*?)(<!\[endif]-->)/gm, (match, prefix, content, suffix) => {
        ^

TypeError: Cannot read property 'replace' of undefined
    at _default (/Users/garrettc/sandbox/LWE/email-templates/node_modules/mjml-core/lib/helpers/minifyOutlookConditionnals.js:9:9)
    at mjml2html (/Users/garrettc/sandbox/LWE/email-templates/node_modules/mjml-core/lib/index.js:398:53)
    at file:///Users/garrettc/sandbox/LWE/email-templates/index.js:59:24
    at FSReqCallback.readFileAfterClose [as oncomplete] (internal/fs/read_file_context.js:63:3)

Just tried with a fresh install and it works fine, can you try to remove your node_modules first ?

Same result I'm afraid.

$ rm -fr node_modules

$ node --version
v14.7.0

$ npm --version
6.14.7

$ npm install
added 158 packages from 188 contributors and audited 158 packages in 1.564s

14 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

$ ./node_modules/.bin/mjml --version
mjml-core: 4.9.0
mjml-cli: 4.9.0

$ ./node_modules/.bin/mjml -l strict -v mjml/*.mjml

$ node index.js
/Users/garrettc/sandbox/LWE/email-templates/node_modules/mjml-core/lib/helpers/minifyOutlookConditionnals.js:9
content.replace(/(<!--\[if\s[^\]]+]>)([\s\S]*?)(<!\[endif]-->)/gm, (match, prefix, content, suffix) => {
        ^

TypeError: Cannot read property 'replace' of undefined
    at _default (/Users/garrettc/sandbox/LWE/email-templates/node_modules/mjml-core/lib/helpers/minifyOutlookConditionnals.js:9:9)
    at mjml2html (/Users/garrettc/sandbox/LWE/email-templates/node_modules/mjml-core/lib/index.js:398:53)
    at file:///Users/garrettc/sandbox/LWE/email-templates/index.js:59:24
    at FSReqCallback.readFileAfterClose [as oncomplete] (internal/fs/read_file_context.js:63:3)

This is what I'm installing:

  "devDependencies": {
    "mjml": "^4.9.0",
    "nunjucks": "^3.2.3",
    "path": "^0.12.7",
    "postmark": "^2.7.3",
    "rimraf": "^3.0.2"
  },

And this is line 59 in index.js:

const HtmlBody = mjml2html(data, mjmlOptions);

Anything else I can supply to help work this out?

Just tried with node 14.9 and it works fine here :(

Try maybe to remove node_modules, remove your lockfile, reinstall ?

If it still doesn't work did you have any mjml installed globally previously ?

I removed node_modules and package-lock.json, still no joy.

I did have a global install, but I removed it after reading your response to dbasilioesp above:

$ ls /usr/local/lib/node_modules
caniuse-cmd       gulp              keybase-installer parker
eslint            hoodie-cli        less              watchless
grunt-cli         keybase           npm

Wait the cli works but not your script right, if so you might be using mjml2html from mjml-core directly instead from mjml package ?

cc @kmcb777 We might need to handle this behavior in MJML5 where rendering without any dep registered would crash because of empty content returned by processing method

Sorry folks, looks like this was user error. After to speaking to another dev on our team we realised that I was using fs.readFileSync to ingest the MJML file, but I wasn't specifying an encoding, so it was returning an object, not a string.

This was broken:

const data = fs.readFileSync(filePath);
const HtmlBody = mjml2html(data, mjmlOptions);

This worked:

const data = fs.readFileSync(filePath, { encoding: "utf8" }); // added encoding option
const HtmlBody = mjml2html(data, mjmlOptions);

Feel free to reopen if you can provide more info @dbasilioesp

Feel free to reopen if you can provide more info @dbasilioesp

Sorry by not respond @iRyusa, I will be able to test again next week.

I have the same issue with mjml-core 4.9.0.

import mjml2html from 'mjml-core';

const mjmlContent = `<mj-section>
  <mj-column>
      <mj-text> Some text </mj-text>
  </mj-column>
  </mj-section>
  `;

mjml2html(mjmlContent, {});

This throws an error:

TypeError: Cannot read property 'replace' of undefined
    at _default (deploy/node_modules/mjml-core/lib/helpers/minifyOutlookConditionnals.js:9:9)
    at Object.mjml2html [as default] (deploy/node_modules/mjml-core/lib/index.js:398:53)

Edit: I'm running this through ts-node,

$ cat bug.ts

import mjml2html from 'mjml-core';

const mjmlContent = `<mj-section>
  <mj-column>
      <mj-text> Some text </mj-text>
  </mj-column>
  </mj-section>`;

mjml2html(mjmlContent, {}); // Throws: TypeError: Cannot read property 'replace' of undefined

Change

import mjml2html from 'mjml-core';

to

import mjml2html from 'mjml';

@iRyusa hmm, I tried that too, unfortunately, it didn't resolve the issue. This repository reproduces the issue:

https://github.com/jrasanen/mjmlbug/blob/trunk/index.ts
https://github.com/jrasanen/mjmlbug/blob/trunk/package.json

Edit:

to rule out any effects from my environment and current OS, I added docker support. It can be reproduced with docker-compose up.

Maybe I just have something wrong with the package.json and dependencies? 🤔

/Users/jussiras/tmp/mjmlbug/node_modules/mjml-core/lib/helpers/minifyOutlookConditionnals.js:9
content.replace(/(<!--\[if\s[^\]]+]>)([\s\S]*?)(<!\[endif]-->)/gm, (match, prefix, content, suffix) => {
        ^
TypeError: Cannot read property 'replace' of undefined
    at _default (/Users/jussiras/tmp/mjmlbug/node_modules/mjml-core/lib/helpers/minifyOutlookConditionnals.js:9:9)
    at Object.mjml2html [as default] (/Users/jussiras/tmp/mjmlbug/node_modules/mjml-core/lib/index.js:398:53)
    at Object.<anonymous> (/Users/jussiras/tmp/mjmlbug/index.ts:9:10)
    at Module._compile (internal/modules/cjs/loader.js:1015:30)
    at Module.m._compile (/Users/jussiras/tmp/mjmlbug/node_modules/ts-node/src/index.ts:1056:23)
    at Module._extensions..js (internal/modules/cjs/loader.js:1035:10)
    at Object.require.extensions.<computed> [as .ts] (/Users/jussiras/tmp/mjmlbug/node_modules/ts-node/src/index.ts:1059:12)
    at Module.load (internal/modules/cjs/loader.js:879:32)
    at Function.Module._load (internal/modules/cjs/loader.js:724:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)

Hi, i think it's related to the fact that there is no <mjml> and <mj-body> tags in your mjml

Looks like you have no mjml root tag in your input string for some reason it crash

<mjml>
<mj-body>
<mj-section>
  <mj-column>
      <mj-text> Some text </mj-text>
  </mj-column>
  </mj-section>
  </mj-body>
</mjml>

works fine in your repo

Was this page helpful?
0 / 5 - 0 ratings

Related issues

AustinTruex68 picture AustinTruex68  Â·  4Comments

sinsunsan picture sinsunsan  Â·  4Comments

liminspace picture liminspace  Â·  3Comments

kytosai picture kytosai  Â·  4Comments

karanmartian picture karanmartian  Â·  3Comments