Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 81 additions & 51 deletions doc/install.md

Large diffs are not rendered by default.

45 changes: 42 additions & 3 deletions packages/mjml-cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,50 @@ These are the default options.
### Change minify options

```bash
$> mjml input.mjml --config.minifyOptions='{"minifyCSS": true, "removeEmptyAttributes": false}'
$> mjml input.mjml --config.minifyOptions='{"minifyCss": true, "removeEmptyAttributes": false}'
```

The defaults are "collapseWhitespace": true, "minifyCSS": false, "removeEmptyAttributes": true
See html-minifier documentation for more available options
Defaults when minify is enabled (htmlnano):
- collapseWhitespace: true
- minifyCss: 'lite' (if not provided)
- removeEmptyAttributes: true
- removeComments: 'safe'
- minifyJs: false

See htmlnano documentation for more options, and cssnano for `minifyCss` presets/options.

Compatibility note:
- The CSS minifier is configured via `minifyCss`. For backward compatibility, `minifyCSS` is still accepted and mapped internally:
- `{"minifyCSS": false}` → disables CSS minification
- `{"minifyCSS": true}` → enables CSS minification with the `'lite'` preset
- To customize string quotation, pass a cssnano option, for example:
- `--config.minifyOptions '{"minifyCss":{"preset":["default", {"normalizeString":{"preferredQuote":"single"}}]}}'`

### Sanitize template variables in CSS

When your MJML contains template variables inside `<mj-style>` or inline `style="..."`, enable sanitization so CSS minification (PostCSS/cssnano) doesn't parse your template tokens:

```bash
$> mjml input.mjml --config.sanitizeStyles true --config.minify true
```

Alternatively, keep HTML minification but skip CSS minification entirely:

```bash
$> mjml input.mjml --config.minify true --config.minifyOptions='{"minifyCss": false}'
```

### Specify template syntax delimiters

You can provide one or more template syntaxes via JSON. Each entry is an object with `prefix` and `suffix`:

```bash
$> mjml input.mjml \
--config.sanitizeStyles true \
--config.templateSyntax='[{"prefix":"[[","suffix":"]]"},{"prefix":"{{","suffix":"}}"}]'
```

This is equivalent to setting the same `templateSyntax` array in `.mjmlconfig.js` or passing it programmatically.

### Change juice options (library used for inlining mj-style css)

Expand Down
1 change: 1 addition & 0 deletions packages/mjml-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"lodash": "^4.17.21",
"minimatch": "^9.0.3",
"mjml-core": "5.0.0-alpha.8",
"mjml-preset-core": "5.0.0-alpha.8",
"mjml-parser-xml": "5.0.0-alpha.8",
"mjml-validator": "5.0.0-alpha.8",
"yargs": "^17.7.2"
Expand Down
38 changes: 34 additions & 4 deletions packages/mjml-cli/src/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import yargs from 'yargs'
import { flow, pick, isNil, negate, pickBy } from 'lodash/fp'
import { isArray, isEmpty, map, get } from 'lodash'

import mjml2html, { components, initializeType } from 'mjml-core'
import validate, { dependencies } from 'mjml-validator'
import mjml2htmlCore, { components, initializeType, assignComponents } from 'mjml-core'
import validate, { dependencies, assignDependencies } from 'mjml-validator'
import presetCore from 'mjml-preset-core'
import MJMLParser from 'mjml-parser-xml'

import { version as coreVersion } from 'mjml-core/package.json'
Expand All @@ -27,7 +28,7 @@ const beautifyConfig = {

const minifyConfig = {
collapseWhitespace: true,
minifyCSS: false,
minifyCss: false,
caseSensitive: true,
removeEmptyAttributes: true,
}
Expand Down Expand Up @@ -85,6 +86,11 @@ export default async () => {
type: 'object',
describe: 'Option to pass to mjml-core',
},
sanitizeStyles: {
type: 'boolean',
describe:
'Sanitize template variables inside CSS before minification',
},
version: {
alias: 'V',
},
Expand All @@ -100,6 +106,7 @@ export default async () => {
let minifyOptions
let juicePreserveTags
let fonts
let templateSyntax

try {
juiceOptions =
Expand Down Expand Up @@ -128,6 +135,13 @@ export default async () => {
error(`Failed to decode JSON for config.fonts argument`)
}

try {
templateSyntax =
argv.c && argv.c.templateSyntax && JSON.parse(argv.c.templateSyntax)
} catch (e) {
error(`Failed to decode JSON for config.templateSyntax argument`)
}

const filePath = argv.c && argv.c.filePath

const config = Object.assign(
Expand All @@ -137,12 +151,27 @@ export default async () => {
minifyOptions && { minifyOptions },
juiceOptions && { juiceOptions },
juicePreserveTags && { juicePreserveTags },
templateSyntax && { templateSyntax },
argv.c && argv.c.keepComments === 'false' && { keepComments: false },
)

if (typeof config.sanitizeStyles === 'string') {
config.sanitizeStyles = config.sanitizeStyles === 'true'
}
if (typeof config.minify === 'string') {
config.minify = config.minify === 'true'
}

if (typeof argv.sanitizeStyles !== 'undefined') {
config.sanitizeStyles = argv.sanitizeStyles
}

const inputArgs = pickArgs(['r', 'w', 'i', '_', 'm', 'v'])(argv)
const outputArgs = pickArgs(['o', 's'])(argv)

assignComponents(components, presetCore.components)
assignDependencies(dependencies, presetCore.dependencies)

// implies (until yargs pr is accepted)
;[
[Object.keys(inputArgs).length === 0, 'No input argument received'],
Expand Down Expand Up @@ -229,12 +258,13 @@ export default async () => {
const minify = config.minify && config.minify !== 'false'

// eslint-disable-next-line no-await-in-loop
compiled = await mjml2html(i.mjml, {
compiled = await mjml2htmlCore(i.mjml, {
...config,
minify,
beautify,
beautifyConfig,
minifyConfig,
useMjmlConfigOptions: config?.useMjmlConfigOptions ?? false,
filePath: filePath || i.file,
actualPath: i.file,
})
Expand Down
Loading
Loading