@nxgt/mail-config 0.1.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/LICENSE +21 -0
- package/README.md +239 -0
- package/dist/index.d.ts +72 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +173 -0
- package/dist/index.js.map +11 -0
- package/dist/layer.d.ts +10 -0
- package/dist/layer.d.ts.map +1 -0
- package/docs/README.md +14 -0
- package/docs/guide/config.md +305 -0
- package/docs/guide/plugins.md +280 -0
- package/docs/guide/production.md +168 -0
- package/docs/roadmap.md +76 -0
- package/docs/troubleshooting.md +497 -0
- package/package.json +58 -0
|
@@ -0,0 +1,497 @@
|
|
|
1
|
+
# Troubleshooting `@nxgt/mail-config`
|
|
2
|
+
|
|
3
|
+
Each entry is headed by the message you see. The last section holds the
|
|
4
|
+
traps that print nothing — a build that succeeds and is wrong. Search this
|
|
5
|
+
page for the words of your message.
|
|
6
|
+
|
|
7
|
+
How the messages are shaped:
|
|
8
|
+
|
|
9
|
+
- **Every message starts with the call you wrote**: `defineMailConfig: …`,
|
|
10
|
+
`defineMailPlugin: …` or `productionConfig: …`. A plugin checked by
|
|
11
|
+
`defineMailPlugin` is refused with its own messages, when the module that
|
|
12
|
+
defines it loads.
|
|
13
|
+
- **Every refusal is a `TypeError`**, thrown when `maizzle.config.ts` (or the
|
|
14
|
+
production config) is loaded: `maizzle build` and `maizzle serve` stop
|
|
15
|
+
before any template is read. It is a wiring mistake; fix the config.
|
|
16
|
+
- **A plugin is named by its `name`** when it has one — otherwise by its
|
|
17
|
+
position in `plugins` (`plugins[1]`) from `defineMailConfig`, or as `plugin`
|
|
18
|
+
from `defineMailPlugin`.
|
|
19
|
+
|
|
20
|
+
## Index
|
|
21
|
+
|
|
22
|
+
**Install and types**
|
|
23
|
+
- [Which `moduleResolution` is supported](#install-and-types)
|
|
24
|
+
|
|
25
|
+
**Configuration**
|
|
26
|
+
- [`defineMailConfig: config must be an object, as { plugins, ...maizzleConfig }`](#definemailconfig-config-must-be-an-object-as--plugins-maizzleconfig-)
|
|
27
|
+
- [`defineMailConfig: plugins must be an array`](#definemailconfig-plugins-must-be-an-array)
|
|
28
|
+
- [`defineMailConfig: plugins[0] must be a plugin object, as { name, ...config } — was it called?`](#definemailconfig-plugins0-must-be-a-plugin-object-as--name-config---was-it-called)
|
|
29
|
+
- [`defineMailConfig: plugins[1] has no name — a plugin is { name, ...config }`](#definemailconfig-plugins1-has-no-name--a-plugin-is--name-config-)
|
|
30
|
+
- [`defineMailConfig: plugin "brand" lists plugins — a plugin cannot bring others; list them in the project`](#definemailconfig-plugin-brand-lists-plugins--a-plugin-cannot-bring-others-list-them-in-the-project)
|
|
31
|
+
- [`defineMailConfig: two plugins are named "brand" — is one listed twice?`](#definemailconfig-two-plugins-are-named-brand--is-one-listed-twice)
|
|
32
|
+
- [`defineMailConfig: plugin "brand": afterBuild must be a function`](#definemailconfig-plugin-brand-afterbuild-must-be-a-function)
|
|
33
|
+
- [`defineMailConfig: beforeRender must be a function`](#definemailconfig-beforerender-must-be-a-function)
|
|
34
|
+
- [`defineMailPlugin: plugin must be a plugin object, as { name, ...config } — was it called?`](#definemailplugin-plugin-must-be-a-plugin-object-as--name-config---was-it-called)
|
|
35
|
+
- [`defineMailPlugin: plugin has no name — a plugin is { name, ...config }`](#definemailplugin-plugin-has-no-name--a-plugin-is--name-config-)
|
|
36
|
+
- [`defineMailPlugin: plugin "brand" lists plugins — a plugin cannot bring others; list them in the project`](#definemailplugin-plugin-brand-lists-plugins--a-plugin-cannot-bring-others-list-them-in-the-project)
|
|
37
|
+
- [`defineMailPlugin: plugin "brand": beforeRender must be a function`](#definemailplugin-plugin-brand-beforerender-must-be-a-function)
|
|
38
|
+
- [`productionConfig: config must be the project config, as productionConfig(config, overrides)`](#productionconfig-config-must-be-the-project-config-as-productionconfigconfig-overrides)
|
|
39
|
+
- [`productionConfig: config lists plugins — pass what defineMailConfig answered, not its argument`](#productionconfig-config-lists-plugins--pass-what-definemailconfig-answered-not-its-argument)
|
|
40
|
+
- [`productionConfig: overrides must be an object`](#productionconfig-overrides-must-be-an-object)
|
|
41
|
+
- [`productionConfig: overrides list plugins — list every plugin in the project config`](#productionconfig-overrides-list-plugins--list-every-plugin-in-the-project-config)
|
|
42
|
+
- [`productionConfig: afterBuild must be a function`](#productionconfig-afterbuild-must-be-a-function)
|
|
43
|
+
|
|
44
|
+
**Traps that print nothing**
|
|
45
|
+
- [No Tailwind utility in the built HTML](#no-tailwind-utility-in-the-built-html)
|
|
46
|
+
- [A plugin's `content` (or another list) disappears](#a-plugins-content-or-another-list-disappears)
|
|
47
|
+
- [`maizzle build -c maizzle.config.production.ts` ignores `maizzle.config.ts`](#maizzle-build--c-maizzleconfigproductionts-ignores-maizzleconfigts)
|
|
48
|
+
- [A hook's change is lost](#a-hooks-change-is-lost)
|
|
49
|
+
- [A plugin's component tag stays in the HTML, unresolved](#a-plugins-component-tag-stays-in-the-html-unresolved)
|
|
50
|
+
- [One of two configs' hooks never runs](#one-of-two-configs-hooks-never-runs)
|
|
51
|
+
- [A bug in `@nxgt/mail-config` itself](#a-bug-in-nxgtmail-config-itself)
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Install and types
|
|
56
|
+
|
|
57
|
+
Resolve as a bundler does (`"moduleResolution": "bundler"`, as Maizzle's jiti
|
|
58
|
+
loader does): that is the supported contract. `nodenext` and `node16` are out
|
|
59
|
+
of contract — they may work today, and are not tested.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Configuration
|
|
64
|
+
|
|
65
|
+
### `defineMailConfig: config must be an object, as { plugins, ...maizzleConfig }`
|
|
66
|
+
|
|
67
|
+
**When:** loading `maizzle.config.ts`, when `defineMailConfig` is given
|
|
68
|
+
`null`, an array, or a function.
|
|
69
|
+
**Why:** `defineMailConfig` takes one object: your Maizzle config, with the
|
|
70
|
+
plugins in its `plugins` key. It does not take the plugins as its argument.
|
|
71
|
+
**Fix:**
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
// maizzle.config.ts
|
|
75
|
+
import { defineMailConfig } from '@nxgt/mail-config';
|
|
76
|
+
import { brand } from './brand';
|
|
77
|
+
|
|
78
|
+
export default defineMailConfig({
|
|
79
|
+
plugins: [brand],
|
|
80
|
+
output: { path: 'dist' },
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
`defineMailConfig()` with no argument is valid: the base config alone.
|
|
85
|
+
|
|
86
|
+
### `defineMailConfig: plugins must be an array`
|
|
87
|
+
|
|
88
|
+
**When:** loading `maizzle.config.ts`, with `plugins` set to one plugin, or to
|
|
89
|
+
an object of plugins.
|
|
90
|
+
**Why:** plugins are layered in the order they are listed; only an array has
|
|
91
|
+
one.
|
|
92
|
+
**Fix:**
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
export default defineMailConfig({ plugins: [brand] }); // not plugins: brand
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### `defineMailConfig: plugins[0] must be a plugin object, as { name, ...config } — was it called?`
|
|
99
|
+
|
|
100
|
+
The index is the position of the plugin in your `plugins` array.
|
|
101
|
+
|
|
102
|
+
**When:** loading `maizzle.config.ts`, when an entry of `plugins` is not a
|
|
103
|
+
plain object: most often a plugin factory listed without calling it, or a
|
|
104
|
+
`false` left by a condition.
|
|
105
|
+
**Why:** a plugin is an object — a partial Maizzle config with a `name`. A
|
|
106
|
+
package usually exports a function that answers one, and the function itself
|
|
107
|
+
is not a plugin.
|
|
108
|
+
**Fix:** call the factory, and filter a conditional plugin out rather than
|
|
109
|
+
leaving `false` in the list:
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
import { defineMailConfig } from '@nxgt/mail-config';
|
|
113
|
+
import { footer } from './footer';
|
|
114
|
+
import { preview } from './preview';
|
|
115
|
+
|
|
116
|
+
export default defineMailConfig({
|
|
117
|
+
plugins: [
|
|
118
|
+
footer(), // not footer
|
|
119
|
+
...(process.env.PREVIEW ? [preview()] : []), // not PREVIEW && preview()
|
|
120
|
+
],
|
|
121
|
+
});
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### `defineMailConfig: plugins[1] has no name — a plugin is { name, ...config }`
|
|
125
|
+
|
|
126
|
+
The index is the position of the plugin in your `plugins` array.
|
|
127
|
+
|
|
128
|
+
**When:** loading `maizzle.config.ts`, for a plugin whose `name` is missing,
|
|
129
|
+
not a string, or blank.
|
|
130
|
+
**Why:** the name tells two plugins apart, and names the plugin in every
|
|
131
|
+
other message. A plain Maizzle config object listed as a plugin has none.
|
|
132
|
+
**Fix:**
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
// brand.ts
|
|
136
|
+
import { defineMailPlugin } from '@nxgt/mail-config';
|
|
137
|
+
|
|
138
|
+
export const brand = defineMailPlugin({
|
|
139
|
+
name: 'brand',
|
|
140
|
+
css: { inline: true },
|
|
141
|
+
});
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### `defineMailConfig: plugin "brand" lists plugins — a plugin cannot bring others; list them in the project`
|
|
145
|
+
|
|
146
|
+
**When:** loading `maizzle.config.ts`, for a plugin that has a `plugins` key.
|
|
147
|
+
`tsc` refuses it first when the plugin is typed `MailPlugin`.
|
|
148
|
+
**Why:** plugins are layered once, in the order the project lists them. A
|
|
149
|
+
plugin that carried others would hide them from that order, and from the
|
|
150
|
+
check for two plugins of the same name.
|
|
151
|
+
**Fix:** export the plugins side by side, and list each one in the project:
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
// maizzle.config.ts
|
|
155
|
+
import { defineMailConfig } from '@nxgt/mail-config';
|
|
156
|
+
import { brand, footer } from './plugins';
|
|
157
|
+
|
|
158
|
+
export default defineMailConfig({ plugins: [brand, footer] });
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### `defineMailConfig: two plugins are named "brand" — is one listed twice?`
|
|
162
|
+
|
|
163
|
+
**When:** loading `maizzle.config.ts`, when two entries of `plugins` carry
|
|
164
|
+
the same `name`.
|
|
165
|
+
**Why:** the same plugin listed twice would run each of its hooks twice. Two
|
|
166
|
+
different plugins with the same name could not be told apart in a message.
|
|
167
|
+
**Fix:** list each plugin once. To change a plugin's settings, set the key in
|
|
168
|
+
your own config — the project is layered over every plugin — rather than
|
|
169
|
+
listing the plugin again:
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
export default defineMailConfig({
|
|
173
|
+
plugins: [brand],
|
|
174
|
+
css: { inline: false }, // wins over what brand sets
|
|
175
|
+
});
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Two different plugins of the same name need one of them renamed where it is
|
|
179
|
+
defined.
|
|
180
|
+
|
|
181
|
+
### `defineMailConfig: plugin "brand": afterBuild must be a function`
|
|
182
|
+
|
|
183
|
+
The event is the one that is wrong: `beforeCreate`, `beforeRender`,
|
|
184
|
+
`afterRender`, `afterTransform` or `afterBuild`.
|
|
185
|
+
|
|
186
|
+
**When:** loading `maizzle.config.ts`, for a plugin whose build event is set to
|
|
187
|
+
something other than a function.
|
|
188
|
+
**Why:** each build event is one function, which `defineMailConfig` chains
|
|
189
|
+
with the other layers'. An array of handlers, a string, or the result of
|
|
190
|
+
calling the handler (`afterBuild: done()`) cannot be chained.
|
|
191
|
+
**Fix:** hand the function itself; to run two things on one event, call both
|
|
192
|
+
from one function:
|
|
193
|
+
|
|
194
|
+
```ts
|
|
195
|
+
import { defineMailPlugin } from '@nxgt/mail-config';
|
|
196
|
+
import { report } from './report';
|
|
197
|
+
import { upload } from './upload';
|
|
198
|
+
|
|
199
|
+
export const brand = defineMailPlugin({
|
|
200
|
+
name: 'brand',
|
|
201
|
+
afterBuild: async (params) => {
|
|
202
|
+
await report(params);
|
|
203
|
+
await upload(params);
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### `defineMailConfig: beforeRender must be a function`
|
|
209
|
+
|
|
210
|
+
**When:** loading `maizzle.config.ts`, when your own config — not a plugin —
|
|
211
|
+
sets a build event to something other than a function.
|
|
212
|
+
**Why and fix:** as in the entry above; the message has no plugin name
|
|
213
|
+
because the value is in the project's own keys.
|
|
214
|
+
|
|
215
|
+
### `defineMailPlugin: plugin must be a plugin object, as { name, ...config } — was it called?`
|
|
216
|
+
|
|
217
|
+
**When:** importing the module that calls `defineMailPlugin`, when its
|
|
218
|
+
argument is not a plain object — `null`, an array, or a function.
|
|
219
|
+
**Why:** `defineMailPlugin` takes the plugin itself, `{ name, ...config }`,
|
|
220
|
+
and answers it unchanged. It is not a factory, and does not take one.
|
|
221
|
+
**Fix:** pass the object; to take options, wrap the call in your own
|
|
222
|
+
function:
|
|
223
|
+
|
|
224
|
+
```ts
|
|
225
|
+
import { defineMailPlugin } from '@nxgt/mail-config';
|
|
226
|
+
|
|
227
|
+
export const brand = (company: string) =>
|
|
228
|
+
defineMailPlugin({ name: 'brand', vue: { globalProperties: { company } } });
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### `defineMailPlugin: plugin has no name — a plugin is { name, ...config }`
|
|
232
|
+
|
|
233
|
+
**When:** importing the module that calls `defineMailPlugin`, for a plugin
|
|
234
|
+
whose `name` is missing, not a string, or blank.
|
|
235
|
+
**Why and fix:** as for
|
|
236
|
+
[`plugins[1] has no name`](#definemailconfig-plugins1-has-no-name--a-plugin-is--name-config-):
|
|
237
|
+
give the plugin a `name`.
|
|
238
|
+
|
|
239
|
+
### `defineMailPlugin: plugin "brand" lists plugins — a plugin cannot bring others; list them in the project`
|
|
240
|
+
|
|
241
|
+
**When:** importing the module that calls `defineMailPlugin`, for a plugin
|
|
242
|
+
with a `plugins` key. `tsc` refuses it first: `MailPlugin` declares
|
|
243
|
+
`plugins?: never`.
|
|
244
|
+
**Why and fix:** as for
|
|
245
|
+
[the same message from `defineMailConfig`](#definemailconfig-plugin-brand-lists-plugins--a-plugin-cannot-bring-others-list-them-in-the-project):
|
|
246
|
+
export the plugins side by side, and let the project list each one.
|
|
247
|
+
|
|
248
|
+
### `defineMailPlugin: plugin "brand": beforeRender must be a function`
|
|
249
|
+
|
|
250
|
+
The event is the one that is wrong: `beforeCreate`, `beforeRender`,
|
|
251
|
+
`afterRender`, `afterTransform` or `afterBuild`.
|
|
252
|
+
|
|
253
|
+
**When:** importing the module that calls `defineMailPlugin`, for a plugin
|
|
254
|
+
whose build event is set to something other than a function.
|
|
255
|
+
**Why and fix:** as for
|
|
256
|
+
[the same message from `defineMailConfig`](#definemailconfig-plugin-brand-afterbuild-must-be-a-function):
|
|
257
|
+
hand the function itself.
|
|
258
|
+
|
|
259
|
+
### `productionConfig: config must be the project config, as productionConfig(config, overrides)`
|
|
260
|
+
|
|
261
|
+
**When:** `maizzle build -c maizzle.config.production.ts`, when the first
|
|
262
|
+
argument of `productionConfig` is not an object: typically `undefined`,
|
|
263
|
+
because the import of the project config did not pick up its default export.
|
|
264
|
+
**Why:** `productionConfig` layers the production settings over the project
|
|
265
|
+
config, and needs it as its first argument. It does not take the overrides
|
|
266
|
+
alone.
|
|
267
|
+
**Fix:**
|
|
268
|
+
|
|
269
|
+
```ts
|
|
270
|
+
// maizzle.config.production.ts
|
|
271
|
+
import { productionConfig } from '@nxgt/mail-config';
|
|
272
|
+
import config from './maizzle.config'; // the default export
|
|
273
|
+
|
|
274
|
+
export default productionConfig(config, { output: { path: 'dist-production' } });
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### `productionConfig: config lists plugins — pass what defineMailConfig answered, not its argument`
|
|
278
|
+
|
|
279
|
+
**When:** `maizzle build -c maizzle.config.production.ts`, when the config
|
|
280
|
+
handed to `productionConfig` still has a `plugins` key.
|
|
281
|
+
**Why:** `productionConfig` does not layer plugins; it expects the config
|
|
282
|
+
`defineMailConfig` already answered, plugins merged and hooks chained. An
|
|
283
|
+
object with `plugins` in it is `defineMailConfig`'s argument, exported or
|
|
284
|
+
imported before the call.
|
|
285
|
+
**Fix:** export what `defineMailConfig` answers, and import that:
|
|
286
|
+
|
|
287
|
+
```ts
|
|
288
|
+
// maizzle.config.ts
|
|
289
|
+
import { defineMailConfig } from '@nxgt/mail-config';
|
|
290
|
+
import { brand } from './brand';
|
|
291
|
+
|
|
292
|
+
export default defineMailConfig({ plugins: [brand] }); // not export default { plugins: [brand] }
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### `productionConfig: overrides must be an object`
|
|
296
|
+
|
|
297
|
+
**When:** `maizzle build -c maizzle.config.production.ts`, when the second
|
|
298
|
+
argument of `productionConfig` is not a plain object: an array, `null`, or a
|
|
299
|
+
function.
|
|
300
|
+
**Why:** the overrides are one partial Maizzle config, layered last.
|
|
301
|
+
**Fix:**
|
|
302
|
+
|
|
303
|
+
```ts
|
|
304
|
+
export default productionConfig(config, { output: { path: 'dist-production' } });
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
Leave the second argument out when there is nothing to override.
|
|
308
|
+
|
|
309
|
+
### `productionConfig: overrides list plugins — list every plugin in the project config`
|
|
310
|
+
|
|
311
|
+
**When:** `maizzle build -c maizzle.config.production.ts`, when the second
|
|
312
|
+
argument of `productionConfig` has a `plugins` key. `tsc` refuses it first.
|
|
313
|
+
**Why:** plugins are layered once, by `defineMailConfig`, in the order the
|
|
314
|
+
project lists them. The overrides are layered over that result, as one more
|
|
315
|
+
plugin would be — they cannot carry plugins of their own.
|
|
316
|
+
**Fix:** list the plugin in `maizzle.config.ts`. What only production needs
|
|
317
|
+
goes in the overrides as plain config keys: their `components.source`,
|
|
318
|
+
`vite.plugins` and `vue.plugins` are added to the project's, and their build
|
|
319
|
+
events run after the project's.
|
|
320
|
+
|
|
321
|
+
```ts
|
|
322
|
+
// maizzle.config.production.ts
|
|
323
|
+
import { productionConfig } from '@nxgt/mail-config';
|
|
324
|
+
import config from './maizzle.config';
|
|
325
|
+
|
|
326
|
+
export default productionConfig(config, {
|
|
327
|
+
output: { path: 'dist-production' },
|
|
328
|
+
afterBuild: async ({ files }) => {
|
|
329
|
+
console.log(`${files.length} files built for production`);
|
|
330
|
+
},
|
|
331
|
+
});
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### `productionConfig: afterBuild must be a function`
|
|
335
|
+
|
|
336
|
+
The event is the one that is wrong: `beforeCreate`, `beforeRender`,
|
|
337
|
+
`afterRender`, `afterTransform` or `afterBuild`.
|
|
338
|
+
|
|
339
|
+
**When:** `maizzle build -c maizzle.config.production.ts`, when an override
|
|
340
|
+
sets a build event to something other than a function.
|
|
341
|
+
**Why:** an override's hook is chained after the project's, and must be a
|
|
342
|
+
function, as in a plugin.
|
|
343
|
+
**Fix:**
|
|
344
|
+
|
|
345
|
+
```ts
|
|
346
|
+
export default productionConfig(config, {
|
|
347
|
+
afterBuild: async ({ files }) => {
|
|
348
|
+
console.log(`${files.length} files built`);
|
|
349
|
+
},
|
|
350
|
+
});
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
## Traps that print nothing
|
|
356
|
+
|
|
357
|
+
### No Tailwind utility in the built HTML
|
|
358
|
+
|
|
359
|
+
**When:** `maizzle build` or `maizzle serve` succeeds, but the classes stay
|
|
360
|
+
in the HTML (`class="p-4"`) with no CSS behind them, and nothing is inlined.
|
|
361
|
+
Typically under Bun workspaces or pnpm.
|
|
362
|
+
**Why:** those package managers install in isolation: a peer that your
|
|
363
|
+
project does not list itself is not linked where Maizzle's Tailwind looks for
|
|
364
|
+
it. The `@import "@maizzle/tailwindcss"` in the layout then fails silently,
|
|
365
|
+
and no utility is generated.
|
|
366
|
+
**Fix:** make `@maizzle/tailwindcss` a direct dependency of the project,
|
|
367
|
+
next to `@maizzle/framework`:
|
|
368
|
+
|
|
369
|
+
```sh
|
|
370
|
+
bun add @nxgt/mail-config @maizzle/framework @maizzle/tailwindcss
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
If it is installed and there are still no utilities, check the layout: the
|
|
374
|
+
`@import "@maizzle/tailwindcss"` must be a literal import in the same
|
|
375
|
+
`<style>` as your theme, or Maizzle scans no source.
|
|
376
|
+
|
|
377
|
+
### A plugin's `content` (or another list) disappears
|
|
378
|
+
|
|
379
|
+
**When:** `maizzle build` succeeds, but templates, static files or watched
|
|
380
|
+
paths a plugin set are missing — right after the project set the same key.
|
|
381
|
+
**Why:** configs merge as Maizzle merges them: objects key by key, but **an
|
|
382
|
+
array replaces** the array under it. Your `content`, `static.source` or
|
|
383
|
+
`server.watch` replaces the plugin's, and Maizzle's default too. Only three
|
|
384
|
+
lists are joined across layers: `components.source`, `vite.plugins` and
|
|
385
|
+
`vue.plugins`.
|
|
386
|
+
**Fix:** leave the key to the plugin, or repeat the entries you keep in your
|
|
387
|
+
own list:
|
|
388
|
+
|
|
389
|
+
```ts
|
|
390
|
+
import { defineMailConfig } from '@nxgt/mail-config';
|
|
391
|
+
import { brand } from './brand';
|
|
392
|
+
|
|
393
|
+
export default defineMailConfig({
|
|
394
|
+
plugins: [brand],
|
|
395
|
+
content: [...(brand.content ?? []), 'emails/**/*.{vue,md}', 'drafts/**/*.vue'],
|
|
396
|
+
});
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### `maizzle build -c maizzle.config.production.ts` ignores `maizzle.config.ts`
|
|
400
|
+
|
|
401
|
+
**When:** the production build runs without your plugins, your components or
|
|
402
|
+
your hooks — the output looks like a bare Maizzle project.
|
|
403
|
+
**Why:** Maizzle has no environments. `-c` loads the file it is given and
|
|
404
|
+
**only** that file; nothing is merged from `maizzle.config.ts`.
|
|
405
|
+
**Fix:** import the project config in the production file, and layer over it
|
|
406
|
+
with `productionConfig`, which also minifies the HTML:
|
|
407
|
+
|
|
408
|
+
```ts
|
|
409
|
+
// maizzle.config.production.ts
|
|
410
|
+
import { productionConfig } from '@nxgt/mail-config';
|
|
411
|
+
import config from './maizzle.config';
|
|
412
|
+
|
|
413
|
+
export default productionConfig(config, { output: { path: 'dist-production' } });
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### A hook's change is lost
|
|
417
|
+
|
|
418
|
+
**When:** a `beforeRender`, `afterRender` or `afterTransform` hook runs, but
|
|
419
|
+
the next hook — and the built file — does not see what it did.
|
|
420
|
+
**Why:** hooks are chained as Maizzle chains its own: **only a string
|
|
421
|
+
returned** replaces `template.source` (for `beforeRender`) or the `html` the
|
|
422
|
+
next hook receives. `undefined` means "leave it as is"; any other value — an
|
|
423
|
+
object such as `{ html }`, a `Buffer` — is ignored the same way. Reassigning
|
|
424
|
+
`params.html` changes nothing either: each hook receives its own `html`.
|
|
425
|
+
`beforeCreate` and `afterBuild` answer nothing; `beforeCreate` changes
|
|
426
|
+
`config` in place.
|
|
427
|
+
**Fix:** return the string:
|
|
428
|
+
|
|
429
|
+
```ts
|
|
430
|
+
import { defineMailPlugin } from '@nxgt/mail-config';
|
|
431
|
+
import posthtml from 'posthtml';
|
|
432
|
+
|
|
433
|
+
export const tidy = defineMailPlugin({
|
|
434
|
+
name: 'tidy',
|
|
435
|
+
afterTransform: async ({ html }) => {
|
|
436
|
+
const result = await posthtml([]).process(html);
|
|
437
|
+
return result.html; // not return result
|
|
438
|
+
},
|
|
439
|
+
});
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
### A plugin's component tag stays in the HTML, unresolved
|
|
443
|
+
|
|
444
|
+
**When:** `maizzle build` succeeds, but a plugin's component — say
|
|
445
|
+
`<BrandFooter>` — is not rendered: the tag is left unresolved in the built
|
|
446
|
+
HTML.
|
|
447
|
+
**Why:** the plugin set `components.source` to a relative path
|
|
448
|
+
(`'./components'`). Maizzle resolves a relative `components.source` against
|
|
449
|
+
the directory `maizzle` runs in — the project — not against the plugin's
|
|
450
|
+
file, so it looks for the folder in the wrong place and finds no component.
|
|
451
|
+
**Fix:** make the path absolute, relative to the plugin's own file:
|
|
452
|
+
|
|
453
|
+
```ts
|
|
454
|
+
import { fileURLToPath } from 'node:url';
|
|
455
|
+
import { defineMailPlugin } from '@nxgt/mail-config';
|
|
456
|
+
|
|
457
|
+
export const brand = defineMailPlugin({
|
|
458
|
+
name: 'brand',
|
|
459
|
+
components: {
|
|
460
|
+
source: [{ path: fileURLToPath(new URL('./components', import.meta.url)), prefix: 'Brand' }],
|
|
461
|
+
},
|
|
462
|
+
});
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
When the plugin is compiled to `dist/`, point the URL at where the folder sits
|
|
466
|
+
from the built file (`'../components'`), and ship the folder in `files`.
|
|
467
|
+
|
|
468
|
+
### One of two configs' hooks never runs
|
|
469
|
+
|
|
470
|
+
**When:** the build succeeds, but a `beforeRender` (or any other build event)
|
|
471
|
+
from one of two configs you combined has no effect.
|
|
472
|
+
**Why:** spreading configs yourself — `{ ...a, ...b }` — keeps one value per
|
|
473
|
+
key: `b.beforeRender` replaces `a.beforeRender`, without a word. Nested
|
|
474
|
+
objects are replaced the same way (`b.css` drops every key of `a.css`).
|
|
475
|
+
**Fix:** give each config a `name` and list both as plugins; their hooks are
|
|
476
|
+
chained, in order, and their objects merged:
|
|
477
|
+
|
|
478
|
+
```ts
|
|
479
|
+
import { defineMailConfig } from '@nxgt/mail-config';
|
|
480
|
+
import { a, b } from './configs';
|
|
481
|
+
|
|
482
|
+
// not: export default defineMailConfig({ ...a, ...b });
|
|
483
|
+
export default defineMailConfig({
|
|
484
|
+
plugins: [
|
|
485
|
+
{ name: 'a', ...a },
|
|
486
|
+
{ name: 'b', ...b },
|
|
487
|
+
],
|
|
488
|
+
});
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
### A bug in `@nxgt/mail-config` itself
|
|
492
|
+
|
|
493
|
+
A refusal of a config this page says is valid, or two plugins' hooks that do
|
|
494
|
+
not both run, in order, is a bug in this package. Open an issue on
|
|
495
|
+
[`softistx/nxgt-mail`](https://github.com/softistx/nxgt-mail/issues) with the
|
|
496
|
+
message, the package version, the Maizzle version and the smallest
|
|
497
|
+
`maizzle.config.ts` that reproduces it.
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nxgt/mail-config",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A shareable Maizzle config: defineMailConfig layers plugins under the project's own config, with every build event chained instead of overwritten.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"docs",
|
|
12
|
+
"README.md",
|
|
13
|
+
"package.json",
|
|
14
|
+
"LICENSE"
|
|
15
|
+
],
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"import": "./dist/index.js",
|
|
20
|
+
"default": "./dist/index.js"
|
|
21
|
+
},
|
|
22
|
+
"./package.json": "./package.json"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"email",
|
|
26
|
+
"maizzle",
|
|
27
|
+
"config",
|
|
28
|
+
"plugins",
|
|
29
|
+
"tailwindcss"
|
|
30
|
+
],
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "git+https://github.com/softistx/nxgt-mail.git",
|
|
34
|
+
"directory": "packages/mail-config"
|
|
35
|
+
},
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"registry": "https://registry.npmjs.org",
|
|
38
|
+
"access": "public"
|
|
39
|
+
},
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "bun run ../../build.ts",
|
|
42
|
+
"test": "bun test src",
|
|
43
|
+
"typecheck": "tsc --noEmit"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"defu": "^6.1.4"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@maizzle/framework": "6.1.7",
|
|
50
|
+
"@maizzle/tailwindcss": "1.5.6",
|
|
51
|
+
"@types/bun": "^1.4.2"
|
|
52
|
+
},
|
|
53
|
+
"peerDependencies": {
|
|
54
|
+
"@maizzle/framework": "^6.1.7",
|
|
55
|
+
"@maizzle/tailwindcss": "^1.5.6",
|
|
56
|
+
"typescript": "^6.0.3"
|
|
57
|
+
}
|
|
58
|
+
}
|