Skip to content

Commit 3217d7d

Browse files
aduthyouknowriadjsnajdrmanzoorwanijk
authored
Build Tooling: Add browserslist config for build targeting (#82179)
* Build Tooling: Add browserslist config for build targeting * Integrate browserlist defaulting into build package Co-authored-by: aduth <aduth@git.wordpress.org> Co-authored-by: youknowriad <youknowriad@git.wordpress.org> Co-authored-by: jsnajdr <jsnajdr@git.wordpress.org> Co-authored-by: manzoorwanijk <manzoorwanijk@git.wordpress.org>
1 parent 4327f17 commit 3217d7d

7 files changed

Lines changed: 79 additions & 12 deletions

File tree

‎package-lock.json‎

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎packages/wp-build/CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
### Enhancements
66

7+
- Target `@wordpress/browserslist-config` for JavaScript and CSS when the project has no Browserslist config, instead of Browserslist's implicit defaults ([#82179](https://github.com/WordPress/gutenberg/pull/82179)).
78
- Transpile `.jsx` package, route, and widget source files alongside the existing JavaScript and TypeScript extensions, and ignore JSX tests during watch rebuilds ([#80990](https://github.com/WordPress/gutenberg/pull/80990)).
89

910
### Bug Fixes

‎packages/wp-build/README.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ Generated CSS module output skips automatic style injection when `NODE_ENV` is
5959
modern CSS features, so tests that need actual styles in the DOM should
6060
run in a browser environment.
6161

62+
## Browser support
63+
64+
JavaScript and CSS builds use [Browserslist](https://github.com/browserslist/browserslist)
65+
when specifying build targets. You can either [provide your own](https://github.com/browserslist/browserslist#config-file),
66+
or the default [`@wordpress/browserslist-config`](https://www.npmjs.com/package/@wordpress/browserslist-config)
67+
will be used to follow [WordPress browser support](https://make.wordpress.org/core/handbook/best-practices/browser-support/).
68+
6269
## Package Configuration
6370

6471
Configure your `package.json` with the following optional fields:
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import browserslist from 'browserslist';
2+
import wordpressBrowserslistConfig from '@wordpress/browserslist-config';
3+
4+
/**
5+
* Resolve the Browserslist queries for a project.
6+
*
7+
* Uses the project's own config if one is present, otherwise falling back to
8+
* `@wordpress/browserslist-config` instead of Browserslist's implicit defaults.
9+
*
10+
* @return {string[]} Browserslist queries.
11+
*/
12+
export function getBrowserslistQueries() {
13+
const config = browserslist.findConfig( process.cwd() );
14+
return config?.defaults || wordpressBrowserslistConfig;
15+
}

‎packages/wp-build/lib/build.mjs‎

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {
2828
renderTemplateToString,
2929
} from './php-generator.mjs';
3030
import { getPackageInfo, getPackageInfoFromFile } from './package-utils.mjs';
31+
import { getBrowserslistQueries } from './browserslist.mjs';
3132
import { getSourceFileGlob, isTestSourceFile } from './source-files.mjs';
3233
import { createWordpressExternalsPlugin } from './wordpress-externals-plugin.mjs';
3334
import {
@@ -47,6 +48,14 @@ import {
4748
generateWorkerCode,
4849
} from './worker-build.mjs';
4950

51+
/**
52+
* Resolve the ESBuild target from the project's Browserslist config.
53+
*
54+
* @return {string[]} ESBuild target strings.
55+
*/
56+
function getEsbuildTarget() {
57+
return browserslistToEsbuild( getBrowserslistQueries() );
58+
}
5059
// Optional dependency: @wordpress/theme provides plugins that inject fallback
5160
// values for design system tokens. Fails gracefully when the package is not
5261
// installed (it is an optional peerDependency).
@@ -587,7 +596,7 @@ async function bundlePackage( packageName, options = {} ) {
587596
if ( packageJson.wpScript ) {
588597
const entryPoint = resolveEntryPoint( packageDir, packageJson );
589598
const outputDir = path.join( BUILD_DIR, 'scripts', packageName );
590-
const target = browserslistToEsbuild();
599+
const target = getEsbuildTarget();
591600

592601
// Check if package matches the namespace and should expose a global
593602
const packageFullName = packageJson.name;
@@ -684,7 +693,7 @@ async function bundlePackage( packageName, options = {} ) {
684693
}
685694

686695
if ( packageJson.wpScriptModuleExports ) {
687-
const target = browserslistToEsbuild();
696+
const target = getEsbuildTarget();
688697
const rootBuildModuleDir = path.join(
689698
BUILD_DIR,
690699
'modules',
@@ -1368,7 +1377,7 @@ async function transpilePackage( packageName ) {
13681377
const buildDir = path.join( packageDir, 'build' );
13691378
const buildModuleDir = path.join( packageDir, 'build-module' );
13701379
const srcDir = path.join( packageDir, 'src' );
1371-
const target = browserslistToEsbuild();
1380+
const target = getEsbuildTarget();
13721381

13731382
const builds = [];
13741383

@@ -1623,7 +1632,11 @@ async function compileStyles( packageName ) {
16231632
const ltrResult = await postcss(
16241633
[
16251634
dsTokenFallbacks,
1626-
autoprefixer( { grid: true } ),
1635+
autoprefixer( {
1636+
grid: true,
1637+
overrideBrowserslist:
1638+
getBrowserslistQueries(),
1639+
} ),
16271640
].filter( Boolean )
16281641
).process( source, { from: undefined } );
16291642

@@ -1744,7 +1757,7 @@ async function buildRoute( routeName ) {
17441757
outfile: path.join( outputDir, 'route.min.js' ),
17451758
bundle: true,
17461759
format: 'esm',
1747-
target: browserslistToEsbuild(),
1760+
target: getEsbuildTarget(),
17481761
minify: true,
17491762
define: getDefine( false ),
17501763
plugins: [
@@ -1762,7 +1775,7 @@ async function buildRoute( routeName ) {
17621775
outfile: path.join( outputDir, 'route.js' ),
17631776
bundle: true,
17641777
format: 'esm',
1765-
target: browserslistToEsbuild(),
1778+
target: getEsbuildTarget(),
17661779
minify: false,
17671780
define: getDefine( true ),
17681781
plugins: [
@@ -1795,7 +1808,7 @@ async function buildRoute( routeName ) {
17951808
outfile: path.join( outputDir, 'content.min.js' ),
17961809
bundle: true,
17971810
format: 'esm',
1798-
target: browserslistToEsbuild(),
1811+
target: getEsbuildTarget(),
17991812
minify: true,
18001813
define: getDefine( false ),
18011814
plugins: [
@@ -1813,7 +1826,7 @@ async function buildRoute( routeName ) {
18131826
outfile: path.join( outputDir, 'content.js' ),
18141827
bundle: true,
18151828
format: 'esm',
1816-
target: browserslistToEsbuild(),
1829+
target: getEsbuildTarget(),
18171830
minify: false,
18181831
define: getDefine( true ),
18191832
plugins: [
@@ -1907,7 +1920,7 @@ async function buildWidget( widgetName ) {
19071920
outfile: path.join( outputDir, 'render.min.js' ),
19081921
bundle: true,
19091922
format: 'esm',
1910-
target: browserslistToEsbuild(),
1923+
target: getEsbuildTarget(),
19111924
minify: true,
19121925
define: getDefine( false ),
19131926
plugins: [
@@ -1925,7 +1938,7 @@ async function buildWidget( widgetName ) {
19251938
outfile: path.join( outputDir, 'render.js' ),
19261939
bundle: true,
19271940
format: 'esm',
1928-
target: browserslistToEsbuild(),
1941+
target: getEsbuildTarget(),
19291942
minify: false,
19301943
define: getDefine( true ),
19311944
plugins: [
@@ -1957,7 +1970,7 @@ async function buildWidget( widgetName ) {
19571970
outfile: path.join( outputDir, 'widget.min.js' ),
19581971
bundle: true,
19591972
format: 'esm',
1960-
target: browserslistToEsbuild(),
1973+
target: getEsbuildTarget(),
19611974
minify: true,
19621975
define: getDefine( false ),
19631976
plugins: [
@@ -1975,7 +1988,7 @@ async function buildWidget( widgetName ) {
19751988
outfile: path.join( outputDir, 'widget.js' ),
19761989
bundle: true,
19771990
format: 'esm',
1978-
target: browserslistToEsbuild(),
1991+
target: getEsbuildTarget(),
19791992
minify: false,
19801993
define: getDefine( true ),
19811994
plugins: [
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import browserslist from 'browserslist';
2+
import wordpressBrowserslistConfig from '@wordpress/browserslist-config';
3+
import { getBrowserslistQueries } from '../browserslist.mjs';
4+
5+
describe( 'browserslist targeting', () => {
6+
afterEach( () => {
7+
jest.restoreAllMocks();
8+
} );
9+
10+
it( 'falls back to @wordpress/browserslist-config when the project has no config', () => {
11+
jest.spyOn( browserslist, 'findConfig' ).mockReturnValue( undefined );
12+
13+
expect( getBrowserslistQueries() ).toEqual(
14+
wordpressBrowserslistConfig
15+
);
16+
} );
17+
18+
it( 'uses the project browserslist config when one is present', () => {
19+
jest.spyOn( browserslist, 'findConfig' ).mockReturnValue( {
20+
defaults: [ 'last 1 chrome version' ],
21+
} );
22+
23+
expect( getBrowserslistQueries() ).toEqual( [
24+
'last 1 chrome version',
25+
] );
26+
} );
27+
} );

‎packages/wp-build/package.json‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@
3636
},
3737
"dependencies": {
3838
"@emotion/babel-plugin": "^11.13.5",
39+
"@wordpress/browserslist-config": "file:../browserslist-config",
3940
"@wordpress/style-runtime": "file:../style-runtime",
4041
"autoprefixer": "^10.4.21",
42+
"browserslist": "^4.28.4",
4143
"browserslist-to-esbuild": "^2.1.1",
4244
"change-case": "^4.1.2",
4345
"chokidar": "^4.0.0",

0 commit comments

Comments
 (0)