155 lines
5.0 KiB
JavaScript
155 lines
5.0 KiB
JavaScript
import resolveConfig from 'tailwindcss/resolveConfig'
|
|
import { defaultRequestToExternal, defaultRequestToHandle } from '@wordpress/dependency-extraction-webpack-plugin/lib/util'
|
|
import fs from 'fs'
|
|
import path from 'path'
|
|
|
|
/**
|
|
* WordPress dependency extraction for Vite.
|
|
*
|
|
* This plugin configures Vite to exclude WordPress packages from your bundle
|
|
* and instead load them from the `window.wp` global. It also generates a
|
|
* dependency file that is read by Sage's setup.php to enqueue required
|
|
* WordPress scripts.
|
|
*
|
|
* @returns {import('vite').Plugin}
|
|
*/
|
|
|
|
const externalMap = new Map()
|
|
|
|
export function extractWordPressDependencies() {
|
|
return {
|
|
name: 'wordpress-dependencies',
|
|
config() {
|
|
return {
|
|
build: {
|
|
rollupOptions: {
|
|
external(id) {
|
|
const result = defaultRequestToExternal(id)
|
|
if (result) {
|
|
externalMap.set(id, result)
|
|
return true
|
|
}
|
|
return false
|
|
},
|
|
output: {
|
|
globals(id) {
|
|
const global = externalMap.get(id)
|
|
return Array.isArray(global) ? global.join('.') : global
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
generateBundle(options, bundle) {
|
|
const deps = Object.values(bundle)
|
|
.filter(chunk => chunk.type === 'chunk' && chunk.isEntry)
|
|
.flatMap(chunk => chunk.imports)
|
|
.map(defaultRequestToHandle)
|
|
.filter(Boolean)
|
|
|
|
if (deps.length) {
|
|
this.emitFile({
|
|
type: 'asset',
|
|
fileName: 'editor.deps.json',
|
|
source: JSON.stringify(deps, null, 2)
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generates a WordPress theme.json file by combining:
|
|
* - Base theme.json settings
|
|
* - Tailwind configuration (colors, fonts, font sizes)
|
|
*
|
|
* The generated theme.json is emitted to public/build/assets/theme.json
|
|
* and provides WordPress with theme settings that match your Tailwind configuration.
|
|
*
|
|
* @param {Object} options Plugin options
|
|
* @param {Object} options.tailwindConfig - The resolved Tailwind configuration object
|
|
* @param {boolean} [options.disableTailwindColors=false] - Disable including Tailwind colors in theme.json
|
|
* @param {boolean} [options.disableTailwindFonts=false] - Disable including Tailwind fonts in theme.json
|
|
* @param {boolean} [options.disableTailwindFontSizes=false] - Disable including Tailwind font sizes in theme.json
|
|
* @returns {import('vite').Plugin} Vite plugin
|
|
*/
|
|
export function processThemeJson({
|
|
tailwindConfig,
|
|
disableTailwindColors = false,
|
|
disableTailwindFonts = false,
|
|
disableTailwindFontSizes = false,
|
|
}) {
|
|
function flattenColors(colors, prefix = '') {
|
|
return Object.entries(colors).reduce((acc, [name, value]) => {
|
|
const formattedName = name.charAt(0).toUpperCase() + name.slice(1)
|
|
|
|
if (typeof value === 'string') {
|
|
acc.push({
|
|
name: prefix ? `${prefix.charAt(0).toUpperCase() + prefix.slice(1)}-${formattedName}` : formattedName,
|
|
slug: prefix ? `${prefix}-${name}`.toLowerCase() : name.toLowerCase(),
|
|
color: value,
|
|
})
|
|
} else if (typeof value === 'object') {
|
|
acc.push(...flattenColors(value, name))
|
|
}
|
|
return acc
|
|
}, [])
|
|
}
|
|
|
|
const resolvedConfig = resolveConfig(tailwindConfig)
|
|
|
|
return {
|
|
name: 'wordpress-theme-json',
|
|
async generateBundle() {
|
|
const baseThemeJson = JSON.parse(
|
|
fs.readFileSync(path.resolve('./theme.json'), 'utf8')
|
|
)
|
|
|
|
const themeJson = {
|
|
__processed__: "This file was generated from the Vite build",
|
|
...baseThemeJson,
|
|
settings: {
|
|
...baseThemeJson.settings,
|
|
...((!disableTailwindColors && resolvedConfig.theme?.colors && {
|
|
color: {
|
|
...baseThemeJson.settings?.color,
|
|
palette: flattenColors(resolvedConfig.theme.colors),
|
|
},
|
|
}) || {}),
|
|
...((!disableTailwindFonts && resolvedConfig.theme?.fontFamily && {
|
|
typography: {
|
|
...baseThemeJson.settings?.typography,
|
|
fontFamilies: Object.entries(resolvedConfig.theme.fontFamily)
|
|
.map(([name, value]) => ({
|
|
name,
|
|
slug: name,
|
|
fontFamily: Array.isArray(value) ? value.join(',') : value,
|
|
})),
|
|
},
|
|
}) || {}),
|
|
...((!disableTailwindFontSizes && resolvedConfig.theme?.fontSize && {
|
|
typography: {
|
|
...baseThemeJson.settings?.typography,
|
|
fontSizes: Object.entries(resolvedConfig.theme.fontSize)
|
|
.map(([name, value]) => ({
|
|
name,
|
|
slug: name,
|
|
size: Array.isArray(value) ? value[0] : value,
|
|
})),
|
|
},
|
|
}) || {}),
|
|
},
|
|
}
|
|
|
|
delete themeJson.__preprocessed__
|
|
|
|
this.emitFile({
|
|
type: 'asset',
|
|
fileName: 'assets/theme.json',
|
|
source: JSON.stringify(themeJson, null, 2)
|
|
})
|
|
},
|
|
}
|
|
}
|