@maizzle/framework 4.8.7 → 5.0.0-beta.0
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/bin/maizzle +3 -1
- package/package.json +65 -58
- package/src/commands/build.js +244 -19
- package/src/commands/serve.js +2 -197
- package/src/generators/plaintext.js +192 -91
- package/src/generators/render.js +128 -0
- package/src/index.js +46 -14
- package/src/{generators/posthtml → posthtml}/defaultComponentsConfig.js +6 -4
- package/src/{generators/posthtml → posthtml}/defaultConfig.js +1 -1
- package/src/posthtml/index.js +74 -0
- package/src/posthtml/plugins/expandLinkTag.js +36 -0
- package/src/server/client.js +181 -0
- package/src/server/index.js +383 -0
- package/src/server/routes/hmr.js +24 -0
- package/src/server/routes/index.js +38 -0
- package/src/server/views/error.html +83 -0
- package/src/server/views/index.html +24 -0
- package/src/server/websockets.js +27 -0
- package/src/transformers/addAttributes.js +30 -0
- package/src/transformers/attributeToStyle.js +30 -36
- package/src/transformers/baseUrl.js +52 -23
- package/src/transformers/comb.js +51 -0
- package/src/transformers/core.js +20 -0
- package/src/transformers/filters/defaultFilters.js +90 -70
- package/src/transformers/filters/index.js +14 -78
- package/src/transformers/index.js +268 -63
- package/src/transformers/inline.js +240 -0
- package/src/transformers/markdown.js +13 -14
- package/src/transformers/minify.js +21 -16
- package/src/transformers/posthtmlMso.js +13 -8
- package/src/transformers/prettify.js +16 -15
- package/src/transformers/preventWidows.js +32 -26
- package/src/transformers/removeAttributes.js +17 -17
- package/src/transformers/replaceStrings.js +30 -9
- package/src/transformers/safeClassNames.js +24 -24
- package/src/transformers/shorthandCss.js +22 -0
- package/src/transformers/sixHex.js +15 -15
- package/src/transformers/urlParameters.js +18 -16
- package/src/transformers/useAttributeSizes.js +65 -0
- package/src/utils/getConfigByFilePath.js +124 -0
- package/src/utils/node.js +68 -0
- package/src/utils/string.js +117 -0
- package/types/build.d.ts +117 -57
- package/types/components.d.ts +130 -112
- package/types/config.d.ts +454 -242
- package/types/css/inline.d.ts +234 -0
- package/types/css/purge.d.ts +125 -0
- package/types/events.d.ts +5 -105
- package/types/index.d.ts +148 -116
- package/types/markdown.d.ts +20 -18
- package/types/minify.d.ts +122 -120
- package/types/plaintext.d.ts +46 -52
- package/types/posthtml.d.ts +103 -136
- package/types/render.d.ts +0 -117
- package/types/urlParameters.d.ts +21 -20
- package/types/widowWords.d.ts +9 -7
- package/src/functions/plaintext.js +0 -5
- package/src/functions/render.js +0 -5
- package/src/generators/config.js +0 -52
- package/src/generators/output/index.js +0 -4
- package/src/generators/output/to-disk.js +0 -254
- package/src/generators/output/to-string.js +0 -73
- package/src/generators/postcss.js +0 -23
- package/src/generators/posthtml/index.js +0 -75
- package/src/generators/tailwindcss.js +0 -157
- package/src/transformers/extraAttributes.js +0 -33
- package/src/transformers/inlineCss.js +0 -42
- package/src/transformers/removeInlineBackgroundColor.js +0 -56
- package/src/transformers/removeInlineSizes.js +0 -43
- package/src/transformers/removeInlinedSelectors.js +0 -100
- package/src/transformers/removeUnusedCss.js +0 -48
- package/src/transformers/shorthandInlineCSS.js +0 -26
- package/src/utils/helpers.js +0 -13
- package/types/baseUrl.d.ts +0 -79
- package/types/fetch.d.ts +0 -143
- package/types/inlineCss.d.ts +0 -207
- package/types/layouts.d.ts +0 -39
- package/types/removeUnusedCss.d.ts +0 -115
- package/types/tailwind.d.ts +0 -22
- package/types/templates.d.ts +0 -181
package/src/generators/config.js
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
const path = require('path')
|
|
2
|
-
const {merge} = require('lodash')
|
|
3
|
-
const {requireUncached} = require('../utils/helpers')
|
|
4
|
-
|
|
5
|
-
const baseConfigFileNames = [
|
|
6
|
-
'./maizzle.config.js',
|
|
7
|
-
'./maizzle.config.cjs',
|
|
8
|
-
'./maizzle.config.local.js',
|
|
9
|
-
'./maizzle.config.local.cjs',
|
|
10
|
-
'./config.js',
|
|
11
|
-
'./config.cjs',
|
|
12
|
-
'./config.local.js',
|
|
13
|
-
'./config.local.cjs'
|
|
14
|
-
]
|
|
15
|
-
|
|
16
|
-
module.exports = {
|
|
17
|
-
getMerged: async (env = 'local') => {
|
|
18
|
-
if (typeof env !== 'string') {
|
|
19
|
-
throw new TypeError(`env name must be a string, received ${typeof env}(${env})`)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
let baseConfig = {env}
|
|
23
|
-
let envConfig = {env}
|
|
24
|
-
|
|
25
|
-
const cwd = ['maizzle-ci', 'test'].includes(env) ? './test/stubs/config' : process.cwd()
|
|
26
|
-
|
|
27
|
-
for (const module of baseConfigFileNames) {
|
|
28
|
-
try {
|
|
29
|
-
baseConfig = merge(baseConfig, requireUncached(path.resolve(cwd, module)))
|
|
30
|
-
} catch {}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (env !== 'local') {
|
|
34
|
-
let loaded = false
|
|
35
|
-
const modulesToTry = [`./maizzle.config.${env}.js`, `./maizzle.config.${env}.cjs`, `./config.${env}.js`, `./config.${env}.cjs`]
|
|
36
|
-
|
|
37
|
-
for (const module of modulesToTry) {
|
|
38
|
-
try {
|
|
39
|
-
envConfig = merge(envConfig, requireUncached(path.resolve(cwd, module)))
|
|
40
|
-
loaded = true
|
|
41
|
-
break
|
|
42
|
-
} catch {}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (!loaded) {
|
|
46
|
-
throw new Error(`Failed to load config file for \`${env}\` environment, do you have one of these files in your project root?\n\n${modulesToTry.join('\n')}`)
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return merge(baseConfig, envConfig)
|
|
51
|
-
}
|
|
52
|
-
}
|
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
const path = require('path')
|
|
2
|
-
const fs = require('fs-extra')
|
|
3
|
-
const {glob} = require('fast-glob')
|
|
4
|
-
const {get, merge, isEmpty} = require('lodash')
|
|
5
|
-
|
|
6
|
-
const Config = require('../config')
|
|
7
|
-
const Plaintext = require('../plaintext')
|
|
8
|
-
const Tailwind = require('../tailwindcss')
|
|
9
|
-
|
|
10
|
-
const render = require('./to-string')
|
|
11
|
-
|
|
12
|
-
module.exports = async (env, spinner, config) => {
|
|
13
|
-
process.env.NODE_ENV = env || 'local'
|
|
14
|
-
|
|
15
|
-
if (isEmpty(config)) {
|
|
16
|
-
config = await Config.getMerged(env).catch(error => {
|
|
17
|
-
spinner.fail('Build failed')
|
|
18
|
-
throw error
|
|
19
|
-
})
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const buildTemplates = get(config, 'build.templates')
|
|
23
|
-
const templatesConfig = Array.isArray(buildTemplates) ? buildTemplates : [buildTemplates]
|
|
24
|
-
|
|
25
|
-
const parsed = []
|
|
26
|
-
let files = []
|
|
27
|
-
|
|
28
|
-
const css = (typeof get(config, 'build.tailwind.compiled') === 'string')
|
|
29
|
-
? config.build.tailwind.compiled
|
|
30
|
-
: await Tailwind.compile({config})
|
|
31
|
-
|
|
32
|
-
// Parse each template config object
|
|
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
|
-
|
|
39
|
-
const outputDir = get(templateConfig, 'destination.path', `build_${env}`)
|
|
40
|
-
|
|
41
|
-
await fs.remove(outputDir)
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Get all files in the template config's source directory
|
|
45
|
-
* Supports `source` defined as:
|
|
46
|
-
* - string
|
|
47
|
-
* - array of strings
|
|
48
|
-
* - function that returns either of the above
|
|
49
|
-
*
|
|
50
|
-
* */
|
|
51
|
-
const templateSource = []
|
|
52
|
-
const templateTypeErrorMessage = 'Invalid template source: expected string or array of strings, got '
|
|
53
|
-
|
|
54
|
-
if (typeof templateConfig.source === 'function') {
|
|
55
|
-
const sources = templateConfig.source(config)
|
|
56
|
-
|
|
57
|
-
if (Array.isArray(sources)) {
|
|
58
|
-
templateSource.push(...sources)
|
|
59
|
-
} else if (typeof sources === 'string') {
|
|
60
|
-
templateSource.push(sources)
|
|
61
|
-
} else {
|
|
62
|
-
throw new TypeError(templateTypeErrorMessage + typeof sources)
|
|
63
|
-
}
|
|
64
|
-
} else {
|
|
65
|
-
if (Array.isArray(templateConfig.source)) {
|
|
66
|
-
templateSource.push(...templateConfig.source)
|
|
67
|
-
} else if (typeof templateConfig.source === 'string') {
|
|
68
|
-
templateSource.push(templateConfig.source)
|
|
69
|
-
} else {
|
|
70
|
-
throw new TypeError(templateTypeErrorMessage + typeof templateConfig.source)
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Create a pipe-delimited list of allowed extensions
|
|
75
|
-
// We only compile these, the rest are copied as-is
|
|
76
|
-
const fileTypes = get(templateConfig, 'filetypes', 'html')
|
|
77
|
-
const extensionsList = Array.isArray(fileTypes)
|
|
78
|
-
? fileTypes.join(',')
|
|
79
|
-
: fileTypes.split('|').join(',')
|
|
80
|
-
|
|
81
|
-
// List of files that won't be copied to the output directory
|
|
82
|
-
const omitted = Array.isArray(templateConfig.omit)
|
|
83
|
-
? templateConfig.omit
|
|
84
|
-
: [get(templateConfig, 'omit', '')]
|
|
85
|
-
|
|
86
|
-
// Parse each template source
|
|
87
|
-
for await (const source of templateSource) {
|
|
88
|
-
/**
|
|
89
|
-
* Copy single-file sources correctly
|
|
90
|
-
* If `src` is a file, `dest` cannot be a directory
|
|
91
|
-
* https://github.com/jprichardson/node-fs-extra/issues/323
|
|
92
|
-
*/
|
|
93
|
-
const out = fs.lstatSync(source).isFile()
|
|
94
|
-
? `${outputDir}/${path.basename(source)}`
|
|
95
|
-
: outputDir
|
|
96
|
-
|
|
97
|
-
await fs
|
|
98
|
-
.copy(source, out, {filter: file => {
|
|
99
|
-
// Do not copy omitted files
|
|
100
|
-
return !omitted
|
|
101
|
-
.filter(Boolean)
|
|
102
|
-
.some(omit => path.normalize(file).includes(path.normalize(omit)))
|
|
103
|
-
}})
|
|
104
|
-
.then(async () => {
|
|
105
|
-
const extensions = extensionsList.includes(',')
|
|
106
|
-
? `{${extensionsList}}`
|
|
107
|
-
: extensionsList
|
|
108
|
-
const allSourceFiles = await glob(`${outputDir}/**/*.${extensions}`)
|
|
109
|
-
|
|
110
|
-
const skipped = Array.isArray(templateConfig.skip) ?
|
|
111
|
-
templateConfig.skip :
|
|
112
|
-
[get(templateConfig, 'skip', '')]
|
|
113
|
-
|
|
114
|
-
const templates = allSourceFiles.filter(template => {
|
|
115
|
-
return !skipped.includes(template.replace(`${outputDir}/`, ''))
|
|
116
|
-
})
|
|
117
|
-
|
|
118
|
-
if (templates.length === 0) {
|
|
119
|
-
spinner.warn(`Error: no files with the .${extensions} extension found in ${templateConfig.source}`)
|
|
120
|
-
return
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
if (config.events && typeof config.events.beforeCreate === 'function') {
|
|
124
|
-
await config.events.beforeCreate(config)
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
for await (const file of templates) {
|
|
128
|
-
config.build.current = {
|
|
129
|
-
path: path.parse(file)
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
const html = await fs.readFile(file, 'utf8')
|
|
133
|
-
|
|
134
|
-
try {
|
|
135
|
-
const compiled = await render(html, {
|
|
136
|
-
useFileConfig: true,
|
|
137
|
-
maizzle: {
|
|
138
|
-
...config,
|
|
139
|
-
env
|
|
140
|
-
},
|
|
141
|
-
tailwind: {
|
|
142
|
-
compiled: css
|
|
143
|
-
},
|
|
144
|
-
...config.events
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
const destination = get(compiled, 'config.permalink', file)
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Generate plaintext
|
|
151
|
-
*
|
|
152
|
-
* We do this first so that we can remove the <plaintext>
|
|
153
|
-
* tags from the markup before outputting the file.
|
|
154
|
-
*/
|
|
155
|
-
|
|
156
|
-
// Check if plaintext: true globally, fallback to template's front matter
|
|
157
|
-
const plaintextConfig = get(templateConfig, 'plaintext', get(compiled.config, 'plaintext', false))
|
|
158
|
-
const plaintextPath = get(plaintextConfig, 'destination.path', destination)
|
|
159
|
-
|
|
160
|
-
if (Boolean(plaintextConfig) || !isEmpty(plaintextConfig)) {
|
|
161
|
-
await Plaintext
|
|
162
|
-
.generate(
|
|
163
|
-
compiled.html,
|
|
164
|
-
plaintextPath,
|
|
165
|
-
merge(plaintextConfig, {filepath: file})
|
|
166
|
-
)
|
|
167
|
-
.then(async ({html, plaintext, destination}) => {
|
|
168
|
-
compiled.html = html
|
|
169
|
-
await fs.outputFile(destination, plaintext)
|
|
170
|
-
})
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Output file
|
|
175
|
-
*/
|
|
176
|
-
const parts = path.parse(destination)
|
|
177
|
-
const extension = get(templateConfig, 'destination.extension', 'html')
|
|
178
|
-
const finalDestination = `${parts.dir}/${parts.name}.${extension}`
|
|
179
|
-
|
|
180
|
-
await fs.outputFile(finalDestination, compiled.html)
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Remove original file if its path is different
|
|
184
|
-
* from the final destination path.
|
|
185
|
-
*
|
|
186
|
-
* This ensures non-HTML files do not pollute
|
|
187
|
-
* the build destination folder.
|
|
188
|
-
*/
|
|
189
|
-
if (finalDestination !== file) {
|
|
190
|
-
await fs.remove(file)
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// Keep track of handled files
|
|
194
|
-
files.push(file)
|
|
195
|
-
parsed.push(file)
|
|
196
|
-
} catch (error) {
|
|
197
|
-
switch (config.build.fail) {
|
|
198
|
-
case 'silent':
|
|
199
|
-
spinner.warn(`Failed to compile template: ${path.basename(file)}`)
|
|
200
|
-
break
|
|
201
|
-
case 'verbose':
|
|
202
|
-
spinner.warn(`Failed to compile template: ${path.basename(file)}`)
|
|
203
|
-
console.error(error)
|
|
204
|
-
break
|
|
205
|
-
default:
|
|
206
|
-
spinner.fail(`Failed to compile template: ${path.basename(file)}`)
|
|
207
|
-
throw error
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
const assets = Array.isArray(get(templateConfig, 'assets'))
|
|
213
|
-
? get(templateConfig, 'assets')
|
|
214
|
-
: [{source: '', destination: 'assets', ...get(templateConfig, 'assets')}]
|
|
215
|
-
|
|
216
|
-
for await (const asset of assets) {
|
|
217
|
-
if (Array.isArray(asset.source)) {
|
|
218
|
-
for await (const source of asset.source) {
|
|
219
|
-
if (fs.existsSync(source)) {
|
|
220
|
-
await fs
|
|
221
|
-
.copy(source, path.join(templateConfig.destination.path, asset.destination))
|
|
222
|
-
.catch(error => spinner.warn(error.message))
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
} else {
|
|
226
|
-
if (fs.existsSync(asset.source)) {
|
|
227
|
-
await fs
|
|
228
|
-
.copy(asset.source, path.join(templateConfig.destination.path, asset.destination))
|
|
229
|
-
.catch(error => spinner.warn(error.message))
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
await glob(path.join(templateConfig.destination.path, '/**').replace(/\\/g, '/'))
|
|
235
|
-
.then(contents => {
|
|
236
|
-
files = [...new Set([...files, ...contents])]
|
|
237
|
-
})
|
|
238
|
-
})
|
|
239
|
-
.catch(error => {
|
|
240
|
-
throw error
|
|
241
|
-
})
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
if (config.events && typeof config.events.afterBuild === 'function') {
|
|
246
|
-
await config.events.afterBuild(files, config)
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
return {
|
|
250
|
-
files,
|
|
251
|
-
parsed,
|
|
252
|
-
css
|
|
253
|
-
}
|
|
254
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
const fm = require('front-matter')
|
|
2
|
-
const Config = require('../config')
|
|
3
|
-
const {get, merge} = require('lodash')
|
|
4
|
-
const posthtml = require('../posthtml')
|
|
5
|
-
const Tailwind = require('../tailwindcss')
|
|
6
|
-
const Transformers = require('../../transformers')
|
|
7
|
-
|
|
8
|
-
module.exports = async (html, options) => {
|
|
9
|
-
process.env.NODE_ENV = get(options, 'maizzle.env', 'local')
|
|
10
|
-
|
|
11
|
-
if (typeof html !== 'string') {
|
|
12
|
-
throw new TypeError(`first argument must be an HTML string, received ${html}`)
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
if (html.length === 0) {
|
|
16
|
-
throw new RangeError('received empty string')
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const fileConfig = get(options, 'useFileConfig')
|
|
20
|
-
? await Config.getMerged(process.env.NODE_ENV)
|
|
21
|
-
: {}
|
|
22
|
-
|
|
23
|
-
let config = merge(fileConfig, get(options, 'maizzle', {}))
|
|
24
|
-
|
|
25
|
-
const {frontmatter} = fm(html)
|
|
26
|
-
|
|
27
|
-
html = `---\n${frontmatter}\n---\n\n${fm(html).body}`
|
|
28
|
-
|
|
29
|
-
config = merge({applyTransformers: true}, config, fm(html).attributes)
|
|
30
|
-
|
|
31
|
-
if (typeof get(options, 'tailwind.compiled') === 'string') {
|
|
32
|
-
config.css = options.tailwind.compiled
|
|
33
|
-
} else {
|
|
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
|
-
})
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if (options && typeof options.beforeRender === 'function') {
|
|
48
|
-
html = await options.beforeRender(html, config)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
html = await posthtml(html, config)
|
|
52
|
-
|
|
53
|
-
while (Object.keys(fm(html).attributes).length > 0) {
|
|
54
|
-
html = fm(html).body
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (options && typeof options.afterRender === 'function') {
|
|
58
|
-
html = await options.afterRender(html, config)
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (config.applyTransformers) {
|
|
62
|
-
html = await Transformers.process(html, config)
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (options && typeof options.afterTransformers === 'function') {
|
|
66
|
-
html = await options.afterTransformers(html, config)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return {
|
|
70
|
-
html,
|
|
71
|
-
config
|
|
72
|
-
}
|
|
73
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
const {get} = require('lodash')
|
|
2
|
-
const postcss = require('postcss')
|
|
3
|
-
const postcssImport = require('postcss-import')
|
|
4
|
-
const postcssNested = require('tailwindcss/nesting')
|
|
5
|
-
const mergeLonghand = require('postcss-merge-longhand')
|
|
6
|
-
|
|
7
|
-
module.exports = {
|
|
8
|
-
process: async (css = '', maizzleConfig = {}) => {
|
|
9
|
-
return postcss([
|
|
10
|
-
postcssImport(),
|
|
11
|
-
postcssNested(),
|
|
12
|
-
get(maizzleConfig, 'shorthandCSS', get(maizzleConfig, 'shorthandInlineCSS')) === true ?
|
|
13
|
-
mergeLonghand() :
|
|
14
|
-
() => {},
|
|
15
|
-
...get(maizzleConfig, 'build.postcss.plugins', [])
|
|
16
|
-
])
|
|
17
|
-
.process(css, {from: undefined})
|
|
18
|
-
.then(result => result.css)
|
|
19
|
-
.catch(error => {
|
|
20
|
-
throw new SyntaxError(error)
|
|
21
|
-
})
|
|
22
|
-
}
|
|
23
|
-
}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
const fm = require('front-matter')
|
|
2
|
-
const posthtml = require('posthtml')
|
|
3
|
-
const fetch = require('posthtml-fetch')
|
|
4
|
-
const layouts = require('posthtml-extend')
|
|
5
|
-
const {get, merge, omit} = require('lodash')
|
|
6
|
-
const components = require('posthtml-component')
|
|
7
|
-
const defaultPosthtmlConfig = require('./defaultConfig')
|
|
8
|
-
const defaultComponentsConfig = require('./defaultComponentsConfig')
|
|
9
|
-
|
|
10
|
-
module.exports = async (html, config) => {
|
|
11
|
-
const posthtmlOptions = merge(defaultPosthtmlConfig, get(config, 'build.posthtml.options', {}))
|
|
12
|
-
const posthtmlPlugins = get(config, 'build.posthtml.plugins', [])
|
|
13
|
-
|
|
14
|
-
const componentsUserOptions = get(config, 'build.components', {})
|
|
15
|
-
|
|
16
|
-
const expressionsOptions = merge(
|
|
17
|
-
{
|
|
18
|
-
loopTags: ['each', 'for'],
|
|
19
|
-
strictMode: false
|
|
20
|
-
},
|
|
21
|
-
get(componentsUserOptions, 'expressions', {}),
|
|
22
|
-
get(config, 'build.posthtml.expressions', {})
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
const locals = merge(
|
|
26
|
-
get(expressionsOptions, 'locals', {}),
|
|
27
|
-
get(config, 'locals', {}),
|
|
28
|
-
{page: config}
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
const fetchPlugin = fetch(
|
|
32
|
-
merge(
|
|
33
|
-
{
|
|
34
|
-
expressions: merge(expressionsOptions, {locals})
|
|
35
|
-
},
|
|
36
|
-
get(config, 'build.posthtml.fetch', {})
|
|
37
|
-
)
|
|
38
|
-
)
|
|
39
|
-
|
|
40
|
-
const componentsOptions = merge(
|
|
41
|
-
{
|
|
42
|
-
...defaultComponentsConfig,
|
|
43
|
-
folders: [
|
|
44
|
-
...get(componentsUserOptions, 'folders', []),
|
|
45
|
-
...defaultComponentsConfig.folders
|
|
46
|
-
],
|
|
47
|
-
expressions: merge(expressionsOptions, {locals})
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
root: componentsUserOptions.root || './'
|
|
51
|
-
},
|
|
52
|
-
/**
|
|
53
|
-
* We omit `folders`, `root` and `expressions` in order to prevent duplicate
|
|
54
|
-
* array values, as they are already added above
|
|
55
|
-
*/
|
|
56
|
-
omit(componentsUserOptions, ['folders', 'root', 'expressions'])
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
return posthtml([
|
|
60
|
-
fetchPlugin,
|
|
61
|
-
layouts(
|
|
62
|
-
merge(
|
|
63
|
-
{
|
|
64
|
-
strict: false,
|
|
65
|
-
expressions: merge(expressionsOptions, {locals})
|
|
66
|
-
},
|
|
67
|
-
get(config, 'build.layouts', {})
|
|
68
|
-
)
|
|
69
|
-
),
|
|
70
|
-
components(componentsOptions),
|
|
71
|
-
...posthtmlPlugins
|
|
72
|
-
])
|
|
73
|
-
.process(html, {...posthtmlOptions})
|
|
74
|
-
.then(result => fm(result.html).body)
|
|
75
|
-
}
|
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
const path = require('path')
|
|
2
|
-
const fs = require('fs-extra')
|
|
3
|
-
const postcss = require('postcss')
|
|
4
|
-
const tailwindcss = require('tailwindcss')
|
|
5
|
-
const postcssImport = require('postcss-import')
|
|
6
|
-
const {get, merge, isObject, isEmpty} = require('lodash')
|
|
7
|
-
const postcssNested = require('tailwindcss/nesting')
|
|
8
|
-
const {requireUncached} = require('../utils/helpers')
|
|
9
|
-
const mergeLonghand = require('postcss-merge-longhand')
|
|
10
|
-
const defaultComponentsConfig = require('./posthtml/defaultComponentsConfig')
|
|
11
|
-
|
|
12
|
-
const addImportantPlugin = () => {
|
|
13
|
-
return {
|
|
14
|
-
postcssPlugin: 'add-important',
|
|
15
|
-
Rule(rule) {
|
|
16
|
-
const shouldAddImportant = get(rule, 'raws.tailwind.layer') === 'variants'
|
|
17
|
-
|| get(rule, 'parent.type') === 'atrule'
|
|
18
|
-
|
|
19
|
-
if (shouldAddImportant) {
|
|
20
|
-
rule.walkDecls(decl => {
|
|
21
|
-
decl.important = true
|
|
22
|
-
})
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
module.exports = {
|
|
29
|
-
compile: async ({css = '', html = '', config = {}}) => {
|
|
30
|
-
// Compute the Tailwind config to use
|
|
31
|
-
const userConfig = config => {
|
|
32
|
-
const tailwindUserConfig = get(config, 'build.tailwind.config', 'tailwind.config.js')
|
|
33
|
-
|
|
34
|
-
// If a custom config object was passed, use that
|
|
35
|
-
if (isObject(tailwindUserConfig) && !isEmpty(tailwindUserConfig)) {
|
|
36
|
-
return tailwindUserConfig
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Try loading a fresh tailwind.config.js, with fallback to an empty object.
|
|
41
|
-
* This will use the default Tailwind config (with rem units etc)
|
|
42
|
-
*/
|
|
43
|
-
try {
|
|
44
|
-
return requireUncached(path.resolve(process.cwd(), tailwindUserConfig))
|
|
45
|
-
} catch {
|
|
46
|
-
return {}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Merge user's Tailwind config on top of a 'base' config
|
|
51
|
-
const layoutsRoot = get(config, 'build.layouts.root')
|
|
52
|
-
const componentsRoot = get(config, 'build.components.root', defaultComponentsConfig.root)
|
|
53
|
-
|
|
54
|
-
const layoutsPath = typeof layoutsRoot === 'string' && layoutsRoot ?
|
|
55
|
-
`${layoutsRoot}/**/*.*`.replace(/\/\//g, '/') :
|
|
56
|
-
'src/layouts/**/*.*'
|
|
57
|
-
|
|
58
|
-
const componentsPath = defaultComponentsConfig.folders.map(folder => {
|
|
59
|
-
return path
|
|
60
|
-
.join(componentsRoot, folder, `**/*.${defaultComponentsConfig.fileExtension}`)
|
|
61
|
-
.replace(/\\/g, '/')
|
|
62
|
-
.replace(/\/\//g, '/')
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
const tailwindConfig = merge({
|
|
66
|
-
content: {
|
|
67
|
-
files: [
|
|
68
|
-
...componentsPath,
|
|
69
|
-
layoutsPath
|
|
70
|
-
]
|
|
71
|
-
}
|
|
72
|
-
}, userConfig(config))
|
|
73
|
-
|
|
74
|
-
// If `content` is an array, add it to `content.files`
|
|
75
|
-
if (Array.isArray(tailwindConfig.content)) {
|
|
76
|
-
tailwindConfig.content = {
|
|
77
|
-
files: [
|
|
78
|
-
...componentsPath,
|
|
79
|
-
layoutsPath,
|
|
80
|
-
...tailwindConfig.content
|
|
81
|
-
]
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// Add raw HTML if using API
|
|
86
|
-
if (html) {
|
|
87
|
-
tailwindConfig.content.files.push({raw: html, extension: 'html'})
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Include all `build.templates.source` paths when scanning for selectors to preserve
|
|
91
|
-
const buildTemplates = get(config, 'build.templates')
|
|
92
|
-
|
|
93
|
-
if (buildTemplates) {
|
|
94
|
-
const templateObjects = Array.isArray(buildTemplates) ? buildTemplates : [buildTemplates]
|
|
95
|
-
const configFileTypes = get(buildTemplates, 'filetypes', ['html'])
|
|
96
|
-
const fileTypes = Array.isArray(configFileTypes) ? configFileTypes : configFileTypes.split('|')
|
|
97
|
-
const fileTypesPattern = fileTypes.length > 1 ? `{${fileTypes.join(',')}}` : fileTypes[0]
|
|
98
|
-
|
|
99
|
-
templateObjects.forEach(template => {
|
|
100
|
-
const source = get(template, 'source')
|
|
101
|
-
|
|
102
|
-
if (typeof source === 'function') {
|
|
103
|
-
const sources = source(config)
|
|
104
|
-
|
|
105
|
-
if (Array.isArray(sources)) {
|
|
106
|
-
sources.map(s => tailwindConfig.content.files.push(`${s}/**/*.${fileTypesPattern}`))
|
|
107
|
-
} else if (typeof sources === 'string') {
|
|
108
|
-
tailwindConfig.content.files.push(sources)
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// Support single-file sources i.e. src/templates/index.html
|
|
113
|
-
else if (typeof source === 'string' && Boolean(path.extname(source))) {
|
|
114
|
-
tailwindConfig.content.files.push(source)
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// Default behavior - directory sources as a string
|
|
118
|
-
else {
|
|
119
|
-
tailwindConfig.content.files.push(`${source}/**/*.${fileTypesPattern}`)
|
|
120
|
-
}
|
|
121
|
-
})
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// Filter out any duplicate content paths
|
|
125
|
-
tailwindConfig.content.files = [...new Set(tailwindConfig.content.files)]
|
|
126
|
-
|
|
127
|
-
const userFilePath = get(config, 'build.tailwind.css', path.join(process.cwd(), 'src/css/tailwind.css'))
|
|
128
|
-
const userFileExists = await fs.pathExists(userFilePath)
|
|
129
|
-
|
|
130
|
-
const toProcess = [
|
|
131
|
-
postcssNested(),
|
|
132
|
-
tailwindcss(tailwindConfig),
|
|
133
|
-
get(tailwindConfig, 'important') === false ? () => {} : addImportantPlugin(),
|
|
134
|
-
get(config, 'shorthandCSS', get(config, 'shorthandInlineCSS')) === true ?
|
|
135
|
-
mergeLonghand() :
|
|
136
|
-
() => {},
|
|
137
|
-
...get(config, 'build.postcss.plugins', [])
|
|
138
|
-
]
|
|
139
|
-
|
|
140
|
-
if (userFileExists) {
|
|
141
|
-
css = await fs.readFile(path.resolve(userFilePath), 'utf8') + css
|
|
142
|
-
|
|
143
|
-
toProcess.unshift(
|
|
144
|
-
postcssImport({path: path.dirname(userFilePath)})
|
|
145
|
-
)
|
|
146
|
-
} else {
|
|
147
|
-
css = `@tailwind components; @tailwind utilities; ${css}`
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return postcss([...toProcess])
|
|
151
|
-
.process(css, {from: userFileExists ? userFilePath : undefined})
|
|
152
|
-
.then(result => result.css)
|
|
153
|
-
.catch(error => {
|
|
154
|
-
throw new SyntaxError(error)
|
|
155
|
-
})
|
|
156
|
-
}
|
|
157
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
const posthtml = require('posthtml')
|
|
2
|
-
const {get, merge, isObject} = require('lodash')
|
|
3
|
-
const addAttributes = require('posthtml-extra-attributes')
|
|
4
|
-
const defaultConfig = require('../generators/posthtml/defaultConfig')
|
|
5
|
-
|
|
6
|
-
module.exports = async (html, config = {}, direct = false) => {
|
|
7
|
-
if (get(config, 'extraAttributes') === false) {
|
|
8
|
-
return html
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const posthtmlOptions = merge(defaultConfig, get(config, 'build.posthtml.options', {}))
|
|
12
|
-
|
|
13
|
-
let attributes = {
|
|
14
|
-
table: {
|
|
15
|
-
cellpadding: 0,
|
|
16
|
-
cellspacing: 0,
|
|
17
|
-
role: 'none'
|
|
18
|
-
},
|
|
19
|
-
img: {
|
|
20
|
-
alt: ''
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
attributes = direct
|
|
25
|
-
? {...attributes, ...config}
|
|
26
|
-
: (
|
|
27
|
-
isObject(config.extraAttributes)
|
|
28
|
-
? {...attributes, ...config.extraAttributes}
|
|
29
|
-
: attributes
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
return posthtml([addAttributes({attributes})]).process(html, posthtmlOptions).then(result => result.html)
|
|
33
|
-
}
|