Skip to content

Commit

Permalink
Scripts: Change webpack configuration to include render files in th…
Browse files Browse the repository at this point in the history
…e build folder (#43917)

* Adapt WebPack to include render files in build

* Ensure getRenderPropPaths returns always an array

* Remove log already handled in entry points

* Update README.md

* Update CHANGELOG.md

* Inform that viewScript is not enqueued when using the render filed

Co-authored-by: Greg Ziółkowski <grzegorz@gziolo.pl>
Co-authored-by: Luis Herranz <luisherranz@gmail.com>
  • Loading branch information
3 people committed Sep 9, 2022
1 parent 10e5234 commit e0fe1a7
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 18 deletions.
2 changes: 1 addition & 1 deletion docs/reference-guides/block-api/block-metadata.md
Expand Up @@ -632,7 +632,7 @@ return array(
Starting in the WordPress 5.8 release, it is possible to instruct WordPress to enqueue scripts and styles for a block type only when rendered on the frontend. It applies to the following asset fields in the `block.json` file:

- `script`
- `viewScript` (when the block defines `render_callback` during registration in PHP, then the block author is responsible for enqueuing the script)
- `viewScript` (when the block defines `render_callback` during registration in PHP or a `render` field in its `block.json`, then the script is registered but the block author is responsible for enqueuing it)
- `style`

## Internationalization
Expand Down
3 changes: 2 additions & 1 deletion packages/scripts/CHANGELOG.md
Expand Up @@ -2,9 +2,10 @@

## Unreleased

### New Feature
### New Features

- Update the default webpack config to allow `webp` image format ([#43880](https://github.com/WordPress/gutenberg/pull/43880)).
- Update webpack configuration for the `build` and `start` commands to automatically copy PHP files listed in the `render` field of `block.json` files from the source to the build folder ([#43917](https://github.com/WordPress/gutenberg/pull/43917)).

## 24.0.0 (2022-08-24)

Expand Down
32 changes: 20 additions & 12 deletions packages/scripts/README.md
Expand Up @@ -62,19 +62,23 @@ We commit to keeping the breaking changes minimal so you can upgrade `@wordpress

### `build`

Transforms your code according the configuration provided so it’s ready for production and optimized for the best performance. The entry points for your project get detected by scanning all script fields in `block.json` files located in the `src` directory. The script fields in `block.json` should pass relative paths to `block.json` in the same folder.
Transforms your code according the configuration provided so it’s ready for production and optimized for the best performance.

_This script exits after producing a single build. For incremental builds, better suited for development, see the [start](#start) script._

The entry points for your project get detected by scanning all script fields in `block.json` files located in the `src` directory. The script fields in `block.json` should pass relative paths to `block.json` in the same folder.

_Example:_

```json
{
"editorScript": "file:index.js",
"editorStyle": "file:editor.css",
"style": "file:style.css"
"script": "file:script.js",
"viewScript": "file:view.js"
}
```

The fallback entry point is `src/index.js` (other supported extensions: `.jsx`, `.ts`, and `.tsx`) in case there is no `block.json` file found. The output generated will be written to `build/index.js`. This script exits after producing a single build. For incremental builds, better suited for development, see the [start](#start) script.
The fallback entry point is `src/index.js` (other supported extensions: `.jsx`, `.ts`, and `.tsx`) in case there is no `block.json` file found. In that scenario, the output generated will be written to `build/index.js`.

_Example:_

Expand All @@ -93,13 +97,13 @@ This is how you execute the script with presented setup:

- `npm run build` - builds the code for production.
- `npm run build:custom` - builds the code for production with two entry points and a custom output directory. Paths for custom entry points are relative to the project root.
- `npm run build:copy-php` - builds the code for production and opts into copying PHP files from the `src` directory and its subfolders to the output directory.
- `npm run build:copy-php` - builds the code for production and opts into copying all PHP files from the `src` directory and its subfolders to the output directory. By default, only PHP files listed in the `render` field in the detected `block.json` files get copied.
- `build:custom-directory` - builds the code for production using the `custom-directory` as the source code directory.

This script automatically use the optimized config but sometimes you may want to specify some custom options:

- `--webpack-bundle-analyzer` – enables visualization for the size of webpack output files with an interactive zoomable treemap.
- `--webpack-copy-php` – enables copying PHP files from the source directory ( default is `src` ) and its subfolders to the output directory.
- `--webpack-copy-php` – enables copying all PHP files from the source directory ( default is `src` ) and its subfolders to the output directory.
- `--webpack-no-externals` – disables scripts' assets generation, and omits the list of default externals.
- `--webpack-src-dir` – Allows customization of the source code directory. Default is `src`.

Expand Down Expand Up @@ -335,19 +339,23 @@ It reuses the same logic as `npm pack` command to create an npm package tarball.

### `start`

Transforms your code according the configuration provided so it’s ready for development. The script will automatically rebuild if you make changes to the code, and you will see the build errors in the console. The entry points for your project get detected by scanning all script fields in `block.json` files located in the `src` directory. The script fields in `block.json` should pass relative paths to `block.json` in the same folder.
Transforms your code according the configuration provided so it’s ready for development. The script will automatically rebuild if you make changes to the code, and you will see the build errors in the console.

_For single builds, better suited for production, see the [build](#build) script._

The entry points for your project get detected by scanning all script fields in `block.json` files located in the `src` directory. The script fields in `block.json` should pass relative paths to `block.json` in the same folder.

_Example:_

```json
{
"editorScript": "file:index.js",
"editorStyle": "file:editor.css",
"style": "file:style.css"
"script": "file:script.js",
"viewScript": "file:view.js"
}
```

The fallback entry point is `src/index.js` (other supported extensions: `.jsx`, `.ts`, and `.tsx`) in case there is no `block.json` file found. The output generated will be written to `build/index.js`. For single builds, better suited for production, see the [build](#build) script.
The fallback entry point is `src/index.js` (other supported extensions: `.jsx`, `.ts`, and `.tsx`) in case there is no `block.json` file found. In that scenario, the output generated will be written to `build/index.js`.

_Example:_

Expand All @@ -368,14 +376,14 @@ This is how you execute the script with presented setup:
- `npm start` - starts the build for development.
- `npm run start:hot` - starts the build for development with "Fast Refresh". The page will automatically reload if you make changes to the files.
- `npm run start:custom` - starts the build for development which contains two entry points and a custom output directory. Paths for custom entry points are relative to the project root.
- `npm run start:copy-php` - starts the build for development and opts into copying PHP files from the `src` directory and its subfolders to the output directory.
- `npm run start:copy-php` - starts the build for development and opts into copying all PHP files from the `src` directory and its subfolders to the output directory. By default, only PHP files listed in the `render` field in the detected `block.json` files get copied.
- `npm run start:custom-directory` - builds the code for production using the `custom-directory` as the source code directory.

This script automatically use the optimized config but sometimes you may want to specify some custom options:

- `--hot` – enables "Fast Refresh". The page will automatically reload if you make changes to the code. _For now, it requires that WordPress has the [`SCRIPT_DEBUG`](https://wordpress.org/support/article/debugging-in-wordpress/#script_debug) flag enabled and the [Gutenberg](https://wordpress.org/plugins/gutenberg/) plugin installed._
- `--webpack-bundle-analyzer` – enables visualization for the size of webpack output files with an interactive zoomable treemap.
- `--webpack-copy-php` – enables copying PHP files from the source directory ( default is `src` ) and its subfolders to the output directory.
- `--webpack-copy-php` – enables copying all PHP files from the source directory ( default is `src` ) and its subfolders to the output directory.
- `--webpack-devtool` – controls how source maps are generated. See options at https://webpack.js.org/configuration/devtool/#devtool.
- `--webpack-no-externals` – disables scripts' assets generation, and omits the list of default externals.
- `--webpack-src-dir` – Allows customization of the source code directory. Default is `src`.
Expand Down
19 changes: 15 additions & 4 deletions packages/scripts/config/webpack.config.js
Expand Up @@ -26,6 +26,7 @@ const {
hasCssnanoConfig,
hasPostCSSConfig,
getWebpackEntryPoints,
getRenderPropPaths,
} = require( '../utils' );

const isProduction = process.env.NODE_ENV === 'production';
Expand All @@ -36,9 +37,8 @@ if ( ! browserslist.findConfig( '.' ) ) {
}
const hasReactFastRefresh = hasArgInCLI( '--hot' ) && ! isProduction;

const copyWebpackPatterns = process.env.WP_COPY_PHP_FILES_TO_DIST
? '**/{block.json,*.php}'
: '**/block.json';
// Get paths of the `render` props included in `block.json` files
const renderPaths = getRenderPropPaths();

const cssLoaders = [
{
Expand Down Expand Up @@ -232,7 +232,7 @@ const config = {
new CopyWebpackPlugin( {
patterns: [
{
from: copyWebpackPatterns,
from: '**/block.json',
context: process.env.WP_SRC_DIRECTORY,
noErrorOnMissing: true,
transform( content, absoluteFrom ) {
Expand Down Expand Up @@ -265,6 +265,17 @@ const config = {
return content;
},
},
{
from: '**/*.php',
context: process.env.WP_SRC_DIRECTORY,
noErrorOnMissing: true,
filter: ( filepath ) => {
return (
process.env.WP_COPY_PHP_FILES_TO_DIST ||
renderPaths.includes( filepath )
);
},
},
],
} ),
// The WP_BUNDLE_ANALYZER global variable enables a utility that represents
Expand Down
56 changes: 56 additions & 0 deletions packages/scripts/utils/config.js
Expand Up @@ -302,10 +302,66 @@ function getWebpackEntryPoints() {
};
}

/**
* Returns the list of paths included in the `render` props by scanning the `block.json` files.
*
* @return {Array} The list of all the `render` prop paths included in `block.json` files.
*/
function getRenderPropPaths() {
// Continue only if the source directory exists.
if ( ! hasProjectFile( process.env.WP_SRC_DIRECTORY ) ) {
return [];
}

// Checks whether any block metadata files can be detected in the defined source directory.
const blockMetadataFiles = glob(
`${ process.env.WP_SRC_DIRECTORY }/**/block.json`,
{
absolute: true,
}
);

const srcDirectory = fromProjectRoot( process.env.WP_SRC_DIRECTORY + sep );

const renderPaths = blockMetadataFiles.map( ( blockMetadataFile ) => {
const { render } = JSON.parse( readFileSync( blockMetadataFile ) );
if ( render && render.startsWith( 'file:' ) ) {
// Removes the `file:` prefix.
const filepath = join(
dirname( blockMetadataFile ),
render.replace( 'file:', '' )
);

// Takes the path without the file extension, and relative to the defined source directory.
if ( ! filepath.startsWith( srcDirectory ) ) {
log(
chalk.yellow(
`Skipping "${ render.replace(
'file:',
''
) }" listed in "${ blockMetadataFile.replace(
fromProjectRoot( sep ),
''
) }". File is located outside of the "${
process.env.WP_SRC_DIRECTORY
}" directory.`
)
);
return false;
}
return filepath;
}
return false;
} );

return renderPaths.filter( ( renderPath ) => renderPath );
}

module.exports = {
getJestOverrideConfigFile,
getWebpackArgs,
getWebpackEntryPoints,
getRenderPropPaths,
hasBabelConfig,
hasCssnanoConfig,
hasJestConfig,
Expand Down
2 changes: 2 additions & 0 deletions packages/scripts/utils/index.js
Expand Up @@ -14,6 +14,7 @@ const {
getJestOverrideConfigFile,
getWebpackArgs,
getWebpackEntryPoints,
getRenderPropPaths,
hasBabelConfig,
hasCssnanoConfig,
hasJestConfig,
Expand All @@ -34,6 +35,7 @@ module.exports = {
getPackageProp,
getWebpackArgs,
getWebpackEntryPoints,
getRenderPropPaths,
hasArgInCLI,
hasBabelConfig,
hasCssnanoConfig,
Expand Down

0 comments on commit e0fe1a7

Please sign in to comment.