Skip to content

Commit 2f5df8f

Browse files
committed
Build V2: Support JSX and JSON
1 parent 4a4522e commit 2f5df8f

File tree

19 files changed

+897
-184
lines changed

19 files changed

+897
-184
lines changed

bin/packages/build-v2.mjs

Lines changed: 86 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
/**
44
* External dependencies
55
*/
6-
import { readFile, writeFile } from 'fs/promises';
6+
import { readFile, writeFile, copyFile, mkdir } from 'fs/promises';
77
import path from 'path';
88
import { fileURLToPath } from 'url';
99
import { 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;

bin/packages/v2-packages.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,15 @@
77
*/
88
const V2_PACKAGES = [
99
'a11y',
10+
'annotations',
1011
'api-fetch',
1112
'autop',
1213
'blob',
1314
'block-serialization-default-parser',
15+
'blocks',
16+
'compose',
17+
'data',
18+
'data-controls',
1419
'date',
1520
'deprecated',
1621
'dom',
@@ -25,18 +30,25 @@ const V2_PACKAGES = [
2530
'is-shallow-equal',
2631
'jest-console',
2732
'jest-puppeteer-axe',
33+
'keyboard-shortcuts',
2834
'keycodes',
35+
'media-utils',
36+
'notices',
2937
'preferences-persistence',
3038
'priority-queue',
3139
'private-apis',
40+
'react-i18n',
3241
'redux-routine',
3342
'report-flaky-tests',
43+
'rich-text',
44+
'router',
3445
'shortcode',
3546
'style-engine',
3647
'sync',
3748
'token-list',
3849
'undo-manager',
3950
'url',
51+
'viewport',
4052
'warning',
4153
'wordcount',
4254
];

0 commit comments

Comments
 (0)