@maizzle/framework 4.3.1 → 4.4.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/package.json +8 -9
- package/src/commands/serve.js +147 -117
- package/src/generators/config.js +11 -4
- package/src/generators/output/to-disk.js +50 -20
- package/src/generators/output/to-string.js +11 -4
- package/src/generators/postcss.js +3 -1
- package/src/generators/posthtml/index.js +17 -24
- package/src/generators/tailwindcss.js +27 -24
- package/src/transformers/baseUrl.js +8 -4
- package/src/transformers/filters/index.js +11 -2
- package/src/transformers/index.js +2 -3
- package/src/transformers/removeInlinedSelectors.js +20 -17
- package/src/transformers/removeUnusedCss.js +6 -8
- package/src/transformers/shorthandInlineCSS.js +10 -4
- package/src/utils/helpers.js +0 -5
package/README.md
CHANGED
|
@@ -34,9 +34,9 @@ The Maizzle framework is open-sourced software licensed under the [MIT license](
|
|
|
34
34
|
|
|
35
35
|
[npm]: https://www.npmjs.com/package/@maizzle/framework
|
|
36
36
|
[npm-stats]: https://npm-stat.com/charts.html?package=%40maizzle%2Fframework&from=2019-03-27
|
|
37
|
-
[npm-version-shield]: https://img.shields.io/npm/v/@maizzle/framework.svg
|
|
38
|
-
[npm-stats-shield]: https://img.shields.io/npm/dt/@maizzle/framework.svg?
|
|
37
|
+
[npm-version-shield]: https://img.shields.io/npm/v/@maizzle/framework.svg
|
|
38
|
+
[npm-stats-shield]: https://img.shields.io/npm/dt/@maizzle/framework.svg?color=4f46e5
|
|
39
39
|
[github-ci]: https://github.com/maizzle/framework/actions
|
|
40
|
-
[github-ci-shield]: https://
|
|
40
|
+
[github-ci-shield]: https://github.com/maizzle/framework/actions/workflows/nodejs.yml/badge.svg
|
|
41
41
|
[license]: ./LICENSE
|
|
42
|
-
[license-shield]: https://img.shields.io/npm/l/@maizzle/framework.svg?
|
|
42
|
+
[license-shield]: https://img.shields.io/npm/l/@maizzle/framework.svg?color=0e9f6e
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maizzle/framework",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.4.0-beta.10",
|
|
4
4
|
"description": "Maizzle is a framework that helps you quickly build HTML emails with Tailwind CSS.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@maizzle/cli": "^1.5.1",
|
|
44
44
|
"autoprefixer": "^10.4.13",
|
|
45
|
-
"browser-sync": "^2.
|
|
45
|
+
"browser-sync": "^2.27.11",
|
|
46
46
|
"color-shorthand-hex-to-six-digit": "^3.0.2",
|
|
47
47
|
"email-comb": "^5.2.0",
|
|
48
48
|
"front-matter": "^4.0.0",
|
|
@@ -53,32 +53,31 @@
|
|
|
53
53
|
"juice": "^8.0.0",
|
|
54
54
|
"lodash": "^4.17.20",
|
|
55
55
|
"ora": "^5.1.0",
|
|
56
|
-
"postcss": "^8.4.
|
|
56
|
+
"postcss": "^8.4.21",
|
|
57
57
|
"postcss-import": "^15.0.0",
|
|
58
58
|
"postcss-merge-longhand": "^5.1.7",
|
|
59
59
|
"posthtml": "^0.16.6",
|
|
60
60
|
"posthtml-attrs-parser": "^0.1.1",
|
|
61
61
|
"posthtml-base-url": "^1.0.1",
|
|
62
|
+
"posthtml-component": "^1.0.0-beta.16",
|
|
62
63
|
"posthtml-content": "^0.1.0",
|
|
63
|
-
"posthtml-expressions": "^1.8.1",
|
|
64
64
|
"posthtml-extend": "^0.6.0",
|
|
65
65
|
"posthtml-extra-attributes": "^1.0.0",
|
|
66
66
|
"posthtml-fetch": "^2.2.0",
|
|
67
|
-
"posthtml-markdownit": "^1.3.
|
|
67
|
+
"posthtml-markdownit": "^1.3.1",
|
|
68
68
|
"posthtml-match-helper": "^1.0.3",
|
|
69
|
-
"posthtml-modules": "^0.9.0",
|
|
70
69
|
"posthtml-mso": "^1.0.4",
|
|
71
70
|
"posthtml-postcss-merge-longhand": "^1.0.2",
|
|
72
71
|
"posthtml-safe-class-names": "^2.0.0",
|
|
73
72
|
"posthtml-url-parameters": "^1.0.4",
|
|
74
73
|
"pretty": "^2.0.0",
|
|
75
|
-
"query-string": "^7.1.
|
|
74
|
+
"query-string": "^7.1.3",
|
|
76
75
|
"string-remove-widows": "^2.1.0",
|
|
77
76
|
"string-strip-html": "^8.2.0",
|
|
78
|
-
"tailwindcss": "^3.2.
|
|
77
|
+
"tailwindcss": "^3.2.6"
|
|
79
78
|
},
|
|
80
79
|
"devDependencies": {
|
|
81
|
-
"ava": "^5.
|
|
80
|
+
"ava": "^5.2.0",
|
|
82
81
|
"c8": "^7.11.0",
|
|
83
82
|
"np": "*",
|
|
84
83
|
"xo": "0.39.1"
|
package/src/commands/serve.js
CHANGED
|
@@ -9,6 +9,10 @@ const renderToString = require('../functions/render')
|
|
|
9
9
|
const {get, merge, isObject} = require('lodash')
|
|
10
10
|
const {clearConsole} = require('../utils/helpers')
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Initialize Browsersync on-demand
|
|
14
|
+
* https://github.com/maizzle/framework/issues/605
|
|
15
|
+
*/
|
|
12
16
|
const browsersync = () => {
|
|
13
17
|
if (!global.cachedBrowserSync) {
|
|
14
18
|
const bs = require('browser-sync')
|
|
@@ -18,142 +22,168 @@ const browsersync = () => {
|
|
|
18
22
|
return global.cachedBrowserSync
|
|
19
23
|
}
|
|
20
24
|
|
|
25
|
+
const getConfig = async (env = 'local', config = {}) => merge(
|
|
26
|
+
config,
|
|
27
|
+
await Config.getMerged(env)
|
|
28
|
+
)
|
|
29
|
+
|
|
21
30
|
const serve = async (env = 'local', config = {}) => {
|
|
22
|
-
config = merge(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
{
|
|
26
|
-
build: {
|
|
27
|
-
command: 'serve'
|
|
28
|
-
}
|
|
31
|
+
config = await getConfig(env, merge(config, {
|
|
32
|
+
build: {
|
|
33
|
+
command: 'serve'
|
|
29
34
|
}
|
|
30
|
-
)
|
|
35
|
+
}))
|
|
31
36
|
|
|
32
37
|
const spinner = ora()
|
|
33
38
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
let templates = get(config, 'build.templates')
|
|
38
|
-
templates = Array.isArray(templates) ? templates : [templates]
|
|
39
|
+
// Build all emails first
|
|
40
|
+
await buildToFile(env, config)
|
|
39
41
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
'src/**',
|
|
44
|
-
...new Set(get(config, 'build.browsersync.watch', []))
|
|
45
|
-
]
|
|
46
|
-
if (typeof tailwindConfig === 'string') {
|
|
47
|
-
globalPaths.push(tailwindConfig);
|
|
48
|
-
}
|
|
42
|
+
// Set some paths to watch
|
|
43
|
+
let templates = get(config, 'build.templates')
|
|
44
|
+
templates = Array.isArray(templates) ? templates : [templates]
|
|
49
45
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
46
|
+
const templatePaths = [...new Set(templates.map(config => `${get(config, 'source', 'src')}/**`))]
|
|
47
|
+
const tailwindConfig = get(config, 'build.tailwind.config', 'tailwind.config.js')
|
|
48
|
+
const globalPaths = [
|
|
49
|
+
'src/**',
|
|
50
|
+
...new Set(get(config, 'build.browsersync.watch', []))
|
|
51
|
+
]
|
|
57
52
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
return [...acc, ...get(template, 'filetypes', ['html'])]
|
|
62
|
-
}, [])
|
|
53
|
+
if (typeof tailwindConfig === 'string') {
|
|
54
|
+
globalPaths.push(tailwindConfig)
|
|
55
|
+
}
|
|
63
56
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
57
|
+
// Watch for Template file changes
|
|
58
|
+
browsersync()
|
|
59
|
+
.watch(templatePaths)
|
|
60
|
+
.on('change', async file => {
|
|
61
|
+
config = await getConfig(env, config)
|
|
67
62
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
63
|
+
if (config.events && typeof config.events.beforeCreate === 'function') {
|
|
64
|
+
await config.events.beforeCreate(config)
|
|
65
|
+
}
|
|
71
66
|
|
|
72
|
-
|
|
67
|
+
// Don't render if file type is not configured
|
|
68
|
+
// eslint-disable-next-line
|
|
69
|
+
const filetypes = templates.reduce((acc, template) => {
|
|
70
|
+
return [...acc, ...get(template, 'filetypes', ['html'])]
|
|
71
|
+
}, [])
|
|
73
72
|
|
|
74
|
-
|
|
73
|
+
if (!filetypes.includes(path.extname(file).slice(1))) {
|
|
74
|
+
return
|
|
75
|
+
}
|
|
75
76
|
|
|
76
|
-
|
|
77
|
+
// Clear console if enabled
|
|
78
|
+
if (get(config, 'build.console.clear')) {
|
|
79
|
+
clearConsole()
|
|
80
|
+
}
|
|
77
81
|
|
|
78
|
-
|
|
79
|
-
|
|
82
|
+
// Start the spinner
|
|
83
|
+
const start = new Date()
|
|
84
|
+
spinner.start('Building email...')
|
|
85
|
+
|
|
86
|
+
// Render the template
|
|
87
|
+
renderToString(
|
|
88
|
+
await fs.readFile(file.replace(/\\/g, '/'), 'utf8'),
|
|
89
|
+
{
|
|
90
|
+
maizzle: merge(
|
|
91
|
+
config,
|
|
92
|
+
{
|
|
93
|
+
build: {
|
|
94
|
+
current: {
|
|
95
|
+
path: path.parse(file)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
),
|
|
80
100
|
...config.events
|
|
81
101
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
})
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
102
|
+
)
|
|
103
|
+
.then(async ({html, config}) => {
|
|
104
|
+
// Write the file to disk
|
|
105
|
+
let source = ''
|
|
106
|
+
let dest = ''
|
|
107
|
+
let ext = ''
|
|
108
|
+
|
|
109
|
+
if (Array.isArray(config.build.templates)) {
|
|
110
|
+
const match = config.build.templates.find(template => template.source === path.parse(file).dir)
|
|
111
|
+
source = path.normalize(get(match, 'source'))
|
|
112
|
+
dest = path.normalize(get(match, 'destination.path', 'build_local'))
|
|
113
|
+
ext = get(match, 'destination.ext', 'html')
|
|
114
|
+
} else if (isObject(config.build.templates)) {
|
|
115
|
+
source = path.normalize(get(config, 'build.templates.source'))
|
|
116
|
+
dest = path.normalize(get(config, 'build.templates.destination.path', 'build_local'))
|
|
117
|
+
ext = get(config, 'build.templates.destination.ext', 'html')
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const fileDir = path.parse(file).dir.replace(source, '')
|
|
121
|
+
const finalDestination = path.join(dest, fileDir, `${path.parse(file).name}.${ext}`)
|
|
122
|
+
|
|
123
|
+
await fs.outputFile(config.permalink || finalDestination, html)
|
|
124
|
+
})
|
|
125
|
+
.then(() => {
|
|
126
|
+
browsersync().reload()
|
|
127
|
+
spinner.succeed(`Compiled in ${(Date.now() - start) / 1000}s [${file}]`)
|
|
128
|
+
})
|
|
129
|
+
.catch(error => {
|
|
130
|
+
throw error
|
|
131
|
+
})
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
// Watch for changes in all other files
|
|
135
|
+
browsersync()
|
|
136
|
+
.watch(globalPaths, {ignored: templatePaths})
|
|
137
|
+
.on('change', () => buildToFile(env, config)
|
|
138
|
+
.then(() => browsersync().reload())
|
|
139
|
+
.catch(error => {
|
|
140
|
+
throw error
|
|
113
141
|
})
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
.
|
|
118
|
-
|
|
119
|
-
.on('unlink', () => buildToFile(env, config).then(() => browsersync().reload()))
|
|
120
|
-
|
|
121
|
-
// Watch for changes in config files
|
|
122
|
-
browsersync()
|
|
123
|
-
.watch('config*.js')
|
|
124
|
-
.on('change', async file => {
|
|
125
|
-
const parsedEnv = path.parse(file).name.split('.')[1] || 'local'
|
|
126
|
-
|
|
127
|
-
Config
|
|
128
|
-
.getMerged(parsedEnv)
|
|
129
|
-
.then(config => buildToFile(parsedEnv, config).then(() => browsersync().reload()))
|
|
142
|
+
)
|
|
143
|
+
.on('unlink', () => buildToFile(env, config)
|
|
144
|
+
.then(() => browsersync().reload())
|
|
145
|
+
.catch(error => {
|
|
146
|
+
throw error
|
|
130
147
|
})
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
.
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
// Watch for changes in config files
|
|
151
|
+
browsersync()
|
|
152
|
+
.watch('config*.js')
|
|
153
|
+
.on('change', async file => {
|
|
154
|
+
const parsedEnv = path.parse(file).name.split('.')[1] || 'local'
|
|
155
|
+
|
|
156
|
+
Config
|
|
157
|
+
.getMerged(parsedEnv)
|
|
158
|
+
.then(config => buildToFile(parsedEnv, config)
|
|
159
|
+
.then(() => browsersync().reload())
|
|
160
|
+
.catch(error => {
|
|
161
|
+
throw error
|
|
162
|
+
})
|
|
163
|
+
)
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
// Browsersync options
|
|
167
|
+
const baseDir = templates.map(t => t.destination.path)
|
|
168
|
+
|
|
169
|
+
// Initialize Browsersync
|
|
170
|
+
browsersync()
|
|
171
|
+
.init(
|
|
172
|
+
merge(
|
|
173
|
+
{
|
|
174
|
+
notify: false,
|
|
175
|
+
open: false,
|
|
176
|
+
port: 3000,
|
|
177
|
+
server: {
|
|
178
|
+
baseDir,
|
|
179
|
+
directory: true
|
|
150
180
|
},
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
181
|
+
tunnel: false,
|
|
182
|
+
ui: {port: 3001},
|
|
183
|
+
logFileChanges: false
|
|
184
|
+
},
|
|
185
|
+
get(config, 'build.browsersync', {})
|
|
186
|
+
), () => {})
|
|
157
187
|
}
|
|
158
188
|
|
|
159
189
|
module.exports = serve
|
package/src/generators/config.js
CHANGED
|
@@ -13,16 +13,23 @@ module.exports = {
|
|
|
13
13
|
|
|
14
14
|
const cwd = env === 'maizzle-ci' ? './test/stubs/config' : process.cwd()
|
|
15
15
|
|
|
16
|
-
for (const module of ['./config', './config.local']) {
|
|
16
|
+
for (const module of ['./config', './config.cjs', './config.local', './config.local.cjs']) {
|
|
17
17
|
try {
|
|
18
18
|
baseConfig = merge(baseConfig, requireUncached(path.resolve(cwd, module)))
|
|
19
19
|
} catch {}
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
if (typeof env === 'string' && env !== 'local') {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
let loaded = false
|
|
24
|
+
for (const module of [`./config.${env}`, `./config.${env}.cjs`]) {
|
|
25
|
+
try {
|
|
26
|
+
envConfig = merge(envConfig, requireUncached(path.resolve(cwd, module)))
|
|
27
|
+
loaded = true
|
|
28
|
+
break
|
|
29
|
+
} catch {}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (!loaded) {
|
|
26
33
|
throw new Error(`could not load config.${env}.js`)
|
|
27
34
|
}
|
|
28
35
|
}
|
|
@@ -2,7 +2,6 @@ const path = require('path')
|
|
|
2
2
|
const fs = require('fs-extra')
|
|
3
3
|
const glob = require('glob-promise')
|
|
4
4
|
const {get, isEmpty, merge} = require('lodash')
|
|
5
|
-
const {asyncForEach} = require('../../utils/helpers')
|
|
6
5
|
|
|
7
6
|
const Config = require('../config')
|
|
8
7
|
const Tailwind = require('../tailwindcss')
|
|
@@ -28,10 +27,15 @@ module.exports = async (env, spinner, config) => {
|
|
|
28
27
|
|
|
29
28
|
const css = (typeof get(config, 'build.tailwind.compiled') === 'string')
|
|
30
29
|
? config.build.tailwind.compiled
|
|
31
|
-
: await Tailwind.compile(
|
|
30
|
+
: await Tailwind.compile({config})
|
|
32
31
|
|
|
33
32
|
// Parse each template config object
|
|
34
|
-
await
|
|
33
|
+
for await (const templateConfig of templatesConfig) {
|
|
34
|
+
if (!templateConfig) {
|
|
35
|
+
const configFileName = env === 'local' ? 'config.js' : `config.${env}.js`
|
|
36
|
+
throw new Error(`No template sources defined in \`build.templates\`, check your ${configFileName} file`)
|
|
37
|
+
}
|
|
38
|
+
|
|
35
39
|
const outputDir = get(templateConfig, 'destination.path', `build_${env}`)
|
|
36
40
|
|
|
37
41
|
await fs.remove(outputDir)
|
|
@@ -67,23 +71,45 @@ module.exports = async (env, spinner, config) => {
|
|
|
67
71
|
}
|
|
68
72
|
}
|
|
69
73
|
|
|
74
|
+
// Create a pipe-delimited list of allowed extensions
|
|
75
|
+
// We only compile these, the rest are copied as-is
|
|
76
|
+
const extensions = Array.isArray(templateConfig.filetypes)
|
|
77
|
+
? templateConfig.filetypes.join('|')
|
|
78
|
+
: templateConfig.filetypes || get(templateConfig, 'filetypes', 'html')
|
|
79
|
+
|
|
80
|
+
// List of files that won't be copied to the output directory
|
|
81
|
+
const omitted = Array.isArray(templateConfig.omit)
|
|
82
|
+
? templateConfig.omit
|
|
83
|
+
: [get(templateConfig, 'omit', '')]
|
|
84
|
+
|
|
70
85
|
// Parse each template source
|
|
71
|
-
await
|
|
86
|
+
for await (const source of templateSource) {
|
|
72
87
|
/**
|
|
73
88
|
* Copy single-file sources correctly
|
|
74
89
|
* If `src` is a file, `dest` cannot be a directory
|
|
75
90
|
* https://github.com/jprichardson/node-fs-extra/issues/323
|
|
76
91
|
*/
|
|
77
|
-
const out = fs.lstatSync(source).isFile()
|
|
92
|
+
const out = fs.lstatSync(source).isFile()
|
|
93
|
+
? `${outputDir}/${path.basename(source)}`
|
|
94
|
+
: outputDir
|
|
78
95
|
|
|
79
96
|
await fs
|
|
80
|
-
.copy(source, out
|
|
97
|
+
.copy(source, out, {filter: file => {
|
|
98
|
+
// Do not copy omitted files
|
|
99
|
+
return !omitted
|
|
100
|
+
.filter(Boolean)
|
|
101
|
+
.some(omit => path.normalize(file).includes(path.normalize(omit)))
|
|
102
|
+
}})
|
|
81
103
|
.then(async () => {
|
|
82
|
-
const
|
|
83
|
-
? templateConfig.filetypes.join('|')
|
|
84
|
-
: templateConfig.filetypes || get(templateConfig, 'filetypes', 'html')
|
|
104
|
+
const allSourceFiles = await glob(`${outputDir}/**/*.+(${extensions})`)
|
|
85
105
|
|
|
86
|
-
const
|
|
106
|
+
const skipped = Array.isArray(templateConfig.skip) ?
|
|
107
|
+
templateConfig.skip :
|
|
108
|
+
[get(templateConfig, 'skip', '')]
|
|
109
|
+
|
|
110
|
+
const templates = allSourceFiles.filter(template => {
|
|
111
|
+
return !skipped.includes(template.replace(`${outputDir}/`, ''))
|
|
112
|
+
})
|
|
87
113
|
|
|
88
114
|
if (templates.length === 0) {
|
|
89
115
|
spinner.warn(`Error: no files with the .${extensions} extension found in ${templateConfig.source}`)
|
|
@@ -94,7 +120,7 @@ module.exports = async (env, spinner, config) => {
|
|
|
94
120
|
await config.events.beforeCreate(config)
|
|
95
121
|
}
|
|
96
122
|
|
|
97
|
-
await
|
|
123
|
+
for await (const file of templates) {
|
|
98
124
|
config.build.current = {
|
|
99
125
|
path: path.parse(file)
|
|
100
126
|
}
|
|
@@ -114,7 +140,7 @@ module.exports = async (env, spinner, config) => {
|
|
|
114
140
|
...config.events
|
|
115
141
|
})
|
|
116
142
|
|
|
117
|
-
const destination = config.permalink
|
|
143
|
+
const destination = get(compiled, 'config.permalink', file)
|
|
118
144
|
|
|
119
145
|
/**
|
|
120
146
|
* Generate plaintext
|
|
@@ -125,7 +151,7 @@ module.exports = async (env, spinner, config) => {
|
|
|
125
151
|
|
|
126
152
|
// Check if plaintext: true globally, fallback to template's front matter
|
|
127
153
|
const plaintextConfig = get(templateConfig, 'plaintext', get(compiled.config, 'plaintext', false))
|
|
128
|
-
const plaintextPath = get(plaintextConfig, 'destination.path',
|
|
154
|
+
const plaintextPath = get(plaintextConfig, 'destination.path', destination)
|
|
129
155
|
|
|
130
156
|
if (Boolean(plaintextConfig) || !isEmpty(plaintextConfig)) {
|
|
131
157
|
await Plaintext
|
|
@@ -177,19 +203,23 @@ module.exports = async (env, spinner, config) => {
|
|
|
177
203
|
throw error
|
|
178
204
|
}
|
|
179
205
|
}
|
|
180
|
-
}
|
|
206
|
+
}
|
|
181
207
|
|
|
182
208
|
const assets = {source: '', destination: 'assets', ...get(templateConfig, 'assets')}
|
|
183
209
|
|
|
184
210
|
if (Array.isArray(assets.source)) {
|
|
185
|
-
await
|
|
211
|
+
for await (const source of assets.source) {
|
|
186
212
|
if (fs.existsSync(source)) {
|
|
187
|
-
await fs
|
|
213
|
+
await fs
|
|
214
|
+
.copy(source, path.join(templateConfig.destination.path, assets.destination))
|
|
215
|
+
.catch(error => spinner.warn(error.message))
|
|
188
216
|
}
|
|
189
|
-
}
|
|
217
|
+
}
|
|
190
218
|
} else {
|
|
191
219
|
if (fs.existsSync(assets.source)) {
|
|
192
|
-
await fs
|
|
220
|
+
await fs
|
|
221
|
+
.copy(assets.source, path.join(templateConfig.destination.path, assets.destination))
|
|
222
|
+
.catch(error => spinner.warn(error.message))
|
|
193
223
|
}
|
|
194
224
|
}
|
|
195
225
|
|
|
@@ -199,8 +229,8 @@ module.exports = async (env, spinner, config) => {
|
|
|
199
229
|
})
|
|
200
230
|
})
|
|
201
231
|
.catch(error => spinner.warn(error.message))
|
|
202
|
-
}
|
|
203
|
-
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
204
234
|
|
|
205
235
|
if (config.events && typeof config.events.afterBuild === 'function') {
|
|
206
236
|
await config.events.afterBuild(files)
|
|
@@ -22,9 +22,6 @@ module.exports = async (html, options) => {
|
|
|
22
22
|
|
|
23
23
|
let config = merge(fileConfig, get(options, 'maizzle', {}))
|
|
24
24
|
|
|
25
|
-
const tailwindConfig = get(options, 'tailwind.config', {})
|
|
26
|
-
const cssString = get(options, 'tailwind.css', '')
|
|
27
|
-
|
|
28
25
|
const {frontmatter} = fm(html)
|
|
29
26
|
|
|
30
27
|
html = `---\n${frontmatter}\n---\n\n${fm(html).body}`
|
|
@@ -34,7 +31,17 @@ module.exports = async (html, options) => {
|
|
|
34
31
|
if (typeof get(options, 'tailwind.compiled') === 'string') {
|
|
35
32
|
config.css = options.tailwind.compiled
|
|
36
33
|
} else {
|
|
37
|
-
config.css = await Tailwind.compile(
|
|
34
|
+
config.css = await Tailwind.compile({
|
|
35
|
+
css: get(options, 'tailwind.css', ''),
|
|
36
|
+
html,
|
|
37
|
+
config: merge(config, {
|
|
38
|
+
build: {
|
|
39
|
+
tailwind: {
|
|
40
|
+
config: get(options, 'tailwind.config')
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
})
|
|
44
|
+
})
|
|
38
45
|
}
|
|
39
46
|
|
|
40
47
|
if (options && typeof options.beforeRender === 'function') {
|
|
@@ -9,7 +9,9 @@ module.exports = {
|
|
|
9
9
|
return postcss([
|
|
10
10
|
postcssImport(),
|
|
11
11
|
postcssNested(),
|
|
12
|
-
maizzleConfig
|
|
12
|
+
get(maizzleConfig, 'shorthandCSS', get(maizzleConfig, 'shorthandInlineCSS')) === true ?
|
|
13
|
+
mergeLonghand() :
|
|
14
|
+
() => {},
|
|
13
15
|
...get(maizzleConfig, 'build.postcss.plugins', [])
|
|
14
16
|
])
|
|
15
17
|
.process(css, {from: undefined})
|
|
@@ -3,23 +3,17 @@ const posthtml = require('posthtml')
|
|
|
3
3
|
const {get, merge} = require('lodash')
|
|
4
4
|
const fetch = require('posthtml-fetch')
|
|
5
5
|
const layouts = require('posthtml-extend')
|
|
6
|
-
const
|
|
6
|
+
const components = require('posthtml-component')
|
|
7
7
|
const defaultConfig = require('./defaultConfig')
|
|
8
|
-
const expressions = require('posthtml-expressions')
|
|
9
8
|
|
|
10
9
|
module.exports = async (html, config) => {
|
|
11
10
|
const layoutsOptions = get(config, 'build.layouts', {})
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
// Fake `from` option so we can reference modules relatively
|
|
15
|
-
const modulesRoot = modulesOptions.root || './'
|
|
16
|
-
const modulesFrom = modulesOptions.from || `${modulesRoot}/fake`
|
|
11
|
+
const componentsOptions = get(config, 'build.components', {})
|
|
12
|
+
const expressionsOptions = merge({strictMode: false}, get(config, 'build.posthtml.expressions', {}))
|
|
17
13
|
|
|
18
14
|
const posthtmlOptions = merge(defaultConfig, get(config, 'build.posthtml.options', {}))
|
|
19
15
|
const posthtmlPlugins = get(config, 'build.posthtml.plugins', [])
|
|
20
16
|
|
|
21
|
-
const expressionsOptions = merge({strictMode: false}, get(config, 'build.posthtml.expressions', {}))
|
|
22
|
-
|
|
23
17
|
const locals = merge(
|
|
24
18
|
get(expressionsOptions, 'locals', {}),
|
|
25
19
|
get(config, 'locals', {}),
|
|
@@ -37,7 +31,6 @@ module.exports = async (html, config) => {
|
|
|
37
31
|
|
|
38
32
|
return posthtml([
|
|
39
33
|
fetchPlugin,
|
|
40
|
-
expressions({...expressionsOptions, locals}),
|
|
41
34
|
layouts(
|
|
42
35
|
merge(
|
|
43
36
|
{
|
|
@@ -47,20 +40,20 @@ module.exports = async (html, config) => {
|
|
|
47
40
|
layoutsOptions
|
|
48
41
|
)
|
|
49
42
|
),
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
43
|
+
components(
|
|
44
|
+
merge(
|
|
45
|
+
{
|
|
46
|
+
root: componentsOptions.root || './',
|
|
47
|
+
folders: ['src/components', 'src/layouts', 'src/templates'],
|
|
48
|
+
tag: 'component',
|
|
49
|
+
attribute: 'src',
|
|
50
|
+
yield: 'content',
|
|
51
|
+
propsAttribute: 'locals',
|
|
52
|
+
expressions: {...expressionsOptions, locals}
|
|
53
|
+
},
|
|
54
|
+
componentsOptions
|
|
55
|
+
)
|
|
56
|
+
),
|
|
64
57
|
...posthtmlPlugins
|
|
65
58
|
])
|
|
66
59
|
.process(html, {...posthtmlOptions})
|
|
@@ -9,14 +9,14 @@ const mergeLonghand = require('postcss-merge-longhand')
|
|
|
9
9
|
const {get, isObject, isEmpty, merge} = require('lodash')
|
|
10
10
|
|
|
11
11
|
module.exports = {
|
|
12
|
-
compile: async (css = '', html = '',
|
|
13
|
-
tailwindConfig = (isObject(tailwindConfig) && !isEmpty(tailwindConfig)) ? tailwindConfig : get(maizzleConfig, 'build.tailwind.config', 'tailwind.config.js')
|
|
14
|
-
|
|
12
|
+
compile: async ({css = '', html = '', config = {}}) => {
|
|
15
13
|
// Compute the Tailwind config to use
|
|
16
|
-
const userConfig =
|
|
14
|
+
const userConfig = config => {
|
|
15
|
+
const tailwindUserConfig = get(config, 'build.tailwind.config', 'tailwind.config.js')
|
|
16
|
+
|
|
17
17
|
// If a custom config object was passed, use that
|
|
18
|
-
if (isObject(
|
|
19
|
-
return
|
|
18
|
+
if (isObject(tailwindUserConfig) && !isEmpty(tailwindUserConfig)) {
|
|
19
|
+
return tailwindUserConfig
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
/**
|
|
@@ -24,17 +24,17 @@ module.exports = {
|
|
|
24
24
|
* This will use the default Tailwind config (with rem units etc)
|
|
25
25
|
*/
|
|
26
26
|
try {
|
|
27
|
-
return requireUncached(path.resolve(process.cwd(),
|
|
27
|
+
return requireUncached(path.resolve(process.cwd(), tailwindUserConfig))
|
|
28
28
|
} catch {
|
|
29
29
|
return {}
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
// Merge user's Tailwind config on top of a 'base' config
|
|
34
|
-
const layoutsRoot = get(
|
|
35
|
-
const componentsRoot = get(
|
|
34
|
+
const layoutsRoot = get(config, 'build.layouts.root')
|
|
35
|
+
const componentsRoot = get(config, 'build.components.root')
|
|
36
36
|
|
|
37
|
-
const
|
|
37
|
+
const tailwindConfig = merge({
|
|
38
38
|
important: true,
|
|
39
39
|
content: {
|
|
40
40
|
files: [
|
|
@@ -47,20 +47,20 @@ module.exports = {
|
|
|
47
47
|
{raw: html, extension: 'html'}
|
|
48
48
|
]
|
|
49
49
|
}
|
|
50
|
-
}, userConfig())
|
|
50
|
+
}, userConfig(config))
|
|
51
51
|
|
|
52
52
|
// Add back the `{raw: html}` option if user provided own config
|
|
53
|
-
if (Array.isArray(
|
|
54
|
-
|
|
53
|
+
if (Array.isArray(tailwindConfig.content)) {
|
|
54
|
+
tailwindConfig.content = {
|
|
55
55
|
files: [
|
|
56
|
-
...
|
|
56
|
+
...tailwindConfig.content,
|
|
57
57
|
{raw: html, extension: 'html'}
|
|
58
58
|
]
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
// Include all `build.templates.source` paths when scanning for selectors to preserve
|
|
63
|
-
const buildTemplates = get(
|
|
63
|
+
const buildTemplates = get(config, 'build.templates')
|
|
64
64
|
|
|
65
65
|
if (buildTemplates) {
|
|
66
66
|
const templateObjects = Array.isArray(buildTemplates) ? buildTemplates : [buildTemplates]
|
|
@@ -68,12 +68,12 @@ module.exports = {
|
|
|
68
68
|
const source = get(template, 'source')
|
|
69
69
|
|
|
70
70
|
if (typeof source === 'function') {
|
|
71
|
-
const sources = source(
|
|
71
|
+
const sources = source(config)
|
|
72
72
|
|
|
73
73
|
if (Array.isArray(sources)) {
|
|
74
|
-
sources.map(s =>
|
|
74
|
+
sources.map(s => tailwindConfig.content.files.push(s))
|
|
75
75
|
} else if (typeof sources === 'string') {
|
|
76
|
-
|
|
76
|
+
tailwindConfig.content.files.push(sources)
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
// Must return a valid `content` entry
|
|
@@ -82,7 +82,7 @@ module.exports = {
|
|
|
82
82
|
|
|
83
83
|
// Support single-file sources i.e. src/templates/index.html
|
|
84
84
|
if (typeof source === 'string' && Boolean(path.extname(source))) {
|
|
85
|
-
|
|
85
|
+
tailwindConfig.content.files.push(source)
|
|
86
86
|
|
|
87
87
|
return {raw: '', extension: 'html'}
|
|
88
88
|
}
|
|
@@ -90,21 +90,24 @@ module.exports = {
|
|
|
90
90
|
return `${source}/**/*.*`
|
|
91
91
|
})
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
tailwindConfig.content.files.push(...templateSources)
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
const userFilePath = get(
|
|
96
|
+
const userFilePath = get(config, 'build.tailwind.css', path.join(process.cwd(), 'src/css/tailwind.css'))
|
|
97
97
|
const userFileExists = await fs.pathExists(userFilePath)
|
|
98
98
|
|
|
99
99
|
const toProcess = [
|
|
100
100
|
postcssNested(),
|
|
101
|
-
tailwindcss(
|
|
102
|
-
|
|
103
|
-
|
|
101
|
+
tailwindcss(tailwindConfig),
|
|
102
|
+
get(config, 'shorthandCSS', get(config, 'shorthandInlineCSS')) === true ?
|
|
103
|
+
mergeLonghand() :
|
|
104
|
+
() => {},
|
|
105
|
+
...get(config, 'build.postcss.plugins', [])
|
|
104
106
|
]
|
|
105
107
|
|
|
106
108
|
if (userFileExists) {
|
|
107
109
|
css = await fs.readFile(path.resolve(userFilePath), 'utf8') + css
|
|
110
|
+
|
|
108
111
|
toProcess.unshift(
|
|
109
112
|
postcssImport({path: path.dirname(userFilePath)})
|
|
110
113
|
)
|
|
@@ -5,7 +5,7 @@ const {get, merge, isObject, isEmpty} = require('lodash')
|
|
|
5
5
|
const defaultConfig = require('../generators/posthtml/defaultConfig')
|
|
6
6
|
|
|
7
7
|
module.exports = async (html, config = {}, direct = false) => {
|
|
8
|
-
const url = direct ? config : get(config, 'baseURL')
|
|
8
|
+
const url = direct ? config : get(config, 'baseURL', get(config, 'baseUrl'))
|
|
9
9
|
const posthtmlOptions = merge(defaultConfig, get(config, 'build.posthtml.options', {}))
|
|
10
10
|
|
|
11
11
|
// Handle `baseUrl` as a string
|
|
@@ -19,11 +19,15 @@ module.exports = async (html, config = {}, direct = false) => {
|
|
|
19
19
|
.then(result => result.html)
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
// Handle `
|
|
22
|
+
// Handle `baseURL` as an object
|
|
23
23
|
if (isObject(url) && !isEmpty(url)) {
|
|
24
|
-
html = rewriteVMLs(html, url
|
|
24
|
+
html = rewriteVMLs(html, get(url, 'url', ''))
|
|
25
25
|
|
|
26
|
-
return posthtml([
|
|
26
|
+
return posthtml([
|
|
27
|
+
baseUrl(merge({styleTag: true, inlineCss: true}, url))
|
|
28
|
+
])
|
|
29
|
+
.process(html, posthtmlOptions)
|
|
30
|
+
.then(result => result.html)
|
|
27
31
|
}
|
|
28
32
|
|
|
29
33
|
return html
|
|
@@ -22,10 +22,19 @@ module.exports = async (html, config = {}, direct = false) => {
|
|
|
22
22
|
* Compile CSS in <style {post|tailwind}css> tags
|
|
23
23
|
*/
|
|
24
24
|
const maizzleConfig = omit(config, ['build.tailwind.css', 'css'])
|
|
25
|
-
const tailwindConfig = get(config, 'build.tailwind.config', 'tailwind.config.js')
|
|
26
25
|
|
|
27
26
|
filters.postcss = css => PostCSS.process(css, maizzleConfig)
|
|
28
|
-
filters.tailwindcss = css => Tailwind.compile(
|
|
27
|
+
filters.tailwindcss = css => Tailwind.compile({
|
|
28
|
+
css,
|
|
29
|
+
html,
|
|
30
|
+
config: merge({
|
|
31
|
+
build: {
|
|
32
|
+
tailwind: {
|
|
33
|
+
config: get(config, 'build.tailwind.config', {})
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}, maizzleConfig)
|
|
37
|
+
})
|
|
29
38
|
|
|
30
39
|
const posthtmlPlugins = [
|
|
31
40
|
styleDataEmbed(),
|
|
@@ -26,9 +26,8 @@ exports.process = async (html, config) => {
|
|
|
26
26
|
html = await preventWidows(html, config)
|
|
27
27
|
html = await attributeToStyle(html, config)
|
|
28
28
|
html = await inline(html, config)
|
|
29
|
-
html = await shorthandInlineCSS(html, config)
|
|
30
29
|
html = await removeUnusedCSS(html, config)
|
|
31
|
-
html = await
|
|
30
|
+
html = await shorthandInlineCSS(html, config)
|
|
32
31
|
html = await removeInlineSizes(html, config)
|
|
33
32
|
html = await removeInlineBgColor(html, config)
|
|
34
33
|
html = await removeAttributes(html, config)
|
|
@@ -54,7 +53,7 @@ exports.addURLParams = (html, config) => addURLParams(html, config, true)
|
|
|
54
53
|
exports.preventWidows = (html, config) => preventWidows(html, config)
|
|
55
54
|
exports.replaceStrings = (html, config) => replaceStrings(html, config, true)
|
|
56
55
|
exports.safeClassNames = (html, config) => safeClassNames(html, config, true)
|
|
57
|
-
exports.removeUnusedCSS = (html, config) => removeUnusedCSS(html, config
|
|
56
|
+
exports.removeUnusedCSS = (html, config) => removeUnusedCSS(html, config)
|
|
58
57
|
exports.removeAttributes = (html, config) => removeAttributes(html, config, true)
|
|
59
58
|
exports.attributeToStyle = (html, config) => attributeToStyle(html, config, true)
|
|
60
59
|
exports.removeInlineSizes = (html, config) => removeInlineSizes(html, config, true)
|
|
@@ -20,16 +20,26 @@ const plugin = posthtmlOptions => tree => {
|
|
|
20
20
|
// For each style tag...
|
|
21
21
|
if (node.tag === 'style') {
|
|
22
22
|
const {root} = postcss().process(node.content)
|
|
23
|
+
const preservedClasses = []
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (
|
|
27
|
-
|
|
25
|
+
// Preserve selectors in at rules
|
|
26
|
+
root.walkAtRules(rule => {
|
|
27
|
+
if (['media', 'supports'].includes(rule.name)) {
|
|
28
|
+
rule.walkRules(rule => {
|
|
29
|
+
preservedClasses.push(rule.selector)
|
|
30
|
+
})
|
|
28
31
|
}
|
|
32
|
+
})
|
|
29
33
|
|
|
34
|
+
root.walkRules(rule => {
|
|
30
35
|
const {selector} = rule
|
|
31
36
|
const prop = get(rule.nodes[0], 'prop')
|
|
32
37
|
|
|
38
|
+
// Preserve pseudo selectors
|
|
39
|
+
if (selector.includes(':')) {
|
|
40
|
+
preservedClasses.push(selector)
|
|
41
|
+
}
|
|
42
|
+
|
|
33
43
|
try {
|
|
34
44
|
// If we find the selector in the HTML...
|
|
35
45
|
tree.match(matchHelper(selector), n => {
|
|
@@ -39,23 +49,16 @@ const plugin = posthtmlOptions => tree => {
|
|
|
39
49
|
|
|
40
50
|
// If the class is in the style attribute (inlined), remove it
|
|
41
51
|
if (has(styleAttr, prop)) {
|
|
42
|
-
// Remove the class
|
|
43
|
-
|
|
52
|
+
// Remove the class as long as it's not a preserved class
|
|
53
|
+
if (!preservedClasses.some(item => item.endsWith(selector) || item.startsWith(selector))) {
|
|
54
|
+
remove(classAttr, classToRemove => selector.includes(classToRemove))
|
|
55
|
+
}
|
|
44
56
|
|
|
45
57
|
// Remove the rule in the <style> tag
|
|
46
|
-
rule.
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Remove from <style> selectors that were used to create shorthand declarations
|
|
51
|
-
* like `margin: 0 0 0 16px` (transformed with mergeLonghand when inlining).
|
|
52
|
-
*/
|
|
53
|
-
Object.keys(styleAttr).forEach(key => {
|
|
54
|
-
if (prop && prop.includes(key)) {
|
|
58
|
+
if (rule.parent.type !== 'atrule') {
|
|
55
59
|
rule.remove()
|
|
56
|
-
remove(classAttr, s => selector.includes(s))
|
|
57
60
|
}
|
|
58
|
-
}
|
|
61
|
+
}
|
|
59
62
|
|
|
60
63
|
n.attrs = parsedAttrs.compose()
|
|
61
64
|
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
const {comb} = require('email-comb')
|
|
2
2
|
const {get, merge} = require('lodash')
|
|
3
|
+
const removeInlinedClasses = require('./removeInlinedSelectors')
|
|
3
4
|
|
|
4
|
-
module.exports = async (html, config = {}
|
|
5
|
+
module.exports = async (html, config = {}) => {
|
|
6
|
+
// If it's explicitly disabled, return the HTML
|
|
5
7
|
if (get(config, 'removeUnusedCSS') === false) {
|
|
6
8
|
return html
|
|
7
9
|
}
|
|
8
10
|
|
|
9
|
-
if (!direct && !get(config, 'removeUnusedCSS')) {
|
|
10
|
-
return html
|
|
11
|
-
}
|
|
12
|
-
|
|
13
11
|
const safelist = [
|
|
14
12
|
'*body*', // Gmail
|
|
15
13
|
'.gmail*', // Gmail
|
|
@@ -36,9 +34,9 @@ module.exports = async (html, config = {}, direct = false) => {
|
|
|
36
34
|
whitelist: [...get(config, 'whitelist', []), ...safelist]
|
|
37
35
|
}
|
|
38
36
|
|
|
39
|
-
const options =
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
const options = merge(defaultOptions, get(config, 'removeUnusedCSS', config))
|
|
38
|
+
|
|
39
|
+
html = await removeInlinedClasses(html, options)
|
|
42
40
|
|
|
43
41
|
return comb(html, options).result
|
|
44
42
|
}
|
|
@@ -1,19 +1,25 @@
|
|
|
1
1
|
const posthtml = require('posthtml')
|
|
2
2
|
const {get, merge, isObject, isEmpty} = require('lodash')
|
|
3
|
-
const
|
|
3
|
+
const mergeInlineLonghand = require('posthtml-postcss-merge-longhand')
|
|
4
4
|
const defaultConfig = require('../generators/posthtml/defaultConfig')
|
|
5
5
|
|
|
6
6
|
module.exports = async (html, config, direct = false) => {
|
|
7
|
-
config = direct ?
|
|
7
|
+
config = direct ?
|
|
8
|
+
(isObject(config) ? config : true) :
|
|
9
|
+
get(config, 'shorthandCSS', get(config, 'shorthandInlineCSS', []))
|
|
8
10
|
|
|
9
11
|
const posthtmlOptions = merge(defaultConfig, get(config, 'build.posthtml.options', {}))
|
|
10
12
|
|
|
11
13
|
if (typeof config === 'boolean' && config) {
|
|
12
|
-
html = await posthtml([
|
|
14
|
+
html = await posthtml([mergeInlineLonghand()])
|
|
15
|
+
.process(html, posthtmlOptions)
|
|
16
|
+
.then(result => result.html)
|
|
13
17
|
}
|
|
14
18
|
|
|
15
19
|
if (isObject(config) && !isEmpty(config)) {
|
|
16
|
-
html = await posthtml([
|
|
20
|
+
html = await posthtml([mergeInlineLonghand(config)])
|
|
21
|
+
.process(html, posthtmlOptions)
|
|
22
|
+
.then(result => result.html)
|
|
17
23
|
}
|
|
18
24
|
|
|
19
25
|
return html
|
package/src/utils/helpers.js
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
module.exports = {
|
|
2
|
-
asyncForEach: async (array, callback) => {
|
|
3
|
-
for (let index = 0; index < array.length; index++) {
|
|
4
|
-
await callback(array[index], index, array) // eslint-disable-line
|
|
5
|
-
}
|
|
6
|
-
},
|
|
7
2
|
requireUncached: module => {
|
|
8
3
|
try {
|
|
9
4
|
delete require.cache[require.resolve(module)]
|