diff --git a/packages/scripts/CHANGELOG.md b/packages/scripts/CHANGELOG.md index 9c208e0d329cd8..4ebc36ac3d2015 100644 --- a/packages/scripts/CHANGELOG.md +++ b/packages/scripts/CHANGELOG.md @@ -2,10 +2,15 @@ ## Unreleased -### Bug Fix +### New Feature + +- Add `--webpack-src-dir` CLI flag to allow customizing the source code directory (`src` by default) ([#39618](https://github.com/WordPress/gutenberg/pull/39618)). + +### Bug Fixes - Add `vendor/` to `.markdownlintignore`, to match `lint-md-docs` docs ([#39724](https://github.com/WordPress/gutenberg/pull/39724)). - Include files with `.jsx` extension in the build process ([#39613](https://github.com/WordPress/gutenberg/pull/39613)). +- Ensure that the default logic for entry points in the build commands is executed only when used the default config ([#39618](https://github.com/WordPress/gutenberg/pull/39618)). ## 22.2.0 (2022-03-11) diff --git a/packages/scripts/README.md b/packages/scripts/README.md index 8fe5bfefb6fc42..0d4e12ca8a09cd 100644 --- a/packages/scripts/README.md +++ b/packages/scripts/README.md @@ -47,6 +47,10 @@ _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. The 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. + + ## 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. @@ -55,6 +59,7 @@ In most cases bumping the `@wordpress/scripts` version in `package.json` and run We commit to keeping the breaking changes minimal so you can upgrade `@wordpress/scripts` as seamless as possible. + ## Available Scripts ### `build` @@ -80,7 +85,8 @@ _Example:_ "scripts": { "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:copy-php": "wp-scripts build --webpack-copy-php", + "build:custom-directory": "wp-scripts build --webpack-src-dir=custom-directory" } } ``` @@ -90,12 +96,14 @@ 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. +- `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 `src` directory and its subfolders to the output directory. +- `--webpack-copy-php` – enables copying 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`. #### Advanced information @@ -371,7 +379,8 @@ _Example:_ "start": "wp-scripts start", "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" + "start:copy-php": "wp-scripts start --webpack-copy-php", + "start:custom-directory": "wp-scripts start --webpack-src-dir=custom-directory", } } ``` @@ -382,14 +391,16 @@ This is how you execute the script with presented setup: - `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: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 `src` directory and its subfolders to the output directory. +- `--webpack-copy-php` – enables copying 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`. #### Advanced information diff --git a/packages/scripts/config/webpack.config.js b/packages/scripts/config/webpack.config.js index b3eddc562f6232..d03e6fe18646f2 100644 --- a/packages/scripts/config/webpack.config.js +++ b/packages/scripts/config/webpack.config.js @@ -36,7 +36,7 @@ if ( ! browserslist.findConfig( '.' ) ) { } const hasReactFastRefresh = hasArgInCLI( '--hot' ) && ! isProduction; -const copyWebPackPatterns = process.env.WP_COPY_PHP_FILES_TO_DIST +const copyWebpackPatterns = process.env.WP_COPY_PHP_FILES_TO_DIST ? '**/{block.json,*.php}' : '**/block.json'; @@ -90,7 +90,7 @@ const cssLoaders = [ const config = { mode, target, - entry: getWebpackEntryPoints(), + entry: getWebpackEntryPoints, output: { filename: '[name].js', path: resolve( process.cwd(), 'build' ), @@ -232,8 +232,8 @@ const config = { new CopyWebpackPlugin( { patterns: [ { - from: copyWebPackPatterns, - context: 'src', + from: copyWebpackPatterns, + context: process.env.WP_SRC_DIRECTORY, noErrorOnMissing: true, }, ], diff --git a/packages/scripts/scripts/build.js b/packages/scripts/scripts/build.js index 19a244da48e15d..f1d101954e7cb0 100644 --- a/packages/scripts/scripts/build.js +++ b/packages/scripts/scripts/build.js @@ -7,7 +7,7 @@ const { sync: resolveBin } = require( 'resolve-bin' ); /** * Internal dependencies */ -const { getWebpackArgs, hasArgInCLI } = require( '../utils' ); +const { getWebpackArgs, hasArgInCLI, getArgFromCLI } = require( '../utils' ); process.env.NODE_ENV = process.env.NODE_ENV || 'production'; @@ -23,6 +23,10 @@ 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', } ); diff --git a/packages/scripts/scripts/start.js b/packages/scripts/scripts/start.js index 383634ee8b46bb..7c9aae9c143e6b 100644 --- a/packages/scripts/scripts/start.js +++ b/packages/scripts/scripts/start.js @@ -25,6 +25,10 @@ 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' ), [ hasArgInCLI( '--hot' ) ? 'serve' : 'watch', ...getWebpackArgs() ], diff --git a/packages/scripts/utils/config.js b/packages/scripts/utils/config.js index b8bc4861c1f8de..1d7650a6a89594 100644 --- a/packages/scripts/utils/config.js +++ b/packages/scripts/utils/config.js @@ -2,6 +2,7 @@ * External dependencies */ const chalk = require( 'chalk' ); +const { readFileSync } = require( 'fs' ); const { basename, dirname, extname, join, sep } = require( 'path' ); const { sync: glob } = require( 'fast-glob' ); @@ -183,26 +184,34 @@ function getWebpackEntryPoints() { return JSON.parse( process.env.WP_ENTRY ); } - // Continue only if the `src` directory exists. - if ( ! hasProjectFile( 'src' ) ) { + // Continue only if the source directory exists. + if ( ! hasProjectFile( process.env.WP_SRC_DIRECTORY ) ) { + log( + chalk.yellow( + `Source directory "${ process.env.WP_SRC_DIRECTORY }" was not found. Please confirm there is a "src" directory in the root or the value passed to --webpack-src-dir is correct.` + ) + ); return {}; } - // 2. Checks whether any block metadata files can be detected in the `src` directory. + // 2. Checks whether any block metadata files can be detected in the defined source directory. // It scans all discovered files looking for JavaScript assets and converts them to entry points. - const blockMetadataFiles = glob( 'src/**/block.json', { - absolute: true, - } ); + const blockMetadataFiles = glob( + `${ process.env.WP_SRC_DIRECTORY }/**/block.json`, + { + absolute: true, + } + ); if ( blockMetadataFiles.length > 0 ) { - const srcDirectory = fromProjectRoot( 'src' + sep ); + const srcDirectory = fromProjectRoot( + process.env.WP_SRC_DIRECTORY + sep + ); const entryPoints = blockMetadataFiles.reduce( ( accumulator, blockMetadataFile ) => { - const { - editorScript, - script, - viewScript, - } = require( blockMetadataFile ); + const { editorScript, script, viewScript } = JSON.parse( + readFileSync( blockMetadataFile ) + ); [ editorScript, script, viewScript ] .flat() .filter( ( value ) => value && value.startsWith( 'file:' ) ) @@ -213,7 +222,7 @@ function getWebpackEntryPoints() { value.replace( 'file:', '' ) ); - // Takes the path without the file extension, and relative to the `src` directory. + // Takes the path without the file extension, and relative to the defined source directory. if ( ! filepath.startsWith( srcDirectory ) ) { log( chalk.yellow( @@ -223,7 +232,9 @@ function getWebpackEntryPoints() { ) }" listed in "${ blockMetadataFile.replace( fromProjectRoot( sep ), '' - ) }". File is located outside of the "src" directory.` + ) }". File is located outside of the "${ + process.env.WP_SRC_DIRECTORY + }" directory.` ) ); return; @@ -233,9 +244,9 @@ function getWebpackEntryPoints() { .replace( srcDirectory, '' ) .replace( /\\/g, '/' ); - // Detects the proper file extension used in the `src` directory. + // Detects the proper file extension used in the defined source directory. const [ entryFilepath ] = glob( - `src/${ entryName }.[jt]s?(x)`, + `${ process.env.WP_SRC_DIRECTORY }/${ entryName }.[jt]s?(x)`, { absolute: true, } @@ -250,7 +261,9 @@ function getWebpackEntryPoints() { ) }" listed in "${ blockMetadataFile.replace( fromProjectRoot( sep ), '' - ) }". File does not exist in the "src" directory.` + ) }". File does not exist in the "${ + process.env.WP_SRC_DIRECTORY + }" directory.` ) ); return; @@ -267,14 +280,19 @@ function getWebpackEntryPoints() { } } - // 3. Checks whether a standard file name can be detected in the `src` directory, + // 3. Checks whether a standard file name can be detected in the defined source directory, // and converts the discovered file to entry point. - const [ entryFile ] = glob( 'src/index.[jt]s?(x)', { - absolute: true, - } ); + const [ entryFile ] = glob( + `${ process.env.WP_SRC_DIRECTORY }/index.[jt]s?(x)`, + { + absolute: true, + } + ); if ( ! entryFile ) { log( - chalk.yellow( 'No entry file discovered in the "src" directory.' ) + chalk.yellow( + `No entry file discovered in the "${ process.env.WP_SRC_DIRECTORY }" directory.` + ) ); return {}; }