From 72ff590394027945b4adea0cd1d838a6060671c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=28Greg=29=20Zi=C3=B3=C5=82kowski?= Date: Thu, 21 Feb 2019 11:00:02 +0100 Subject: [PATCH] Extract reusable part of Webpack config and put in @wordpress/scripts (#13814) * New build-config package with webpack config. Pull the Gutenberg webpack config into a package so it can be re-used for block/extension development. * Require new build-config package. * Dynamically handle WP externals with a function. Use code from WP Calypso for handling WP externals so we don't have to have the actual list of packages accessible in our webpack configuration. * Use webpack config from build-config package. * Require build-config package. * Adjust file refs for WP packages. * Move main gutenberg entry definition and webpack copy plugin out of build-config. * Add react-dev-utils for formatting webpack compiler messages. * Implement build script using webpack config from build-config. * Adjust output path so build goes to working directory. * Update package name to webpack-config * Apply more tweaks to the way webpack config package is structured * Update the way externals are handled * Add default values for entry and output * Move shared webpack config under @wordpress/scripts package * Improve the way how loaders are handled * Replace GUTENBERG with WP in webpack config env variables Co-Authored-By: gziolo * Bring back feature flag to webpack config accidentally removed during merge * Add missing dev dependencies for the packages used in webpack config * Fix the list of excluded folders for babel-loader --- package-lock.json | 90 ++++--- package.json | 5 +- .../test/index.js | 3 +- .../CHANGELOG.md | 10 +- .../block-serialization-spec-parser/index.js | 2 - .../package.json | 6 +- .../test/index.js | 3 +- packages/scripts/config/webpack.config.js | 109 +++++++++ packages/scripts/package.json | 6 +- packages/scripts/scripts/build.js | 1 - packages/scripts/utils/index.js | 4 + packages/scripts/utils/string.js | 20 ++ packages/scripts/utils/test/string.js | 23 ++ webpack.config.js | 228 ++++++------------ 14 files changed, 305 insertions(+), 205 deletions(-) delete mode 100644 packages/block-serialization-spec-parser/index.js create mode 100644 packages/scripts/config/webpack.config.js create mode 100644 packages/scripts/utils/string.js create mode 100644 packages/scripts/utils/test/string.js diff --git a/package-lock.json b/package-lock.json index ed633e96e9bd29..656ba9ae3cd0ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2562,7 +2562,10 @@ } }, "@wordpress/block-serialization-spec-parser": { - "version": "file:packages/block-serialization-spec-parser" + "version": "file:packages/block-serialization-spec-parser", + "requires": { + "pegjs": "^0.10.0" + } }, "@wordpress/blocks": { "version": "file:packages/blocks", @@ -2997,6 +3000,7 @@ "@wordpress/eslint-plugin": "file:packages/eslint-plugin", "@wordpress/jest-preset-default": "file:packages/jest-preset-default", "@wordpress/npm-package-json-lint-config": "file:packages/npm-package-json-lint-config", + "babel-loader": "^8.0.5", "chalk": "^2.4.1", "check-node-version": "^3.1.1", "cross-spawn": "^5.1.0", @@ -3007,10 +3011,13 @@ "puppeteer": "1.6.1", "read-pkg-up": "^1.0.1", "resolve-bin": "^0.4.0", + "source-map-loader": "^0.2.4", "stylelint": "^9.10.1", "stylelint-config-wordpress": "^13.1.0", "webpack": "4.8.3", - "webpack-cli": "^3.1.2" + "webpack-bundle-analyzer": "^3.0.3", + "webpack-cli": "^3.1.2", + "webpack-livereload-plugin": "^2.2.0" } }, "@wordpress/shortcode": { @@ -15869,8 +15876,7 @@ "pegjs": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/pegjs/-/pegjs-0.10.0.tgz", - "integrity": "sha1-z4uvrm7d/0tafvsYUmnqr0YQ3b0=", - "dev": true + "integrity": "sha1-z4uvrm7d/0tafvsYUmnqr0YQ3b0=" }, "pend": { "version": "1.2.0", @@ -15956,6 +15962,34 @@ "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", "dev": true }, + "portfinder": { + "version": "1.0.20", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.20.tgz", + "integrity": "sha512-Yxe4mTyDzTd59PZJY4ojZR8F+E5e97iq2ZOHPz3HDgSvYC5siNad2tLooQ5y5QHyQhc3xVqvyk/eNA3wuoa7Sw==", + "dev": true, + "requires": { + "async": "^1.5.2", + "debug": "^2.2.0", + "mkdirp": "0.5.x" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", @@ -19763,34 +19797,13 @@ "dev": true }, "source-map-loader": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-0.2.3.tgz", - "integrity": "sha512-MYbFX9DYxmTQFfy2v8FC1XZwpwHKYxg3SK8Wb7VPBKuhDjz8gi9re2819MsG4p49HDyiOSUKlmZ+nQBArW5CGw==", + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-0.2.4.tgz", + "integrity": "sha512-OU6UJUty+i2JDpTItnizPrlpOIBLmQbWMuBg9q5bVtnHACqw1tn9nNwqJLbv0/00JjnJb/Ee5g5WS5vrRv7zIQ==", "dev": true, "requires": { "async": "^2.5.0", - "loader-utils": "~0.2.2", - "source-map": "~0.6.1" - }, - "dependencies": { - "loader-utils": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", - "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", - "dev": true, - "requires": { - "big.js": "^3.1.3", - "emojis-list": "^2.0.0", - "json5": "^0.5.0", - "object-assign": "^4.0.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } + "loader-utils": "^1.1.0" } }, "source-map-resolve": { @@ -21820,9 +21833,9 @@ } }, "webpack-bundle-analyzer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.0.2.tgz", - "integrity": "sha512-cZG4wSQtKrSpk5RJ33dxiaAyo8bP0V+JvycAyIDFEiDIhw4LHhhVKhn40YT1w6TR9E4scHA00LnIoBtTA13Mow==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.0.3.tgz", + "integrity": "sha512-naLWiRfmtH4UJgtUktRTLw6FdoZJ2RvCR9ePbwM9aRMsS/KjFerkPZG9epEvXRAw5d5oPdrs9+3p+afNjxW8Xw==", "dev": true, "requires": { "acorn": "^5.7.3", @@ -21846,9 +21859,9 @@ "dev": true }, "commander": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.18.0.tgz", - "integrity": "sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ==", + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", "dev": true } } @@ -22052,11 +22065,12 @@ } }, "webpack-livereload-plugin": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/webpack-livereload-plugin/-/webpack-livereload-plugin-2.1.1.tgz", - "integrity": "sha512-W7Q55QbPvVJotpIZSjjwzmqQ22333ExYxWM3WFlHKkbPStQqVRSmJkjntUqXF9jtpdeXi8r8HLkA1RVnAP0SQA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/webpack-livereload-plugin/-/webpack-livereload-plugin-2.2.0.tgz", + "integrity": "sha512-sx9xA5mHoNOUgLQI0PmXT3KV9ecsVmUaTgr+fsoL69qAOHw/7VzkL1+ZMDQ8n0dPbWounswK6cBRSgMod7Nhgg==", "dev": true, "requires": { + "portfinder": "^1.0.17", "tiny-lr": "^1.1.1" } }, diff --git a/package.json b/package.json index ea6cd663dbca01..2299994e4f3859 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,6 @@ "@wordpress/npm-package-json-lint-config": "file:packages/npm-package-json-lint-config", "@wordpress/postcss-themes": "file:packages/postcss-themes", "@wordpress/scripts": "file:packages/scripts", - "babel-loader": "8.0.5", "benchmark": "2.1.4", "browserslist": "4.4.1", "chalk": "2.4.1", @@ -104,6 +103,7 @@ "node-watch": "0.6.0", "pegjs": "0.10.0", "phpegjs": "1.0.0-beta7", + "postcss": "7.0.13", "react-dom": "16.6.3", "react-test-renderer": "16.6.3", "redux": "4.0.0", @@ -113,13 +113,10 @@ "shallow-equal": "1.0.0", "shallow-equals": "1.0.0", "shallowequal": "1.1.0", - "source-map-loader": "0.2.3", "sprintf-js": "1.1.1", "stylelint-config-wordpress": "13.1.0", "uuid": "3.3.2", "webpack": "4.8.3", - "webpack-bundle-analyzer": "3.0.2", - "webpack-livereload-plugin": "2.1.1", "webpack-rtl-plugin": "github:yoavf/webpack-rtl-plugin#develop" }, "npmPackageJsonLintConfig": { diff --git a/packages/block-serialization-default-parser/test/index.js b/packages/block-serialization-default-parser/test/index.js index a3c67e280ef946..72f4121ce19445 100644 --- a/packages/block-serialization-default-parser/test/index.js +++ b/packages/block-serialization-default-parser/test/index.js @@ -6,7 +6,8 @@ import path from 'path'; /** * WordPress dependencies */ -import { jsTester, phpTester } from '@wordpress/block-serialization-spec-parser'; +// eslint-disable-next-line no-restricted-syntax +import { jsTester, phpTester } from '@wordpress/block-serialization-spec-parser/shared-tests'; /** * Internal dependencies diff --git a/packages/block-serialization-spec-parser/CHANGELOG.md b/packages/block-serialization-spec-parser/CHANGELOG.md index e4f403ffd68497..7ba44f0cd9a963 100644 --- a/packages/block-serialization-spec-parser/CHANGELOG.md +++ b/packages/block-serialization-spec-parser/CHANGELOG.md @@ -1,6 +1,12 @@ -## 2.1.0 (Unreleased) +## 3.0.0 (Unreleased) -- A `parser.php` file generated from the PEGJS grammar is now included. +## Breaking Change + +- A `parser.js` file generated from the PEGJS grammar is now outputted in commonjs format. + +## New Feature + +- A `parser.php` file generated from the PEGJS grammar is now added upon installation. ## 2.0.2 (2018-12-12) diff --git a/packages/block-serialization-spec-parser/index.js b/packages/block-serialization-spec-parser/index.js deleted file mode 100644 index b217f8f5c5ad76..00000000000000 --- a/packages/block-serialization-spec-parser/index.js +++ /dev/null @@ -1,2 +0,0 @@ -export { parse } from './parser'; -export { jsTester, phpTester } from './shared-tests'; diff --git a/packages/block-serialization-spec-parser/package.json b/packages/block-serialization-spec-parser/package.json index 918c269169f09f..5d40a8cfd03de1 100644 --- a/packages/block-serialization-spec-parser/package.json +++ b/packages/block-serialization-spec-parser/package.json @@ -18,12 +18,16 @@ "bugs": { "url": "https://github.com/WordPress/gutenberg/issues" }, + "main": "parser.js", + "dependencies": { + "pegjs": "^0.10.0" + }, "publishConfig": { "access": "public" }, "scripts": { "build": "concurrently \"npm run build:js\" \"npm run build:php\"", - "build:js": "pegjs --format umd -o ./parser.js ./grammar.pegjs", + "build:js": "pegjs --format commonjs -o ./parser.js ./grammar.pegjs", "build:php": "node bin/create-php-parser.js" } } diff --git a/packages/block-serialization-spec-parser/test/index.js b/packages/block-serialization-spec-parser/test/index.js index 7bdbe9f053f169..9d00c5a5434c33 100644 --- a/packages/block-serialization-spec-parser/test/index.js +++ b/packages/block-serialization-spec-parser/test/index.js @@ -6,7 +6,8 @@ import path from 'path'; /** * Internal dependencies */ -import { jsTester, phpTester, parse } from '../'; +import { parse } from '../'; +import { jsTester, phpTester } from '../shared-tests'; describe( 'block-serialization-spec-parser-js', jsTester( parse ) ); diff --git a/packages/scripts/config/webpack.config.js b/packages/scripts/config/webpack.config.js new file mode 100644 index 00000000000000..44d0ff61d9a659 --- /dev/null +++ b/packages/scripts/config/webpack.config.js @@ -0,0 +1,109 @@ +/** + * External dependencies + */ +const { BundleAnalyzerPlugin } = require( 'webpack-bundle-analyzer' ); +const LiveReloadPlugin = require( 'webpack-livereload-plugin' ); +const path = require( 'path' ); + +/** + * Internal dependencies + */ +const { camelCaseDash } = require( '../utils' ); + +/** + * Converts @wordpress/* string request into request object. + * + * Note this isn't the same as camel case because of the + * way that numbers don't trigger the capitalized next letter. + * + * @example + * formatRequest( '@wordpress/api-fetch' ); + * // { this: [ 'wp', 'apiFetch' ] } + * formatRequest( '@wordpress/i18n' ); + * // { this: [ 'wp', 'i18n' ] } + * + * @param {string} request Request name from import statement. + * @return {Object} Request object formatted for further processing. + */ +const formatRequest = ( request ) => { + // '@wordpress/api-fetch' -> [ '@wordpress', 'api-fetch' ] + const [ , name ] = request.split( '/' ); + + // { this: [ 'wp', 'apiFetch' ] } + return { + this: [ 'wp', camelCaseDash( name ) ], + }; +}; + +const wordpressExternals = ( context, request, callback ) => { + if ( /^@wordpress\//.test( request ) ) { + callback( null, formatRequest( request ), 'this' ); + } else { + callback(); + } +}; + +const externals = [ + { + react: 'React', + 'react-dom': 'ReactDOM', + moment: 'moment', + jquery: 'jQuery', + lodash: 'lodash', + 'lodash-es': 'lodash', + }, + wordpressExternals, +]; + +const isProduction = process.env.NODE_ENV === 'production'; +const mode = isProduction ? 'production' : 'development'; + +const config = { + mode, + entry: { + index: path.resolve( process.cwd(), 'src', 'index.js' ), + }, + output: { + filename: '[name].js', + path: path.resolve( process.cwd(), 'build' ), + }, + externals, + resolve: { + alias: { + 'lodash-es': 'lodash', + }, + }, + module: { + rules: [ + { + test: /\.js$/, + use: require.resolve( 'source-map-loader' ), + enforce: 'pre', + }, + { + test: /\.js$/, + exclude: /node_modules/, + use: require.resolve( 'babel-loader' ), + }, + ], + }, + plugins: [ + // WP_BUNDLE_ANALYZER global variable enables utility that represents bundle content + // as convenient interactive zoomable treemap. + process.env.WP_BUNDLE_ANALYZER && new BundleAnalyzerPlugin(), + // WP_LIVE_RELOAD_PORT global variable changes port on which live reload works + // when running watch mode. + ! isProduction && new LiveReloadPlugin( { port: process.env.WP_LIVE_RELOAD_PORT || 35729 } ), + ].filter( Boolean ), + stats: { + children: false, + }, +}; + +if ( ! isProduction ) { + // WP_DEVTOOL global variable controls how source maps are generated. + // See: https://webpack.js.org/configuration/devtool/#devtool. + config.devtool = process.env.WP_DEVTOOL || 'source-map'; +} + +module.exports = config; diff --git a/packages/scripts/package.json b/packages/scripts/package.json index 8aaf6e8ee7ac67..388bc0a26a3b86 100644 --- a/packages/scripts/package.json +++ b/packages/scripts/package.json @@ -35,6 +35,7 @@ "@wordpress/eslint-plugin": "file:../eslint-plugin", "@wordpress/jest-preset-default": "file:../jest-preset-default", "@wordpress/npm-package-json-lint-config": "file:../npm-package-json-lint-config", + "babel-loader": "^8.0.5", "chalk": "^2.4.1", "check-node-version": "^3.1.1", "cross-spawn": "^5.1.0", @@ -45,10 +46,13 @@ "puppeteer": "1.6.1", "read-pkg-up": "^1.0.1", "resolve-bin": "^0.4.0", + "source-map-loader": "^0.2.4", "stylelint": "^9.10.1", "stylelint-config-wordpress": "^13.1.0", "webpack": "4.8.3", - "webpack-cli": "^3.1.2" + "webpack-bundle-analyzer": "^3.0.3", + "webpack-cli": "^3.1.2", + "webpack-livereload-plugin": "^2.2.0" }, "publishConfig": { "access": "public" diff --git a/packages/scripts/scripts/build.js b/packages/scripts/scripts/build.js index 9470274f76633c..ea2c7d303f2fa0 100644 --- a/packages/scripts/scripts/build.js +++ b/packages/scripts/scripts/build.js @@ -32,4 +32,3 @@ if ( hasWebpackConfig ) { console.log( 'Webpack config file is missing.' ); process.exit( 1 ); } - diff --git a/packages/scripts/utils/index.js b/packages/scripts/utils/index.js index 473952fcdfc174..b1a78d0d600c91 100644 --- a/packages/scripts/utils/index.js +++ b/packages/scripts/utils/index.js @@ -18,8 +18,12 @@ const { const { hasPackageProp, } = require( './package' ); +const { + camelCaseDash, +} = require( './string' ); module.exports = { + camelCaseDash, fromConfigRoot, getCliArg, getCliArgs, diff --git a/packages/scripts/utils/string.js b/packages/scripts/utils/string.js new file mode 100644 index 00000000000000..ea6ea3889c1ad8 --- /dev/null +++ b/packages/scripts/utils/string.js @@ -0,0 +1,20 @@ +/** + * Given a string, returns a new string with dash separators converted to + * camelCase equivalent. This is not as aggressive as `_.camelCase` in + * converting to uppercase, where Lodash will also capitalize letters + * following numbers. + * + * @param {string} string Input dash-delimited string. + * + * @return {string} Camel-cased string. + */ +function camelCaseDash( string ) { + return string.replace( + /-([a-z])/g, + ( match, letter ) => letter.toUpperCase() + ); +} + +module.exports = { + camelCaseDash, +}; diff --git a/packages/scripts/utils/test/string.js b/packages/scripts/utils/test/string.js new file mode 100644 index 00000000000000..ca81bdda5df540 --- /dev/null +++ b/packages/scripts/utils/test/string.js @@ -0,0 +1,23 @@ +/** + * Internal dependencies + */ +import { camelCaseDash } from '../string'; + +describe( 'string', () => { + describe( 'camelCaseDash', () => { + test( 'does not change a single word', () => { + expect( camelCaseDash( 'blocks' ) ).toBe( 'blocks' ); + expect( camelCaseDash( 'dom' ) ).toBe( 'dom' ); + } ); + + test( 'does not capitalize letters following numbers', () => { + expect( camelCaseDash( 'a11y' ) ).toBe( 'a11y' ); + expect( camelCaseDash( 'i18n' ) ).toBe( 'i18n' ); + } ); + + test( 'converts dashes into camel case', () => { + expect( camelCaseDash( 'api-fetch' ) ).toBe( 'apiFetch' ); + expect( camelCaseDash( 'list-reusable-blocks' ) ).toBe( 'listReusableBlocks' ); + } ); + } ); +} ); diff --git a/webpack.config.js b/webpack.config.js index c67b8c95c804dd..a5dd63c3bd9822 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -3,10 +3,8 @@ */ const { DefinePlugin } = require( 'webpack' ); const WebpackRTLPlugin = require( 'webpack-rtl-plugin' ); -const LiveReloadPlugin = require( 'webpack-livereload-plugin' ); const CopyWebpackPlugin = require( 'copy-webpack-plugin' ); const postcss = require( 'postcss' ); - const { get } = require( 'lodash' ); const { basename } = require( 'path' ); @@ -15,7 +13,8 @@ const { basename } = require( 'path' ); */ const CustomTemplatedPathPlugin = require( '@wordpress/custom-templated-path-webpack-plugin' ); const LibraryExportDefaultPlugin = require( '@wordpress/library-export-default-webpack-plugin' ); -const { BundleAnalyzerPlugin } = require( 'webpack-bundle-analyzer' ); +const config = require( '@wordpress/scripts/config/webpack.config' ); +const { camelCaseDash } = require( '@wordpress/scripts/utils' ); /** * Internal dependencies @@ -24,165 +23,86 @@ const { dependencies } = require( './package' ); const WORDPRESS_NAMESPACE = '@wordpress/'; -/** - * Given a string, returns a new string with dash separators converted to - * camelCase equivalent. This is not as aggressive as `_.camelCase` in - * converting to uppercase, where Lodash will also capitalize letters - * following numbers. - * - * @param {string} string Input dash-delimited string. - * - * @return {string} Camel-cased string. - */ -function camelCaseDash( string ) { - return string.replace( - /-([a-z])/g, - ( match, letter ) => letter.toUpperCase() - ); -} - const gutenbergPackages = Object.keys( dependencies ) .filter( ( packageName ) => packageName.startsWith( WORDPRESS_NAMESPACE ) ) .map( ( packageName ) => packageName.replace( WORDPRESS_NAMESPACE, '' ) ); -const externals = { - react: 'React', - 'react-dom': 'ReactDOM', - moment: 'moment', - jquery: 'jQuery', - lodash: 'lodash', - 'lodash-es': 'lodash', +config.entry = gutenbergPackages.reduce( ( memo, packageName ) => { + const name = camelCaseDash( packageName ); + memo[ name ] = `./packages/${ packageName }`; + return memo; +}, {} ); + +config.output = { + filename: './build/[basename]/index.js', + path: __dirname, + library: [ 'wp', '[name]' ], + libraryTarget: 'this', }; -gutenbergPackages.forEach( ( name ) => { - externals[ WORDPRESS_NAMESPACE + name ] = { - this: [ 'wp', camelCaseDash( name ) ], - }; -} ); - -const isProduction = process.env.NODE_ENV === 'production'; -const mode = isProduction ? 'production' : 'development'; - -const config = { - mode, - entry: gutenbergPackages.reduce( ( memo, packageName ) => { - const name = camelCaseDash( packageName ); - memo[ name ] = `./packages/${ packageName }`; - return memo; - }, {} ), - output: { - filename: './build/[basename]/index.js', - path: __dirname, - library: [ 'wp', '[name]' ], - libraryTarget: 'this', - }, - externals, - resolve: { - modules: [ - __dirname, - 'node_modules', - ], - alias: { - 'lodash-es': 'lodash', +config.plugins.push( + new DefinePlugin( { + // Inject the `GUTENBERG_PHASE` global, used for feature flagging. + // eslint-disable-next-line @wordpress/gutenberg-phase + 'process.env.GUTENBERG_PHASE': JSON.stringify( parseInt( process.env.npm_package_config_GUTENBERG_PHASE, 10 ) || 1 ), + } ), + // Create RTL files with a -rtl suffix + new WebpackRTLPlugin( { + suffix: '-rtl', + minify: config.mode === 'production' ? { safe: true } : false, + } ), + new CustomTemplatedPathPlugin( { + basename( path, data ) { + let rawRequest; + + const entryModule = get( data, [ 'chunk', 'entryModule' ], {} ); + switch ( entryModule.type ) { + case 'javascript/auto': + rawRequest = entryModule.rawRequest; + break; + + case 'javascript/esm': + rawRequest = entryModule.rootModule.rawRequest; + break; + } + + if ( rawRequest ) { + return basename( rawRequest ); + } + + return path; }, - }, - module: { - rules: [ - { - test: /\.js$/, - use: [ 'source-map-loader' ], - enforce: 'pre', - }, - { - test: /\.js$/, - exclude: [ - /block-serialization-spec-parser/, - /is-shallow-equal/, - /node_modules/, - ], - use: 'babel-loader', - }, - ], - }, - plugins: [ - new DefinePlugin( { - // Inject the `GUTENBERG_PHASE` global, used for feature flagging. - // eslint-disable-next-line @wordpress/gutenberg-phase - 'process.env.GUTENBERG_PHASE': JSON.stringify( parseInt( process.env.npm_package_config_GUTENBERG_PHASE, 10 ) || 1 ), - } ), - // Create RTL files with a -rtl suffix - new WebpackRTLPlugin( { - suffix: '-rtl', - minify: process.env.NODE_ENV === 'production' ? { safe: true } : false, - } ), - new CustomTemplatedPathPlugin( { - basename( path, data ) { - let rawRequest; - - const entryModule = get( data, [ 'chunk', 'entryModule' ], {} ); - switch ( entryModule.type ) { - case 'javascript/auto': - rawRequest = entryModule.rawRequest; - break; - - case 'javascript/esm': - rawRequest = entryModule.rootModule.rawRequest; - break; - } - - if ( rawRequest ) { - return basename( rawRequest ); + } ), + new LibraryExportDefaultPlugin( [ + 'api-fetch', + 'deprecated', + 'dom-ready', + 'redux-routine', + 'token-list', + ].map( camelCaseDash ) ), + new CopyWebpackPlugin( + gutenbergPackages.map( ( packageName ) => ( { + from: `./packages/${ packageName }/build-style/*.css`, + to: `./build/${ packageName }/`, + flatten: true, + transform: ( content ) => { + if ( config.mode === 'production' ) { + return postcss( [ + require( 'cssnano' )( { + preset: [ 'default', { + discardComments: { + removeAll: true, + }, + } ], + } ), + ] ) + .process( content, { from: 'src/app.css', to: 'dest/app.css' } ) + .then( ( result ) => result.css ); } - - return path; + return content; }, - } ), - new LibraryExportDefaultPlugin( [ - 'api-fetch', - 'deprecated', - 'dom-ready', - 'redux-routine', - 'token-list', - ].map( camelCaseDash ) ), - new CopyWebpackPlugin( - gutenbergPackages.map( ( packageName ) => ( { - from: `./packages/${ packageName }/build-style/*.css`, - to: `./build/${ packageName }/`, - flatten: true, - transform: ( content ) => { - if ( config.mode === 'production' ) { - return postcss( [ - require( 'cssnano' )( { - preset: [ 'default', { - discardComments: { - removeAll: true, - }, - } ], - } ), - ] ) - .process( content, { from: 'src/app.css', to: 'dest/app.css' } ) - .then( ( result ) => result.css ); - } - return content; - }, - } ) ) - ), - // GUTENBERG_BUNDLE_ANALYZER global variable enables utility that represents bundle content - // as convenient interactive zoomable treemap. - process.env.GUTENBERG_BUNDLE_ANALYZER && new BundleAnalyzerPlugin(), - // GUTENBERG_LIVE_RELOAD_PORT global variable changes port on which live reload works - // when running watch mode. - ! isProduction && new LiveReloadPlugin( { port: process.env.GUTENBERG_LIVE_RELOAD_PORT || 35729 } ), - ].filter( Boolean ), - stats: { - children: false, - }, -}; - -if ( ! isProduction ) { - // GUTENBERG_DEVTOOL global variable controls how source maps are generated. - // See: https://webpack.js.org/configuration/devtool/#devtool. - config.devtool = process.env.GUTENBERG_DEVTOOL || 'source-map'; -} + } ) ) + ) +); module.exports = config;