Upgrade to version 11.0.1 #1

Merged
steve merged 60 commits from v11.0.1 into main 2025-10-30 22:14:46 +00:00
2 changed files with 148 additions and 44 deletions
Showing only changes of commit 37e3773d88 - Show all commits

View File

@@ -1,61 +1,159 @@
import resolveConfig from 'tailwindcss/resolveConfig' import resolveConfig from 'tailwindcss/resolveConfig'
import { defaultRequestToExternal, defaultRequestToHandle } from '@wordpress/dependency-extraction-webpack-plugin/lib/util' import {
defaultRequestToExternal,
defaultRequestToHandle,
} from '@wordpress/dependency-extraction-webpack-plugin/lib/util'
import fs from 'fs' import fs from 'fs'
import path from 'path' import path from 'path'
/** /**
* WordPress dependency extraction for Vite. * Vite plugin that handles WordPress dependencies and generates a dependency manifest.
* *
* This plugin configures Vite to exclude WordPress packages from your bundle * This plugin:
* and instead load them from the `window.wp` global. It also generates a * 1. Transforms @wordpress/* imports into global wp.* references
* dependency file that is read by Sage's setup.php to enqueue required * 2. Tracks WordPress script dependencies
* WordPress scripts. * 3. Generates an editor.deps.json file listing all WordPress dependencies
* *
* @returns {import('vite').Plugin} * @returns {import('vite').Plugin} Vite plugin
*/ */
export function wordpressPlugin() {
const dependencies = new Set()
const externalMap = new Map() // Helper functions for import handling
function extractNamedImports(imports) {
const match = imports.match(/{([^}]+)}/)
if (!match) return []
return match[1].split(',').map((s) => s.trim())
}
function handleNamedReplacement(namedImports, external) {
return namedImports
.map((imports) => {
const [name, alias = name] = imports
.split(' as ')
.map((script) => script.trim())
return `const ${alias} = ${external.join('.')}.${name};`
})
.join('\n')
}
function handleReplacements(imports, external) {
const importStr = Array.isArray(imports) ? imports[0] : imports
if (importStr.includes('{')) {
const namedImports = extractNamedImports(importStr)
return handleNamedReplacement(namedImports, external)
}
if (importStr.includes('* as')) {
const match = importStr.match(/\*\s+as\s+(\w+)/)
if (!match) return ''
const alias = match[1]
return `const ${alias} = ${external.join('.')};`
}
const name = importStr.trim()
return `const ${name} = ${external.join('.')};`
}
export function extractWordPressDependencies() {
return { return {
name: 'wordpress-dependencies', name: 'wordpress-plugin',
config() { enforce: 'pre',
config(config) {
return { return {
build: { ...config,
rollupOptions: { resolve: {
external(id) { ...config.resolve,
const result = defaultRequestToExternal(id) alias: {
if (result) { ...config.resolve?.alias,
externalMap.set(id, result) }
return true },
} }
return false },
}, resolveId(id) {
output: { if (id.startsWith('@wordpress/')) {
globals(id) { const pkg = id.replace('@wordpress/', '')
const global = externalMap.get(id) const external = defaultRequestToExternal(id)
return Array.isArray(global) ? global.join('.') : global const handle = defaultRequestToHandle(id)
}
} if (external && handle) {
dependencies.add(handle)
return {
id,
external: true,
} }
} }
} }
}, },
generateBundle(options, bundle) { transform(code, id) {
const deps = Object.values(bundle) if (!id.endsWith('.js')) return
.filter(chunk => chunk.type === 'chunk' && chunk.isEntry)
.flatMap(chunk => chunk.imports)
.map(defaultRequestToHandle)
.filter(Boolean)
if (deps.length) { const imports = [
this.emitFile({ ...(code.match(/^import .+ from ['"]@wordpress\/[^'"]+['"]/gm) || []),
type: 'asset', ...(code.match(/^import ['"]@wordpress\/[^'"]+['"]/gm) || []),
fileName: 'editor.deps.json', ]
source: JSON.stringify(deps, null, 2)
}) imports.forEach((statement) => {
const match =
statement.match(/^import (.+) from ['"]@wordpress\/([^'"]+)['"]/) ||
statement.match(/^import ['"]@wordpress\/([^'"]+)['"]/)
if (!match) return
const [, imports, pkg] = match
if (!pkg) return
const external = defaultRequestToExternal(`@wordpress/${pkg}`)
const handle = defaultRequestToHandle(`@wordpress/${pkg}`)
if (external && handle) {
dependencies.add(handle)
const replacement = imports
? handleReplacements(imports, external)
: `const ${pkg.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase())} = ${external.join('.')};`
code = code.replace(statement, replacement)
}
})
return { code, map: null }
},
generateBundle() {
this.emitFile({
type: 'asset',
fileName: 'editor.deps.json',
source: JSON.stringify([...dependencies]),
})
},
}
}
/**
* Rollup plugin that configures external WordPress dependencies.
*
* This plugin:
* 1. Marks all @wordpress/* packages as external dependencies
* 2. Maps external @wordpress/* imports to wp.* global variables
*
* This prevents WordPress core libraries from being bundled and ensures
* they are loaded from WordPress's global scope instead.
*
* @returns {import('rollup').Plugin} Rollup plugin
*/
export function wordpressRollupPlugin() {
return {
name: 'wordpress-rollup-plugin',
options(opts) {
opts.external = (id) => id.startsWith('@wordpress/')
opts.output = opts.output || {}
opts.output.globals = (id) => {
if (id.startsWith('@wordpress/')) {
const packageName = id.replace('@wordpress/', '')
return `wp.${packageName.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase())}`
}
} }
} return opts
},
} }
} }
@@ -74,7 +172,7 @@ export function extractWordPressDependencies() {
* @param {boolean} [options.disableTailwindFontSizes=false] - Disable including Tailwind font sizes in theme.json * @param {boolean} [options.disableTailwindFontSizes=false] - Disable including Tailwind font sizes in theme.json
* @returns {import('vite').Plugin} Vite plugin * @returns {import('vite').Plugin} Vite plugin
*/ */
export function processThemeJson({ export function wordpressThemeJson({
tailwindConfig, tailwindConfig,
disableTailwindColors = false, disableTailwindColors = false,
disableTailwindFonts = false, disableTailwindFonts = false,

View File

@@ -1,6 +1,10 @@
import { defineConfig } from 'vite' import { defineConfig } from 'vite'
import laravel from 'laravel-vite-plugin' import laravel from 'laravel-vite-plugin'
import { extractWordPressDependencies, processThemeJson } from './resources/js/build/wordpress' import {
wordpressPlugin,
wordpressRollupPlugin,
wordpressThemeJson,
} from './resources/js/build/wordpress'
import tailwindConfig from './tailwind.config.js' import tailwindConfig from './tailwind.config.js'
export default defineConfig({ export default defineConfig({
@@ -15,11 +19,13 @@ export default defineConfig({
], ],
refresh: true, refresh: true,
}), }),
extractWordPressDependencies(),
wordpressPlugin(),
wordpressRollupPlugin(),
// Generate the theme.json file in the public/build/assets directory // Generate the theme.json file in the public/build/assets directory
// based on the Tailwind config and the theme.json file from base theme folder // based on the Tailwind config and the theme.json file from base theme folder
processThemeJson({ wordpressThemeJson({
tailwindConfig, tailwindConfig,
disableTailwindColors: false, disableTailwindColors: false,
disableTailwindFonts: false, disableTailwindFonts: false,