diff --git a/package-lock.json b/package-lock.json
index 4e337d5bb945a1..25d870a5f8e2c6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2830,6 +2830,8 @@
"version": "file:packages/webpack-config",
"dev": true,
"requires": {
+ "babel-loader": "^8.0.5",
+ "source-map-loader": "^0.2.4",
"webpack-bundle-analyzer": "^3.0.3",
"webpack-livereload-plugin": "^2.2.0"
}
@@ -3585,15 +3587,80 @@
}
},
"babel-loader": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.0.tgz",
- "integrity": "sha512-lBUGBz411lSfT+8MHPEaqIVQ44odS1D/wxuTMhijqHc9arZR6jhJEaJa0RpZlCSITZoeK6xoDXTaVTrSoFD7IQ==",
+ "version": "8.0.5",
+ "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.5.tgz",
+ "integrity": "sha512-NTnHnVRd2JnRqPC0vW+iOQWU5pchDbYXsG2E6DMXEpMfUcQKclF9gmf3G3ZMhzG7IG9ji4coL0cm+FxeWxDpnw==",
"dev": true,
"requires": {
- "find-cache-dir": "^1.0.0",
+ "find-cache-dir": "^2.0.0",
"loader-utils": "^1.0.2",
"mkdirp": "^0.5.1",
"util.promisify": "^1.0.0"
+ },
+ "dependencies": {
+ "find-cache-dir": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.0.0.tgz",
+ "integrity": "sha512-LDUY6V1Xs5eFskUVYtIwatojt6+9xC9Chnlk/jYOOvn3FAFfSaWddxahDGyNHh0b2dMXa6YW2m0tk8TdVaXHlA==",
+ "dev": true,
+ "requires": {
+ "commondir": "^1.0.1",
+ "make-dir": "^1.0.0",
+ "pkg-dir": "^3.0.0"
+ }
+ },
+ "find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^3.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "p-limit": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz",
+ "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==",
+ "dev": true,
+ "requires": {
+ "p-try": "^2.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.0.0"
+ }
+ },
+ "p-try": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz",
+ "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==",
+ "dev": true
+ },
+ "pkg-dir": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
+ "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==",
+ "dev": true,
+ "requires": {
+ "find-up": "^3.0.0"
+ }
+ }
}
},
"babel-messages": {
@@ -18524,34 +18591,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": {
diff --git a/package.json b/package.json
index a50e84b098f0bf..371a491e2c486a 100644
--- a/package.json
+++ b/package.json
@@ -72,7 +72,6 @@
"@wordpress/postcss-themes": "file:packages/postcss-themes",
"@wordpress/scripts": "file:packages/scripts",
"@wordpress/webpack-config": "file:packages/webpack-config",
- "babel-loader": "8.0.0",
"benchmark": "2.1.4",
"browserslist": "4.4.1",
"chalk": "2.4.1",
@@ -111,7 +110,6 @@
"shallow-equals": "1.0.0",
"shallowequal": "1.1.0",
"sprintf-js": "1.1.1",
- "source-map-loader": "0.2.3",
"stylelint-config-wordpress": "13.1.0",
"uuid": "3.3.2",
"webpack-rtl-plugin": "github:yoavf/webpack-rtl-plugin#develop"
diff --git a/packages/webpack-config/README.md b/packages/webpack-config/README.md
index 5602de2c9ed815..02f0e12ba3529b 100644
--- a/packages/webpack-config/README.md
+++ b/packages/webpack-config/README.md
@@ -10,4 +10,16 @@ Install the module
npm install @wordpress/webpack-config --save-dev
```
+## Usage
+
+This is how to extend the default WordPress config for Webpack. You have to create your own `webpack.config.js` file in the root of your project, import the config and extend it with your custom settings as follows:
+
+```js
+const { config } = require( '@wordpress/webpack-config' );
+
+module.exports = Object.assign( {}, config, {
+ // apply your changes here
+} );
+```
+
diff --git a/packages/webpack-config/config.js b/packages/webpack-config/config.js
new file mode 100644
index 00000000000000..b7bd3c9b1c135a
--- /dev/null
+++ b/packages/webpack-config/config.js
@@ -0,0 +1,103 @@
+/**
+ * External dependencies
+ */
+const { BundleAnalyzerPlugin } = require( 'webpack-bundle-analyzer' );
+const LiveReloadPlugin = require( 'webpack-livereload-plugin' );
+
+/**
+ * Internal dependencies
+ */
+const { camelCaseDash } = require( './utils' );
+
+/**
+ * Converts @wordpress require into window reference.
+ *
+ * Note this isn't the same as camel case because of the
+ * way that numbers don't trigger the capitalized next letter.
+ *
+ * @example
+ * wordpressRequire( '@wordpress/api-fetch' ) = 'wp.apiFetch'
+ * wordpressRequire( '@wordpress/i18n' ) = 'wp.i18n'
+ *
+ * @param {string} request import name
+ * @return {string} global variable reference for import
+ */
+const wordpressRequire = ( request ) => {
+ // @wordpress/components -> [ @wordpress, components ]
+ const [ , name ] = request.split( '/' );
+
+ // components -> wp.components
+ return `wp.${ camelCaseDash( name ) }`;
+};
+
+const wordpressExternals = ( context, request, callback ) =>
+ /^@wordpress\//.test( request ) ?
+ callback( null, `root ${ wordpressRequire( request ) }` ) :
+ callback();
+
+const externals = [
+ {
+ react: 'React',
+ 'react-dom': 'ReactDOM',
+ tinymce: 'tinymce',
+ 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,
+ externals,
+ resolve: {
+ modules: [
+ process.cwd(),
+ 'node_modules',
+ ],
+ alias: {
+ 'lodash-es': 'lodash',
+ },
+ },
+ 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: [
+ // 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;
diff --git a/packages/webpack-config/index.js b/packages/webpack-config/index.js
index 4ab9659ced1082..eb022a4e505eb2 100644
--- a/packages/webpack-config/index.js
+++ b/packages/webpack-config/index.js
@@ -1,104 +1,10 @@
/**
- * External dependencies
+ * Internal dependencies
*/
-const { BundleAnalyzerPlugin } = require( 'webpack-bundle-analyzer' );
-const LiveReloadPlugin = require( 'webpack-livereload-plugin' );
+const { camelCaseDash } = require( './utils' );
+const config = require( './config' );
-/**
- * Converts @wordpress require into window reference
- *
- * Note this isn't the same as camel case because of the
- * way that numbers don't trigger the capitalized next letter
- *
- * @example
- * wordpressRequire( '@wordpress/api-fetch' ) = 'wp.apiFetch'
- * wordpressRequire( '@wordpress/i18n' ) = 'wp.i18n'
- *
- * @param {string} request import name
- * @return {string} global variable reference for import
- */
-const wordpressRequire = ( request ) => {
- // @wordpress/components -> [ @wordpress, components ]
- const [ , name ] = request.split( '/' );
-
- // components -> wp.components
- return `wp.${ name.replace( /-([a-z])/g, ( match, letter ) => letter.toUpperCase() ) }`;
-};
-
-const wordpressExternals = ( context, request, callback ) =>
- /^@wordpress\//.test( request ) ?
- callback( null, `root ${ wordpressRequire( request ) }` ) :
- callback();
-
-const externals = [
- {
- react: 'React',
- 'react-dom': 'ReactDOM',
- tinymce: 'tinymce',
- 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,
- output: {
- filename: './build/[basename]/index.js',
- path: process.cwd(),
- library: [ 'wp', '[name]' ],
- libraryTarget: 'this',
- },
- externals,
- resolve: {
- modules: [
- process.cwd(),
- 'node_modules',
- ],
- alias: {
- 'lodash-es': 'lodash',
- },
- },
- 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: [
- // 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,
- },
+module.exports = {
+ camelCaseDash,
+ config,
};
-
-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;
diff --git a/packages/webpack-config/package.json b/packages/webpack-config/package.json
index d87db2dade203f..c5ac5e8c452bcd 100644
--- a/packages/webpack-config/package.json
+++ b/packages/webpack-config/package.json
@@ -23,6 +23,8 @@
},
"main": "index.js",
"dependencies": {
+ "babel-loader": "^8.0.5",
+ "source-map-loader": "^0.2.4",
"webpack-bundle-analyzer": "^3.0.3",
"webpack-livereload-plugin": "^2.2.0"
},
diff --git a/packages/webpack-config/utils.js b/packages/webpack-config/utils.js
new file mode 100644
index 00000000000000..ea6ea3889c1ad8
--- /dev/null
+++ b/packages/webpack-config/utils.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/webpack.config.js b/webpack.config.js
index a57a176d0fc81f..a1c5c5f7726898 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -13,7 +13,7 @@ const { basename } = require( 'path' );
*/
const CustomTemplatedPathPlugin = require( '@wordpress/custom-templated-path-webpack-plugin' );
const LibraryExportDefaultPlugin = require( '@wordpress/library-export-default-webpack-plugin' );
-const webpackConfig = require( '@wordpress/webpack-config' );
+const { camelCaseDash, config } = require( '@wordpress/webpack-config' );
/**
* Internal dependencies
@@ -22,38 +22,28 @@ 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, '' ) );
-webpackConfig.entry = gutenbergPackages.reduce( ( memo, packageName ) => {
+config.entry = gutenbergPackages.reduce( ( memo, packageName ) => {
const name = camelCaseDash( packageName );
memo[ name ] = `./packages/${ packageName }`;
return memo;
}, {} );
-webpackConfig.plugins.push(
+config.output = {
+ filename: './build/[basename]/index.js',
+ path: __dirname,
+ library: [ 'wp', '[name]' ],
+ libraryTarget: 'this',
+};
+
+config.plugins.push(
// Create RTL files with a -rtl suffix
new WebpackRTLPlugin( {
suffix: '-rtl',
- minify: process.env.NODE_ENV === 'production' ? { safe: true } : false,
+ minify: config.mode === 'production' ? { safe: true } : false,
} ),
new CustomTemplatedPathPlugin( {
basename( path, data ) {
@@ -90,7 +80,7 @@ webpackConfig.plugins.push(
to: `./build/${ packageName }/`,
flatten: true,
transform: ( content ) => {
- if ( webpackConfig.mode === 'production' ) {
+ if ( config.mode === 'production' ) {
return postcss( [
require( 'cssnano' )( {
preset: [ 'default', {
@@ -109,4 +99,4 @@ webpackConfig.plugins.push(
)
);
-module.exports = webpackConfig;
+module.exports = config;