mirror of
https://github.com/gosticks/wordpress-develop.git
synced 2025-10-16 12:05:38 +00:00
It aligns with the changes proposed added in Gutenberg: https://github.com/WordPress/gutenberg/pull/33293. The idea here is to split the growing webpack config into two parts: blocks and packages. We need to add handling for JavaScript files that are going to be used with blocks on the frontend. They didn't work quite well with the current setup for entry points created for packages. As part of the effort, it adds support for `viewScript` in `block.json` metadata file that is later translated to `$view_script` in `WP_Block_Type` class and exposed as `view_script` from the REST API endpoint for block types. Props youknowriad, desrosj, aristath. Fixes #53690. git-svn-id: https://develop.svn.wordpress.org/trunk@51501 602fd350-edb4-49c9-b593-d223f7449a82
276 lines
8.3 KiB
JavaScript
276 lines
8.3 KiB
JavaScript
/**
|
|
* External dependencies
|
|
*/
|
|
const { DefinePlugin } = require( 'webpack' );
|
|
const CopyWebpackPlugin = require( 'copy-webpack-plugin' );
|
|
const LiveReloadPlugin = require( 'webpack-livereload-plugin' );
|
|
const postcss = require( 'postcss' );
|
|
const UglifyJS = require( 'uglify-js' );
|
|
|
|
const { join, basename } = require( 'path' );
|
|
const { get } = require( 'lodash' );
|
|
|
|
/**
|
|
* WordPress dependencies
|
|
*/
|
|
const CustomTemplatedPathPlugin = require( '@wordpress/custom-templated-path-webpack-plugin' );
|
|
const DependencyExtractionPlugin = require( '@wordpress/dependency-extraction-webpack-plugin' );
|
|
const LibraryExportDefaultPlugin = require( '@wordpress/library-export-default-webpack-plugin' );
|
|
|
|
/**
|
|
* Internal dependencies
|
|
*/
|
|
const { dependencies } = require( '../../package' );
|
|
|
|
const baseDir = join( __dirname, '../../' );
|
|
|
|
/**
|
|
* Given a string, returns a new string with dash separators converedd to
|
|
* camel-case equivalent. This is not as aggressive as `_.camelCase` in
|
|
* converting to uppercase, where Lodash will convert 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()
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Maps vendors to copy commands for the CopyWebpackPlugin.
|
|
*
|
|
* @param {Object} vendors Vendors to include in the vendor folder.
|
|
* @param {string} buildTarget The folder in which to build the packages.
|
|
*
|
|
* @return {Object[]} Copy object suitable for the CopyWebpackPlugin.
|
|
*/
|
|
function mapVendorCopies( vendors, buildTarget ) {
|
|
return Object.keys( vendors ).map( ( filename ) => ( {
|
|
from: join( baseDir, `node_modules/${ vendors[ filename ] }` ),
|
|
to: join( baseDir, `${ buildTarget }/js/dist/vendor/${ filename }` ),
|
|
} ) );
|
|
}
|
|
|
|
module.exports = function( env = { environment: 'production', watch: false, buildTarget: false } ) {
|
|
const mode = env.environment;
|
|
const suffix = mode === 'production' ? '.min' : '';
|
|
let buildTarget = env.buildTarget ? env.buildTarget : ( mode === 'production' ? 'build' : 'src' );
|
|
buildTarget = buildTarget + '/wp-includes';
|
|
|
|
const WORDPRESS_NAMESPACE = '@wordpress/';
|
|
const BUNDLED_PACKAGES = [ '@wordpress/icons', '@wordpress/interface' ];
|
|
const packages = Object.keys( dependencies )
|
|
.filter( ( packageName ) =>
|
|
! BUNDLED_PACKAGES.includes( packageName ) &&
|
|
packageName.startsWith( WORDPRESS_NAMESPACE )
|
|
)
|
|
.map( ( packageName ) => packageName.replace( WORDPRESS_NAMESPACE, '' ) );
|
|
|
|
const vendors = {
|
|
'lodash.js': 'lodash/lodash.js',
|
|
'wp-polyfill.js': '@wordpress/babel-preset-default/build/polyfill.js',
|
|
'wp-polyfill-fetch.js': 'whatwg-fetch/dist/fetch.umd.js',
|
|
'wp-polyfill-element-closest.js': 'element-closest/element-closest.js',
|
|
'wp-polyfill-node-contains.js': 'polyfill-library/polyfills/__dist/Node.prototype.contains/raw.js',
|
|
'wp-polyfill-url.js': 'core-js-url-browser/url.js',
|
|
'wp-polyfill-dom-rect.js': 'polyfill-library/polyfills/__dist/DOMRect/raw.js',
|
|
'wp-polyfill-formdata.js': 'formdata-polyfill/FormData.js',
|
|
'wp-polyfill-object-fit.js': 'objectFitPolyfill/src/objectFitPolyfill.js',
|
|
'moment.js': 'moment/moment.js',
|
|
'react.js': 'react/umd/react.development.js',
|
|
'react-dom.js': 'react-dom/umd/react-dom.development.js',
|
|
'regenerator-runtime.js': 'regenerator-runtime/runtime.js',
|
|
};
|
|
|
|
const minifiedVendors = {
|
|
'lodash.min.js': 'lodash/lodash.min.js',
|
|
'wp-polyfill.min.js': '@wordpress/babel-preset-default/build/polyfill.min.js',
|
|
'wp-polyfill-formdata.min.js': 'formdata-polyfill/formdata.min.js',
|
|
'wp-polyfill-url.min.js': 'core-js-url-browser/url.min.js',
|
|
'wp-polyfill-object-fit.min.js': 'objectFitPolyfill/dist/objectFitPolyfill.min.js',
|
|
'moment.min.js': 'moment/min/moment.min.js',
|
|
'react.min.js': 'react/umd/react.production.min.js',
|
|
'react-dom.min.js': 'react-dom/umd/react-dom.production.min.js',
|
|
};
|
|
|
|
const minifyVendors = {
|
|
'regenerator-runtime.min.js': 'regenerator-runtime/runtime.js',
|
|
'wp-polyfill-fetch.min.js': 'whatwg-fetch/dist/fetch.umd.js',
|
|
'wp-polyfill-element-closest.min.js': 'element-closest/element-closest.js',
|
|
'wp-polyfill-node-contains.min.js': 'polyfill-library/polyfills/__dist/Node.prototype.contains/raw.js',
|
|
'wp-polyfill-dom-rect.min.js': 'polyfill-library/polyfills/__dist/DOMRect/raw.js',
|
|
};
|
|
|
|
const phpFiles = {
|
|
'block-serialization-default-parser/parser.php': 'wp-includes/class-wp-block-parser.php',
|
|
};
|
|
|
|
const developmentCopies = mapVendorCopies( vendors, buildTarget );
|
|
const minifiedCopies = mapVendorCopies( minifiedVendors, buildTarget );
|
|
const minifyCopies = mapVendorCopies( minifyVendors, buildTarget ).map( ( copyCommand ) => {
|
|
return {
|
|
...copyCommand,
|
|
transform: ( content ) => {
|
|
return UglifyJS.minify( content.toString() ).code;
|
|
},
|
|
};
|
|
} );
|
|
|
|
let vendorCopies = mode === "development" ? developmentCopies : [ ...minifiedCopies, ...minifyCopies ];
|
|
|
|
let cssCopies = packages.map( ( packageName ) => ( {
|
|
from: join( baseDir, `node_modules/@wordpress/${ packageName }/build-style/*.css` ),
|
|
to: join( baseDir, `${ buildTarget }/css/dist/${ packageName }/` ),
|
|
flatten: true,
|
|
transform: ( content ) => {
|
|
if ( mode === 'production' ) {
|
|
return postcss( [
|
|
require( 'cssnano' )( {
|
|
preset: 'default',
|
|
} ),
|
|
] )
|
|
.process( content, { from: 'src/app.css', to: 'dest/app.css' } )
|
|
.then( ( result ) => result.css );
|
|
}
|
|
|
|
return content;
|
|
},
|
|
transformPath: ( targetPath, sourcePath ) => {
|
|
if ( mode === 'production' ) {
|
|
return targetPath.replace( /\.css$/, '.min.css' );
|
|
}
|
|
|
|
return targetPath;
|
|
}
|
|
} ) );
|
|
|
|
const phpCopies = Object.keys( phpFiles ).map( ( filename ) => ( {
|
|
from: join( baseDir, `node_modules/@wordpress/${ filename }` ),
|
|
to: join( baseDir, `src/${ phpFiles[ filename ] }` ),
|
|
} ) );
|
|
|
|
const config = {
|
|
mode,
|
|
|
|
entry: packages.reduce( ( memo, packageName ) => {
|
|
const name = camelCaseDash( packageName );
|
|
memo[ name ] = join( baseDir, `node_modules/@wordpress/${ packageName }` );
|
|
return memo;
|
|
}, {} ),
|
|
output: {
|
|
devtoolNamespace: 'wp',
|
|
filename: `[basename]${ suffix }.js`,
|
|
path: join( baseDir, `${ buildTarget }/js/dist` ),
|
|
library: {
|
|
root: [ 'wp', '[name]' ]
|
|
},
|
|
libraryTarget: 'this',
|
|
},
|
|
resolve: {
|
|
modules: [
|
|
baseDir,
|
|
'node_modules',
|
|
],
|
|
alias: {
|
|
'lodash-es': 'lodash',
|
|
},
|
|
},
|
|
module: {
|
|
rules: [
|
|
{
|
|
test: /\.js$/,
|
|
use: [ 'source-map-loader' ],
|
|
enforce: 'pre',
|
|
},
|
|
],
|
|
},
|
|
optimization: {
|
|
moduleIds: mode === 'production' ? 'hashed' : 'named',
|
|
},
|
|
plugins: [
|
|
new DefinePlugin( {
|
|
// Inject the `GUTENBERG_PHASE` global, used for feature flagging.
|
|
'process.env.GUTENBERG_PHASE': 1,
|
|
// Inject the `COMPONENT_SYSTEM_PHASE` global, used for controlling Component System roll-out.
|
|
'process.env.COMPONENT_SYSTEM_PHASE': 0,
|
|
'process.env.FORCE_REDUCED_MOTION': JSON.stringify(
|
|
process.env.FORCE_REDUCED_MOTION
|
|
),
|
|
} ),
|
|
new LibraryExportDefaultPlugin( [
|
|
'api-fetch',
|
|
'deprecated',
|
|
'dom-ready',
|
|
'redux-routine',
|
|
'token-list',
|
|
'server-side-render',
|
|
'shortcode',
|
|
'warning',
|
|
].map( camelCaseDash ) ),
|
|
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;
|
|
},
|
|
} ),
|
|
new DependencyExtractionPlugin( {
|
|
injectPolyfill: true,
|
|
combineAssets: true,
|
|
combinedOutputFile: '../../assets/script-loader-packages.php',
|
|
} ),
|
|
new CopyWebpackPlugin(
|
|
[
|
|
...vendorCopies,
|
|
...cssCopies,
|
|
...phpCopies,
|
|
],
|
|
),
|
|
],
|
|
stats: {
|
|
children: false,
|
|
},
|
|
|
|
watch: env.watch,
|
|
};
|
|
|
|
if ( config.mode !== 'production' ) {
|
|
config.devtool = process.env.SOURCEMAP || 'source-map';
|
|
}
|
|
|
|
if ( mode === 'development' && env.buildTarget === 'build/' ) {
|
|
delete config.devtool;
|
|
config.mode = 'production';
|
|
config.optimization = {
|
|
minimize: false,
|
|
moduleIds: 'hashed',
|
|
};
|
|
}
|
|
|
|
if ( config.mode === 'development' ) {
|
|
config.plugins.push( new LiveReloadPlugin( { port: process.env.WORDPRESS_LIVE_RELOAD_PORT || 35729 } ) );
|
|
}
|
|
|
|
return config;
|
|
};
|