@eleventy-plugin-themer/build-vite 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 +161 -0
- package/index.mjs +260 -0
- package/package.json +63 -0
- package/plugins/auto-import.mjs +82 -0
- package/plugins/critical-css.mjs +31 -0
- package/plugins/feature-serve.mjs +51 -0
- package/plugins/index.mjs +15 -0
- package/plugins/minify-html.mjs +66 -0
- package/plugins/preserve-non-html.mjs +55 -0
- package/plugins/prism-theme.mjs +61 -0
- package/plugins/purge-css.mjs +64 -0
- package/plugins/validate-links.mjs +164 -0
- package/postcss.mjs +113 -0
- package/theme-config.mjs +245 -0
- package/utils/constants.mjs +23 -0
- package/utils/features.mjs +98 -0
- package/utils/file-processor.mjs +122 -0
- package/utils/integration-check.mjs +146 -0
- package/utils/merge-arrays.mjs +34 -0
- package/utils/merge-config.mjs +99 -0
- package/utils/plugin-orchestrator.mjs +74 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for merging Vite configuration objects
|
|
3
|
+
*
|
|
4
|
+
* Provides deep merge functionality for Vite config, handling nested
|
|
5
|
+
* objects like resolve.alias, css.preprocessorOptions, and plugins arrays.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { UNSAFE_KEYS } from '@eleventy-plugin-themer/core/internal/safe-keys';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Deep merge Vite configuration objects.
|
|
12
|
+
*
|
|
13
|
+
* Merges a base theme config with user-provided overrides.
|
|
14
|
+
* Handles special cases for Vite's nested config structure:
|
|
15
|
+
* - resolve.alias: Merged (user aliases override theme)
|
|
16
|
+
* - css.preprocessorOptions.scss: Merged deeply
|
|
17
|
+
* - plugins: Concatenated (theme first, then user)
|
|
18
|
+
*
|
|
19
|
+
* NOTE: Distinct from `deepMergeConfig` in core by design. This variant is
|
|
20
|
+
* shallow with an explicit set of deep-merge keys (`resolve`, `css`,
|
|
21
|
+
* `build` incl. `rollupOptions.input`, `server`) matched to Vite's config
|
|
22
|
+
* shape. Other top-level keys use shallow spread. If you add a new
|
|
23
|
+
* deep-merge key, update both this function and its tests.
|
|
24
|
+
*
|
|
25
|
+
* @param {Object} themeConfig - Base theme Vite configuration
|
|
26
|
+
* @param {Object} userConfig - User's Vite configuration overrides
|
|
27
|
+
* @returns {Object} Merged Vite configuration
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* const mergedConfig = deepMergeViteConfig(themeConfig, {
|
|
31
|
+
* resolve: { alias: { '@custom': '/path/to/custom' } },
|
|
32
|
+
* css: { preprocessorOptions: { scss: { additionalData: '$color: red;' } } },
|
|
33
|
+
* });
|
|
34
|
+
*/
|
|
35
|
+
export function deepMergeViteConfig(themeConfig, userConfig = {}) {
|
|
36
|
+
// Strip unsafe keys to prevent prototype pollution
|
|
37
|
+
const safeTheme = Object.fromEntries(
|
|
38
|
+
Object.entries(themeConfig).filter(([k]) => !UNSAFE_KEYS.has(k)),
|
|
39
|
+
);
|
|
40
|
+
const safeUser = Object.fromEntries(
|
|
41
|
+
Object.entries(userConfig).filter(([k]) => !UNSAFE_KEYS.has(k)),
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
// Extract plugins for special handling (concatenation, not merge)
|
|
45
|
+
const themePlugins = safeTheme.plugins || [];
|
|
46
|
+
const userPlugins = safeUser.plugins || [];
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
...safeTheme,
|
|
50
|
+
...safeUser,
|
|
51
|
+
|
|
52
|
+
// Deep merge resolve options
|
|
53
|
+
resolve: {
|
|
54
|
+
...safeTheme.resolve,
|
|
55
|
+
...(safeUser.resolve || {}),
|
|
56
|
+
alias: {
|
|
57
|
+
...(safeTheme.resolve?.alias || {}),
|
|
58
|
+
...(safeUser.resolve?.alias || {}),
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
// Deep merge CSS options
|
|
63
|
+
css: {
|
|
64
|
+
...safeTheme.css,
|
|
65
|
+
...(safeUser.css || {}),
|
|
66
|
+
preprocessorOptions: {
|
|
67
|
+
...(safeTheme.css?.preprocessorOptions || {}),
|
|
68
|
+
...(safeUser.css?.preprocessorOptions || {}),
|
|
69
|
+
scss: {
|
|
70
|
+
...(safeTheme.css?.preprocessorOptions?.scss || {}),
|
|
71
|
+
...(safeUser.css?.preprocessorOptions?.scss || {}),
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
// Deep merge build options
|
|
77
|
+
build: {
|
|
78
|
+
...(safeTheme.build || {}),
|
|
79
|
+
...(safeUser.build || {}),
|
|
80
|
+
rollupOptions: {
|
|
81
|
+
...(safeTheme.build?.rollupOptions || {}),
|
|
82
|
+
...(safeUser.build?.rollupOptions || {}),
|
|
83
|
+
input: {
|
|
84
|
+
...(safeTheme.build?.rollupOptions?.input || {}),
|
|
85
|
+
...(safeUser.build?.rollupOptions?.input || {}),
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
// Deep merge server options
|
|
91
|
+
server: {
|
|
92
|
+
...(safeTheme.server || {}),
|
|
93
|
+
...(safeUser.server || {}),
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
// Concatenate plugins (theme first, then user)
|
|
97
|
+
plugins: [...themePlugins, ...userPlugins],
|
|
98
|
+
};
|
|
99
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin orchestration utility
|
|
3
|
+
* Maps config keys to plugin functions via explicit registry
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { logger } from '@eleventy-plugin-themer/core/logger';
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
purgeCSSFiles,
|
|
10
|
+
generateCriticalCSS,
|
|
11
|
+
minifyHTML,
|
|
12
|
+
validateLinks,
|
|
13
|
+
preserveNonHtmlFiles,
|
|
14
|
+
} from '../plugins/index.mjs';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Explicit mapping from optimization config keys to plugin functions.
|
|
18
|
+
* Add new plugins here when they are created.
|
|
19
|
+
*/
|
|
20
|
+
const PLUGIN_REGISTRY = {
|
|
21
|
+
purgeCSS: purgeCSSFiles,
|
|
22
|
+
criticalCSS: generateCriticalCSS,
|
|
23
|
+
minifyHTML: minifyHTML,
|
|
24
|
+
validateLinks: validateLinks,
|
|
25
|
+
preserveNonHtml: preserveNonHtmlFiles,
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Set of valid optimization keys, exposed so consumers (and `eleventyPluginThemerVite`)
|
|
30
|
+
* can fail-fast on typos in user-supplied `optimizations` rather than silently no-op.
|
|
31
|
+
*/
|
|
32
|
+
export const KNOWN_OPTIMIZATIONS = new Set(Object.keys(PLUGIN_REGISTRY));
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Run optimization plugins based on configuration
|
|
36
|
+
*
|
|
37
|
+
* All plugins follow a uniform signature: (outputDir, options) => Promise<void>
|
|
38
|
+
* The dirs object is merged into options so plugins can access temp, output, etc.
|
|
39
|
+
*
|
|
40
|
+
* @param {Object} optimizations - Optimization configuration (key: true|false|function|object)
|
|
41
|
+
* @param {Object} dirs - Directory configuration
|
|
42
|
+
* @param {string} dirs.output - Output directory (required)
|
|
43
|
+
* @param {string} [dirs.temp] - Temp directory (optional, passed to plugins via options)
|
|
44
|
+
*/
|
|
45
|
+
export async function runOptimizations(optimizations, dirs) {
|
|
46
|
+
for (const [name, config] of Object.entries(optimizations)) {
|
|
47
|
+
// Skip if optimization is disabled
|
|
48
|
+
if (!config) continue;
|
|
49
|
+
|
|
50
|
+
// Custom function provided
|
|
51
|
+
if (typeof config === 'function') {
|
|
52
|
+
await config();
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Built-in plugin
|
|
57
|
+
if (config === true || typeof config === 'object') {
|
|
58
|
+
const pluginFn = PLUGIN_REGISTRY[name];
|
|
59
|
+
|
|
60
|
+
if (!pluginFn) {
|
|
61
|
+
logger.warn(
|
|
62
|
+
`⚠️ No plugin found for optimization: "${name}". Available: ${Object.keys(PLUGIN_REGISTRY).join(', ')}`,
|
|
63
|
+
);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Merge dirs into options so plugins have access to all paths
|
|
68
|
+
const userOptions = typeof config === 'object' ? config : {};
|
|
69
|
+
const options = { ...dirs, ...userOptions };
|
|
70
|
+
|
|
71
|
+
await pluginFn(dirs.output, options);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|