33/**
44 * External dependencies
55 */
6- import { readFile , writeFile } from 'fs/promises' ;
6+ import { readFile , writeFile , copyFile , mkdir } from 'fs/promises' ;
77import path from 'path' ;
88import { fileURLToPath } from 'url' ;
99import { parseArgs } from 'node:util' ;
@@ -113,10 +113,14 @@ function momentTimezoneAliasPlugin() {
113113 * WordPress externals and asset plugin.
114114 * Inspired by wp-build's wordpressExternalsAndAssetPlugin.
115115 *
116- * @param {string } assetName Optional. The name of the asset file to generate (without .asset.php extension). Defaults to 'index.min'.
116+ * @param {string } assetName Optional. The name of the asset file to generate (without .asset.php extension). Defaults to 'index.min'.
117+ * @param {string } buildFormat Optional. The build format: 'iife' for scripts or 'esm' for script modules. Defaults to 'iife'.
117118 * @return {Object } esbuild plugin.
118119 */
119- function wordpressExternalsPlugin ( assetName = 'index.min' ) {
120+ function wordpressExternalsPlugin (
121+ assetName = 'index.min' ,
122+ buildFormat = 'iife'
123+ ) {
120124 return {
121125 name : 'wordpress-externals' ,
122126 setup ( build ) {
@@ -257,11 +261,17 @@ function wordpressExternalsPlugin( assetName = 'index.min' ) {
257261 return undefined ;
258262 }
259263
260- // Check if this is a script module
261- const isScriptModule = isScriptModuleImport (
264+ // Check if this is a script module or a script dependency.
265+ let isScriptModule = isScriptModuleImport (
262266 packageJson ,
263267 subpath
264268 ) ;
269+ let isScript = packageJson . wpScript ;
270+ if ( isScriptModule && isScript ) {
271+ // If the package is both a script and a script module, we should rely on the format being built
272+ isScript = buildFormat === 'iife' ;
273+ isScriptModule = buildFormat === 'esm' ;
274+ }
265275
266276 // Determine import kind: dynamic or static
267277 const kind =
@@ -283,7 +293,7 @@ function wordpressExternalsPlugin( assetName = 'index.min' ) {
283293 }
284294
285295 // If it has wpScript, convert to global variable
286- if ( packageJson . wpScript ) {
296+ if ( isScript ) {
287297 // Track regular script dependency using wp- handle format
288298 dependencies . add ( wpHandle ) ;
289299
@@ -426,7 +436,7 @@ async function bundlePackage( packageName ) {
426436 minify : true ,
427437 plugins : [
428438 momentTimezoneAliasPlugin ( ) ,
429- wordpressExternalsPlugin ( 'index.min' ) ,
439+ wordpressExternalsPlugin ( 'index.min' , 'iife' ) ,
430440 ] ,
431441 } ) ,
432442 esbuild . build ( {
@@ -477,7 +487,7 @@ async function bundlePackage( packageName ) {
477487 platform : 'browser' ,
478488 minify : true ,
479489 plugins : [
480- wordpressExternalsPlugin ( `${ fileName } .min` ) ,
490+ wordpressExternalsPlugin ( `${ fileName } .min` , 'esm' ) ,
481491 ] ,
482492 } )
483493 ) ;
@@ -494,76 +504,109 @@ async function bundlePackage( packageName ) {
494504}
495505
496506/**
497- * Transpile source files for a package (both CJS and ESM) .
507+ * Transpile a single package's source files and copy JSON files .
498508 *
499- * @param {string } packageDir Package directory path.
500- * @param {string[] } srcFiles Array of source file paths.
501- * @param {Object } packageJson Package.json contents.
509+ * @param {string } packageName Package name.
510+ * @return {Promise<number> } Build time in milliseconds.
502511 */
503- async function transpilePackage ( packageDir , srcFiles , packageJson ) {
512+ async function transpilePackage ( packageName ) {
513+ const startTime = Date . now ( ) ;
514+ const packageDir = path . join ( PACKAGES_DIR , packageName ) ;
515+ const packageJsonPath = path . join ( packageDir , 'package.json' ) ;
516+ const packageJson = JSON . parse ( await readFile ( packageJsonPath , 'utf8' ) ) ;
517+
518+ // Find source files to transpile
519+ const srcFiles = await glob (
520+ normalizePath (
521+ path . join ( packageDir , `src/**/*.${ SOURCE_EXTENSIONS } ` )
522+ ) ,
523+ {
524+ ignore : IGNORE_PATTERNS ,
525+ }
526+ ) ;
527+
528+ // Find JSON files to copy
529+ const jsonFiles = await glob (
530+ normalizePath ( path . join ( packageDir , 'src/**/*.json' ) ) ,
531+ {
532+ ignore : IGNORE_PATTERNS ,
533+ }
534+ ) ;
535+
504536 const buildDir = path . join ( packageDir , 'build' ) ;
505537 const buildModuleDir = path . join ( packageDir , 'build-module' ) ;
538+ const srcDir = path . join ( packageDir , 'src' ) ;
506539 const target = browserslistToEsbuild ( ) ;
507540
508541 const builds = [ ] ;
509542
510- // Only build CJS if package has 'main' property
543+ // Build CJS and copy JSON files to build directory
511544 if ( packageJson . main ) {
512545 builds . push (
513546 esbuild . build ( {
514547 entryPoints : srcFiles ,
515548 outdir : buildDir ,
516- outbase : path . join ( packageDir , 'src' ) ,
549+ outbase : srcDir ,
517550 bundle : false ,
518551 platform : 'node' ,
519552 format : 'cjs' ,
520553 sourcemap : true ,
521554 target,
555+ jsx : 'automatic' ,
556+ jsxImportSource : 'react' ,
557+ loader : {
558+ '.js' : 'jsx' ,
559+ } ,
522560 } )
523561 ) ;
562+
563+ // Copy JSON files to build directory
564+ for ( const jsonFile of jsonFiles ) {
565+ const relativePath = path . relative ( srcDir , jsonFile ) ;
566+ const destPath = path . join ( buildDir , relativePath ) ;
567+ const destDir = path . dirname ( destPath ) ;
568+ builds . push (
569+ mkdir ( destDir , { recursive : true } ) . then ( ( ) =>
570+ copyFile ( jsonFile , destPath )
571+ )
572+ ) ;
573+ }
524574 }
525575
526- // Only build ESM if package has ' module' property
576+ // Build ESM and copy JSON files to build- module directory
527577 if ( packageJson . module ) {
528578 builds . push (
529579 esbuild . build ( {
530580 entryPoints : srcFiles ,
531581 outdir : buildModuleDir ,
532- outbase : path . join ( packageDir , 'src' ) ,
582+ outbase : srcDir ,
533583 bundle : false ,
534584 platform : 'neutral' ,
535585 format : 'esm' ,
536586 sourcemap : true ,
537587 target,
588+ jsx : 'automatic' ,
589+ jsxImportSource : 'react' ,
590+ loader : {
591+ '.js' : 'jsx' ,
592+ } ,
538593 } )
539594 ) ;
540- }
541595
542- await Promise . all ( builds ) ;
543- }
544-
545- /**
546- * Transpile a single package's source files.
547- *
548- * @param {string } packageName Package name.
549- * @return {Promise<number> } Build time in milliseconds.
550- */
551- async function transpilePackageFiles ( packageName ) {
552- const startTime = Date . now ( ) ;
553- const packageDir = path . join ( PACKAGES_DIR , packageName ) ;
554- const packageJsonPath = path . join ( packageDir , 'package.json' ) ;
555- const packageJson = JSON . parse ( await readFile ( packageJsonPath , 'utf8' ) ) ;
556-
557- const srcFiles = await glob (
558- normalizePath (
559- path . join ( packageDir , `src/**/*.${ SOURCE_EXTENSIONS } ` )
560- ) ,
561- {
562- ignore : IGNORE_PATTERNS ,
596+ // Copy JSON files to build-module directory
597+ for ( const jsonFile of jsonFiles ) {
598+ const relativePath = path . relative ( srcDir , jsonFile ) ;
599+ const destPath = path . join ( buildModuleDir , relativePath ) ;
600+ const destDir = path . dirname ( destPath ) ;
601+ builds . push (
602+ mkdir ( destDir , { recursive : true } ) . then ( ( ) =>
603+ copyFile ( jsonFile , destPath )
604+ )
605+ ) ;
563606 }
564- ) ;
607+ }
565608
566- await transpilePackage ( packageDir , srcFiles , packageJson ) ;
609+ await Promise . all ( builds ) ;
567610
568611 return Date . now ( ) - startTime ;
569612}
@@ -631,7 +674,7 @@ async function buildAll() {
631674 console . log ( '📝 Phase 1: Transpiling packages...\n' ) ;
632675 await Promise . all (
633676 V2_PACKAGES . map ( async ( packageName ) => {
634- const buildTime = await transpilePackageFiles ( packageName ) ;
677+ const buildTime = await transpilePackage ( packageName ) ;
635678 console . log ( `✔ Transpiled ${ packageName } (${ buildTime } ms)` ) ;
636679 } )
637680 ) ;
@@ -674,7 +717,7 @@ async function watchMode() {
674717 try {
675718 const startTime = Date . now ( ) ;
676719
677- await transpilePackageFiles ( packageName ) ;
720+ await transpilePackage ( packageName ) ;
678721 await bundlePackage ( packageName ) ;
679722
680723 const buildTime = Date . now ( ) - startTime ;
0 commit comments