Skip to content

Commit

Permalink
Scripts: Recommend passing JS entry points with paths
Browse files Browse the repository at this point in the history
  • Loading branch information
gziolo committed Dec 23, 2024
1 parent 5a59c03 commit fb7579b
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 144 deletions.
135 changes: 73 additions & 62 deletions packages/scripts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,6 @@ _Example:_

It might also be a good idea to get familiar with the [JavaScript Build Setup tutorial](https://github.com/WordPress/gutenberg/tree/HEAD/docs/how-to-guides/javascript/js-build-setup.md) for setting up a development environment to use ESNext syntax. It gives a very in-depth explanation of how to use the [build](#build) and [start](#start) scripts.

## Automatic block.json detection and the source code directory

When using the `start` or `build` commands, the source code directory ( the default is `./src`) and its subdirectories are scanned for the existence of `block.json` files. If one or more are found, they are treated a entry points and will be output into corresponding folders in the `build` directory. This allows for the creation of multiple blocks that use a single build process. The source directory can be customized using the `--webpack-src-dir` flag and the output directory with the `--output-path` flag.

## Updating to New Release

To update an existing project to a new version of `@wordpress/scripts`, open the [changelog](https://github.com/WordPress/gutenberg/blob/HEAD/packages/scripts/CHANGELOG.md), find the version you’re currently on (check `package.json` in the top-level directory of your project), and apply the migration instructions for the newer versions.
Expand All @@ -66,19 +62,7 @@ Transforms your code according the configuration provided so it’s ready for pr

_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",
"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. In that scenario, the output generated will be written to `build/index.js`.
#### How to use `build` script?

_Example:_

Expand All @@ -88,7 +72,7 @@ _Example:_
"build": "wp-scripts build",
"build:custom": "wp-scripts build entry-one.js entry-two.js --output-path=custom",
"build:copy-php": "wp-scripts build --webpack-copy-php",
"build:custom-directory": "wp-scripts build --webpack-src-dir=custom-directory"
"build:custom-directory": "wp-scripts build --source-path=custom-directory"
}
}
```
Expand All @@ -105,19 +89,20 @@ This script automatically use the optimized config but sometimes you may want to
- `--webpack-bundle-analyzer` – enables visualization for the size of webpack output files with an interactive zoomable treemap.
- `--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`.
- `--source-path` – Allows customization of the source directory. Default is `.`. In the automatic detection mode the default changes to `src`.
- `--output-path` – Allows customization of the output directory. Default is `build`.

Experimental support for the block.json `viewScriptModule` field is available via the
`--experimental-modules` option. With this option enabled, script and module fields will all be
compiled. The `viewScriptModule` field is analogous to the `viewScript` field, but will compile a module
and should be registered in WordPress using the Modules API.

Learn more about [using build scripts](#using-build-scripts) to optimize the development experience based on your specific needs.

#### Advanced information

This script uses [webpack](https://webpack.js.org/) behind the scenes. It’ll look for a webpack config in the top-level directory of your package and will use it if it finds one. If none is found, it’ll use the default config provided by `@wordpress/scripts` packages. Learn more in the [Advanced Usage](#advanced-usage) section.


### `build-blocks-manifest`

This script generates a PHP file containing block metadata from all
Expand All @@ -128,10 +113,12 @@ when registering multiple block types, as it allows you to use
Usage: `wp-scripts build-blocks-manifest [options]`

Options:
- `--input`: Specify the input directory (default: 'build')
- `--output`: Specify the output file path (default: 'build/blocks-manifest.php')

- `--input`: Specify the input directory (default: 'build')
- `--output`: Specify the output file path (default: 'build/blocks-manifest.php')

Example:

```bash
wp-scripts build-blocks-manifest --input=src --output=dist/blocks-manifest.php
```
Expand Down Expand Up @@ -392,19 +379,7 @@ Transforms your code according the configuration provided so it’s ready for de

_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",
"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. In that scenario, the output generated will be written to `build/index.js`.
#### How to use `start` script?

_Example:_

Expand All @@ -415,7 +390,7 @@ _Example:_
"start:hot": "wp-scripts start --hot",
"start:custom": "wp-scripts start entry-one.js entry-two.js --output-path=custom",
"start:copy-php": "wp-scripts start --webpack-copy-php",
"start:custom-directory": "wp-scripts start --webpack-src-dir=custom-directory"
"start:custom-directory": "wp-scripts start --source-path=custom-directory"
}
}
```
Expand All @@ -436,14 +411,16 @@ This script automatically use the optimized config but sometimes you may want to
- `--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`.
- `--source-path` – Allows customization of the source directory. Default is `.`. In the automatic detection mode the default changes to `src`.
- `--output-path` – Allows customization of the output directory. Default is `build`.

