🩹 Dev server: fix WP dependency handling (#3207)
* Revert "🎨 Simplify WordPress dependency handling" (#3202) * 🩹 Fix dev server error
This commit is contained in:
@@ -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) {
|
||||||
export function extractWordPressDependencies() {
|
const match = imports.match(/{([^}]+)}/)
|
||||||
return {
|
if (!match) return []
|
||||||
name: 'wordpress-dependencies',
|
return match[1].split(',').map((s) => s.trim())
|
||||||
config() {
|
}
|
||||||
return {
|
|
||||||
build: {
|
function handleNamedReplacement(namedImports, external) {
|
||||||
rollupOptions: {
|
return namedImports
|
||||||
external(id) {
|
.map((imports) => {
|
||||||
const result = defaultRequestToExternal(id)
|
const [name, alias = name] = imports
|
||||||
if (result) {
|
.split(' as ')
|
||||||
externalMap.set(id, result)
|
.map((script) => script.trim())
|
||||||
return true
|
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('.')};`
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: 'wordpress-plugin',
|
||||||
|
enforce: 'pre',
|
||||||
|
config(config) {
|
||||||
|
return {
|
||||||
|
...config,
|
||||||
|
resolve: {
|
||||||
|
...config.resolve,
|
||||||
|
alias: {
|
||||||
|
...config.resolve?.alias,
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
},
|
},
|
||||||
output: {
|
|
||||||
globals(id) {
|
|
||||||
const global = externalMap.get(id)
|
|
||||||
return Array.isArray(global) ? global.join('.') : global
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
resolveId(id) {
|
||||||
|
if (id.startsWith('@wordpress/')) {
|
||||||
|
const pkg = id.replace('@wordpress/', '')
|
||||||
|
const external = defaultRequestToExternal(id)
|
||||||
|
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 = [
|
||||||
|
...(code.match(/^import .+ from ['"]@wordpress\/[^'"]+['"]/gm) || []),
|
||||||
|
...(code.match(/^import ['"]@wordpress\/[^'"]+['"]/gm) || []),
|
||||||
|
]
|
||||||
|
|
||||||
|
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({
|
this.emitFile({
|
||||||
type: 'asset',
|
type: 'asset',
|
||||||
fileName: 'editor.deps.json',
|
fileName: 'editor.deps.json',
|
||||||
source: JSON.stringify(deps, null, 2)
|
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,
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user