Experimental support for the block.json `viewScriptModule` field is available via the
`--experimental-modules` option. With this option enabled, script and module fields will all be
compiled. The `viewScriptModule` field is analogous to the `viewScript` field, but will compile a module
and should be registered in WordPress using the Modules API.

Learn more about [using build scripts](#using-build-scripts) to optimize the development experience based on your specific needs.

#### Advanced information

This script uses [webpack](https://webpack.js.org/) behind the scenes. It’ll look for a webpack config in the top-level directory of your package and will use it if it finds one. If none is found, it’ll use the default config provided by `@wordpress/scripts` packages. Learn more in the [Advanced Usage](#advanced-usage) section.
Expand Down Expand Up @@ -639,30 +616,45 @@ To also debug the browser context, run `wp-scripts --inspect-brk test-e2e --pupp

For more e2e debugging tips check out the [Puppeteer debugging docs](https://developers.google.com/web/tools/puppeteer/debugging).

## Advanced Usage
## Using build scripts

In general, this package should be used with the set of recommended config files. While it’s possible to override every single config file provided, if you have to do it, it means that your use case is far more complicated than anticipated. If that happens, it would be better to avoid using the whole abstraction layer and set up your project with full control over tooling used.
The `build` and `start` commands use [webpack](https://webpack.js.org/) behind the scenes. webpack is a tool that helps you transform your code into something else. For example: it can take code written in ESNext and output ES5 compatible code that is minified for production.

### Working with build scripts
### Listing entry points

The `build` and `start` commands use [webpack](https://webpack.js.org/) behind the scenes. webpack is a tool that helps you transform your code into something else. For example: it can take code written in ESNext and output ES5 compatible code that is minified for production.
The simplest way to list JavaScript entry points is to pass them as arguments for the command:

#### Default webpack config
```bash
wp-scripts build entry-one.js entry-two.js
```

`@wordpress/scripts` bundles the default webpack config used as a base by the WordPress editor. These are the defaults:
### Automatic block.json detection and the source code directory

- [Entry](https://webpack.js.org/configuration/entry-context/#entry): the entry points for your project get detected by scanning all script fields in `block.json` files located in the `src` directory. The fallback entry point is `src/index.js` (other supported extensions: `.jsx`, `.ts`, and `.tsx`) in case there is no `block.json` file found.
- [Output](https://webpack.js.org/configuration/output): `build/[name].js`, for example: `build/index.js`, or `build/my-block/index.js`.
- [Loaders](https://webpack.js.org/loaders/):
- [`babel-loader`](https://webpack.js.org/loaders/babel-loader/) allows transpiling JavaScript and TypeScript files using Babel and webpack.
- [`@svgr/webpack`](https://www.npmjs.com/package/@svgr/webpack) and [`url-loader`](https://webpack.js.org/loaders/url-loader/) makes it possible to handle SVG files in JavaScript code.
- [`css-loader`](https://webpack.js.org/loaders/css-loader/) chained with [`postcss-loader`](https://webpack.js.org/loaders/postcss-loader/) and [sass-loader](https://webpack.js.org/loaders/sass-loader/) let webpack process CSS, SASS or SCSS files referenced in JavaScript files.
- [Plugins](https://webpack.js.org/configuration/plugins) (among others):
- [`CopyWebpackPlugin`](https://webpack.js.org/plugins/copy-webpack-plugin/) copies all `block.json` files discovered in the `src` directory to the build directory.
- [`MiniCssExtractPlugin`](https://webpack.js.org/plugins/mini-css-extract-plugin/) extracts CSS into separate files. It creates a CSS file per JavaScript entry point which contains CSS.
- [`@wordpress/dependency-extraction-webpack-plugin`](https://github.com/WordPress/gutenberg/tree/HEAD/packages/dependency-extraction-webpack-plugin/README.md) is used with the default configuration to ensure that WordPress provided scripts are not included in the built bundle.
A convenient alternative for blocks is using automatic entry points detection. In that case, the source code directory (the default is `./src`) and its subdirectories are scanned for the existence of `block.json` files. If one or more are found, the JavaScript files listed in metadata are treated as entry points and will be output into corresponding folders in the `build` directory. The script fields in `block.json` should pass relative paths to `block.json` in the same folder.

_Example:_

```json
{
"editorScript": "file:index.js",
"script": "file:script.js",
"viewScript": "file:view.js"
}
```

This allows for the creation of multiple blocks that use a single build process triggered with a simple command:

```bash
wp-scripts build
```

The source directory can be customized using the `--source-path` flag and the output directory with the `--output-path` flag.

#### Using CSS
### Fallback entry point

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`.

### Using CSS

_Example:_

Expand Down Expand Up @@ -694,19 +686,19 @@ When you run the build using the default command `wp-scripts build` (also applie
1. `index.css` – all imported CSS files are bundled into one chunk named after the entry point, which defaults to `index.js`, and thus the file created becomes `index.css`. This is for styles used only in the editor.
2. `style-index.css` – imported `style.css` file(s) (applies to PCSS, SASS and SCSS extensions) get bundled into one `style-index.css` file that is meant to be used both on the front-end and in the editor.

You can also have multiple entry points as described in the docs for the script:
For example, if the project has two entry points:

```bash
wp-scripts start entry-one.js entry-two.js --output-path=custom
wp-scripts build entry-one.js entry-two.js
```

If you do so, then CSS files generated will follow the names of the entry points: `entry-one.css` and `entry-two.css`.
In that case, the CSS generated based on import statements in the JavaScript code will follow the names of the entry points: `entry-one.css` and `entry-two.css`.

Avoid using `style` keyword in an entry point name, this might break your build process.
_Important:_ Avoid using `style` keyword in an entry point name, this might break your build process.

You can also bundle CSS modules by prefixing `.module` to the extension, e.g. `style.module.scss`. Otherwise, these files are handled like all other `style.scss`. They will also be extracted into `style-index.css`.

#### Using fonts and images
### Using fonts and images

It is possible to reference font (`woff`, `woff2`, `eot`, `ttf` and `otf`) and image (`bmp`, `png`, `jpg`, `jpeg`, `gif` and `wepb`) files from CSS that is controlled by webpack as explained in the previous section.

Expand All @@ -724,7 +716,7 @@ _Example:_
}
```

#### Using SVG
### Using SVG

_Example:_

Expand All @@ -739,14 +731,33 @@ const App = () => (
);
```

#### Provide your own webpack config
## Advanced Usage

In general, this package should be used with the set of recommended config files. While it’s possible to override every single config file provided, if you have to do it, it means that your use case is far more complicated than anticipated. If that happens, it would be better to avoid using the whole abstraction layer and set up your project with full control over tooling used.

### Default webpack config

`@wordpress/scripts` bundles the default webpack config used as a base by the WordPress editor. These are the defaults:

- [Entry](https://webpack.js.org/configuration/entry-context/#entry): the entry points for your project get detected by scanning all script fields in `block.json` files located in the `src` directory. The fallback entry point is `src/index.js` (other supported extensions: `.jsx`, `.ts`, and `.tsx`) in case there is no `block.json` file found.
- [Output](https://webpack.js.org/configuration/output): `build/[name].js`, for example: `build/index.js`, or `build/my-block/index.js`.
- [Loaders](https://webpack.js.org/loaders/):
- [`babel-loader`](https://webpack.js.org/loaders/babel-loader/) allows transpiling JavaScript and TypeScript files using Babel and webpack.
- [`@svgr/webpack`](https://www.npmjs.com/package/@svgr/webpack) and [`url-loader`](https://webpack.js.org/loaders/url-loader/) makes it possible to handle SVG files in JavaScript code.
- [`css-loader`](https://webpack.js.org/loaders/css-loader/) chained with [`postcss-loader`](https://webpack.js.org/loaders/postcss-loader/) and [sass-loader](https://webpack.js.org/loaders/sass-loader/) let webpack process CSS, SASS or SCSS files referenced in JavaScript files.
- [Plugins](https://webpack.js.org/configuration/plugins) (among others):
- [`CopyWebpackPlugin`](https://webpack.js.org/plugins/copy-webpack-plugin/) copies all `block.json` files discovered in the `src` directory to the build directory.
- [`MiniCssExtractPlugin`](https://webpack.js.org/plugins/mini-css-extract-plugin/) extracts CSS into separate files. It creates a CSS file per JavaScript entry point which contains CSS.
- [`@wordpress/dependency-extraction-webpack-plugin`](https://github.com/WordPress/gutenberg/tree/HEAD/packages/dependency-extraction-webpack-plugin/README.md) is used with the default configuration to ensure that WordPress provided scripts are not included in the built bundle.

### Provide your own webpack config

Should there be any situation where you want to provide your own webpack config, you can do so. The `build` and `start` commands will use your provided file when:

- the command receives a `--config` argument. Example: `wp-scripts build --config my-own-webpack-config.js`.
- there is a file called `webpack.config.js` or `webpack.config.babel.js` in the top-level directory of your project (at the same level as `package.json`).

##### Extending the webpack config
#### Extending the webpack config

To extend the provided webpack config, or replace subsections within the provided webpack config, you can provide your own `webpack.config.js` file, `require` the provided `webpack.config.js` file, and use the [`spread` operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) to import all of or part of the provided configuration.

Expand Down
12 changes: 6 additions & 6 deletions packages/scripts/config/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const {
hasArgInCLI,
hasCssnanoConfig,
hasPostCSSConfig,
getWordPressSrcDirectory,
getProjectSourcePath,
getWebpackEntryPoints,
getAsBooleanFromENV,
getBlockJsonModuleFields,
Expand Down Expand Up @@ -302,14 +302,14 @@ const scriptConfig = {
} ),

new PhpFilePathsPlugin( {
context: getWordPressSrcDirectory(),
context: getProjectSourcePath(),
props: [ 'render', 'variations' ],
} ),
new CopyWebpackPlugin( {
patterns: [
{
from: '**/block.json',
context: getWordPressSrcDirectory(),
context: getProjectSourcePath(),
noErrorOnMissing: true,
transform( content, absoluteFrom ) {
const convertExtension = ( path ) => {
Expand Down Expand Up @@ -346,7 +346,7 @@ const scriptConfig = {
const runtimePath = relative(
dirname( absoluteFrom ),
fromProjectRoot(
getWordPressSrcDirectory() +
getProjectSourcePath() +
sep +
'runtime.js'
)
Expand Down Expand Up @@ -375,7 +375,7 @@ const scriptConfig = {
},
{
from: '**/*.php',
context: getWordPressSrcDirectory(),
context: getProjectSourcePath(),
noErrorOnMissing: true,
filter: ( filepath ) => {
return (
Expand Down Expand Up @@ -417,7 +417,7 @@ if ( hasExperimentalModulesFlag ) {
/** @type {ReadonlyArray<string>} */
this.blockJsonFiles = glob( '**/block.json', {
absolute: true,
cwd: fromProjectRoot( getWordPressSrcDirectory() ),
cwd: fromProjectRoot( getProjectSourcePath() ),
} );
}

Expand Down
22 changes: 1 addition & 21 deletions packages/scripts/scripts/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,11 @@ const { sync: resolveBin } = require( 'resolve-bin' );
/**
* Internal dependencies
*/
const { getWebpackArgs, hasArgInCLI, getArgFromCLI } = require( '../utils' );
const { getWebpackArgs } = require( '../utils' );
const EXIT_ERROR_CODE = 1;

process.env.NODE_ENV = process.env.NODE_ENV || 'production';

if ( hasArgInCLI( '--experimental-modules' ) ) {
process.env.WP_EXPERIMENTAL_MODULES = true;
}

if ( hasArgInCLI( '--webpack-no-externals' ) ) {
process.env.WP_NO_EXTERNALS = true;
}

if ( hasArgInCLI( '--webpack-bundle-analyzer' ) ) {
process.env.WP_BUNDLE_ANALYZER = true;
}

if ( hasArgInCLI( '--webpack-copy-php' ) ) {
process.env.WP_COPY_PHP_FILES_TO_DIST = true;
}

process.env.WP_SRC_DIRECTORY = hasArgInCLI( '--webpack-src-dir' )
? getArgFromCLI( '--webpack-src-dir' )
: 'src';

const { status } = spawn( resolveBin( 'webpack' ), getWebpackArgs(), {
stdio: 'inherit',
} );
Expand Down
Loading

0 comments on commit fb7579b

Please sign in to comment.