From 596372a4d9b8acc8f6ca9a3b9ca5d1e6619076d7 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Fri, 2 Feb 2018 15:30:35 -0500 Subject: [PATCH] Framework: Per-block script bundles --- .../raw-handling/test/integration/index.js | 4 +- blocks/index.js | 1 - blocks/library/index.js | 91 ------------------- blocks/library/paragraph/index.js | 14 ++- blocks/library/paragraph/index.php | 16 ++++ blocks/test/full-content.js | 4 +- .../components/document-outline/test/index.js | 4 +- editor/store/test/reducer.js | 3 +- editor/store/test/selectors.js | 4 +- lib/client-assets.php | 43 +++++---- test/unit/setup-wp-aliases.js | 2 +- webpack.config.js | 16 +++- 12 files changed, 68 insertions(+), 134 deletions(-) delete mode 100644 blocks/library/index.js create mode 100644 blocks/library/paragraph/index.php diff --git a/blocks/api/raw-handling/test/integration/index.js b/blocks/api/raw-handling/test/integration/index.js index 5ac2086d3568c..a074dabc515f8 100644 --- a/blocks/api/raw-handling/test/integration/index.js +++ b/blocks/api/raw-handling/test/integration/index.js @@ -8,7 +8,6 @@ import path from 'path'; /** * Internal dependencies */ -import { registerCoreBlocks } from '../../../../library'; import rawHandler from '../../index'; import serialize from '../../../serializer'; @@ -24,7 +23,8 @@ describe( 'raw handling: integration', () => { beforeAll( () => { // Load all hooks that modify blocks require( 'blocks/hooks' ); - registerCoreBlocks(); + + // TODO: Need to load/register core blocks. Maybe requireIndex ? } ); types.forEach( ( type ) => { diff --git a/blocks/index.js b/blocks/index.js index 4ef35d2d54ab4..626424cc8bdba 100644 --- a/blocks/index.js +++ b/blocks/index.js @@ -13,7 +13,6 @@ import './hooks'; // Blocks are inferred from the HTML source of a post through a parsing mechanism // and then stored as objects in state, from which it is then rendered for editing. export * from './api'; -export { registerCoreBlocks } from './library'; export { default as AlignmentToolbar } from './alignment-toolbar'; export { default as BlockAlignmentToolbar } from './block-alignment-toolbar'; export { default as BlockControls } from './block-controls'; diff --git a/blocks/library/index.js b/blocks/library/index.js deleted file mode 100644 index 17e7534aa35cd..0000000000000 --- a/blocks/library/index.js +++ /dev/null @@ -1,91 +0,0 @@ -/** - * Internal dependencies - */ -import { - registerBlockType, - setDefaultBlockName, - setUnknownTypeHandlerName, -} from '../api'; -import * as audio from './audio'; -import * as button from './button'; -import * as categories from './categories'; -import * as code from './code'; -import * as coverImage from './cover-image'; -import * as embed from './embed'; -import * as freeform from './freeform'; -import * as gallery from './gallery'; -import * as heading from './heading'; -import * as html from './html'; -import * as image from './image'; -import * as latestPosts from './latest-posts'; -import * as list from './list'; -import * as more from './more'; -import * as paragraph from './paragraph'; -import * as preformatted from './preformatted'; -import * as pullquote from './pullquote'; -import * as quote from './quote'; -import * as reusableBlock from './block'; -import * as separator from './separator'; -import * as shortcode from './shortcode'; -import * as subhead from './subhead'; -import * as table from './table'; -import * as textColumns from './text-columns'; -import * as verse from './verse'; -import * as video from './video'; - -export const registerCoreBlocks = () => { - [ - // FIXME: Temporary fix. - // - // The Shortcode block declares a catch-all shortcode transform, - // meaning it will attempt to intercept pastes and block conversions of - // any valid shortcode-like content. Other blocks (e.g. Gallery) may - // declare specific shortcode transforms (e.g. `[gallery]`), with which - // this block would conflict. Thus, the Shortcode block needs to be - // registered as early as possible, so that any other block types' - // shortcode transforms can be honoured. - // - // This isn't a proper solution, as it is at odds with the - // specification of shortcode conversion, in the sense that conversion - // is explicitly independent of block order. Thus, concurrent parse - // rules (i.e. a same text input can yield two different transforms, - // like `[gallery] -> { Gallery, Shortcode }`) are unsupported, - // yielding non-deterministic results. A proper solution could be to - // let the editor (or site owners) determine a default block handler of - // unknown shortcodes — see `setUnknownTypeHandlerName`. - shortcode, - - audio, - button, - categories, - code, - coverImage, - embed, - ...embed.common, - ...embed.others, - freeform, - gallery, - heading, - html, - image, - list, - latestPosts, - more, - paragraph, - preformatted, - pullquote, - quote, - reusableBlock, - separator, - subhead, - table, - textColumns, - verse, - video, - ].forEach( ( { name, settings } ) => { - registerBlockType( name, settings ); - } ); - - setDefaultBlockName( paragraph.name ); - setUnknownTypeHandlerName( freeform.name ); -}; diff --git a/blocks/library/paragraph/index.js b/blocks/library/paragraph/index.js index 396a8ee59dd6e..96aaca734f749 100644 --- a/blocks/library/paragraph/index.js +++ b/blocks/library/paragraph/index.js @@ -7,6 +7,11 @@ import classnames from 'classnames'; * WordPress dependencies */ import { __ } from '@wordpress/i18n'; +import { + createBlock, + registerBlockType, + setDefaultBlockName, +} from '@wordpress/blocks'; import { concatChildren, Component } from '@wordpress/element'; import { Autocomplete, PanelBody, PanelColor, withFallbackStyles } from '@wordpress/components'; @@ -15,7 +20,6 @@ import { Autocomplete, PanelBody, PanelColor, withFallbackStyles } from '@wordpr */ import './editor.scss'; import './style.scss'; -import { createBlock } from '../../api'; import { blockAutocompleter, userAutocompleter } from '../../autocompleters'; import AlignmentToolbar from '../../alignment-toolbar'; import BlockAlignmentToolbar from '../../block-alignment-toolbar'; @@ -192,9 +196,7 @@ class ParagraphBlock extends Component { } } -export const name = 'core/paragraph'; - -export const settings = { +registerBlockType( 'core/paragraph', { title: __( 'Paragraph' ), description: __( 'This is a simple text only block for adding a single paragraph of content.' ), @@ -283,4 +285,6 @@ export const settings = { return

{ content }

; }, -}; +} ); + +setDefaultBlockName( 'core/paragraph' ); diff --git a/blocks/library/paragraph/index.php b/blocks/library/paragraph/index.php new file mode 100644 index 0000000000000..521aceaede7d7 --- /dev/null +++ b/blocks/library/paragraph/index.php @@ -0,0 +1,16 @@ + 'core-paragraph-block', + ) ); +} + +add_action( 'init', 'register_core_paragraph_block' ); diff --git a/blocks/test/full-content.js b/blocks/test/full-content.js index be355e6d242a3..c038d09891312 100644 --- a/blocks/test/full-content.js +++ b/blocks/test/full-content.js @@ -9,7 +9,6 @@ import { format } from 'util'; /** * Internal dependencies */ -import { registerCoreBlocks } from '../library'; import parse from '../api/parser'; import { parse as grammarParse } from '../api/post.pegjs'; import serialize from '../api/serializer'; @@ -94,7 +93,8 @@ describe( 'full post content fixture', () => { // Load all hooks that modify blocks require( 'blocks/hooks' ); - registerCoreBlocks(); + + // TODO: Need to load/register core blocks. Maybe requireIndex ? } ); fileBasenames.forEach( f => { diff --git a/editor/components/document-outline/test/index.js b/editor/components/document-outline/test/index.js index a38c04c147381..561310fc7c456 100644 --- a/editor/components/document-outline/test/index.js +++ b/editor/components/document-outline/test/index.js @@ -6,7 +6,7 @@ import { shallow } from 'enzyme'; /** * WordPress dependencies */ -import { createBlock, registerCoreBlocks } from '@wordpress/blocks'; +import { createBlock } from '@wordpress/blocks'; /** * Internal dependencies @@ -14,7 +14,7 @@ import { createBlock, registerCoreBlocks } from '@wordpress/blocks'; import { DocumentOutline } from '../'; describe( 'DocumentOutline', () => { - registerCoreBlocks(); + // TODO: Need to load/register core blocks. Maybe requireIndex ? const paragraph = createBlock( 'core/paragraph' ); const headingH1 = createBlock( 'core/heading', { diff --git a/editor/store/test/reducer.js b/editor/store/test/reducer.js index fd53c7a4a5795..7602655d0c961 100644 --- a/editor/store/test/reducer.js +++ b/editor/store/test/reducer.js @@ -8,7 +8,6 @@ import deepFreeze from 'deep-freeze'; * WordPress dependencies */ import { - registerCoreBlocks, registerBlockType, unregisterBlockType, } from '@wordpress/blocks'; @@ -958,7 +957,7 @@ describe( 'state', () => { describe( 'preferences()', () => { beforeAll( () => { - registerCoreBlocks(); + // TODO: Need to load/register core blocks (or at least some demo blocks). Maybe requireIndex ? } ); it( 'should apply all defaults', () => { diff --git a/editor/store/test/selectors.js b/editor/store/test/selectors.js index cebb550803b33..e9c92e5efbe64 100644 --- a/editor/store/test/selectors.js +++ b/editor/store/test/selectors.js @@ -8,7 +8,7 @@ import { union } from 'lodash'; * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { registerBlockType, unregisterBlockType, registerCoreBlocks, getBlockTypes } from '@wordpress/blocks'; +import { registerBlockType, unregisterBlockType, getBlockTypes } from '@wordpress/blocks'; /** * Internal dependencies @@ -1949,7 +1949,7 @@ describe( 'selectors', () => { describe( 'getRecentInserterItems', () => { beforeAll( () => { - registerCoreBlocks(); + // TODO: Need to load/register core blocks (or at least some demo blocks). Maybe requireIndex ? } ); it( 'should return the 8 most recently used blocks', () => { diff --git a/lib/client-assets.php b/lib/client-assets.php index 041adf545b0d0..e4f34c95da56d 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -78,27 +78,27 @@ function gutenberg_register_scripts_and_styles() { // Editor Scripts. wp_register_script( 'wp-data', - gutenberg_url( 'data/build/index.js' ), + gutenberg_url( 'build/data.js' ), array( 'wp-element' ), - filemtime( gutenberg_dir_path() . 'data/build/index.js' ) + filemtime( gutenberg_dir_path() . 'build/data.js' ) ); wp_register_script( 'wp-utils', - gutenberg_url( 'utils/build/index.js' ), + gutenberg_url( 'build/utils.js' ), array(), - filemtime( gutenberg_dir_path() . 'utils/build/index.js' ) + filemtime( gutenberg_dir_path() . 'build/utils.js' ) ); wp_register_script( 'wp-hooks', - gutenberg_url( 'hooks/build/index.js' ), + gutenberg_url( 'build/hooks.js' ), array(), - filemtime( gutenberg_dir_path() . 'hooks/build/index.js' ) + filemtime( gutenberg_dir_path() . 'build/hooks.js' ) ); wp_register_script( 'wp-date', - gutenberg_url( 'date/build/index.js' ), + gutenberg_url( 'build/date.js' ), array( 'moment' ), - filemtime( gutenberg_dir_path() . 'date/build/index.js' ) + filemtime( gutenberg_dir_path() . 'build/date.js' ) ); global $wp_locale; wp_add_inline_script( 'wp-date', 'window._wpDateSettings = ' . wp_json_encode( array( @@ -128,27 +128,27 @@ function gutenberg_register_scripts_and_styles() { ) ), 'before' ); wp_register_script( 'wp-i18n', - gutenberg_url( 'i18n/build/index.js' ), + gutenberg_url( 'build/i18n.js' ), array(), - filemtime( gutenberg_dir_path() . 'i18n/build/index.js' ) + filemtime( gutenberg_dir_path() . 'build/i18n.js' ) ); wp_register_script( 'wp-element', - gutenberg_url( 'element/build/index.js' ), + gutenberg_url( 'build/element.js' ), array( 'react', 'react-dom', 'react-dom-server' ), - filemtime( gutenberg_dir_path() . 'element/build/index.js' ) + filemtime( gutenberg_dir_path() . 'build/element.js' ) ); wp_register_script( 'wp-components', - gutenberg_url( 'components/build/index.js' ), + gutenberg_url( 'build/components.js' ), array( 'wp-element', 'wp-i18n', 'wp-utils', 'wp-hooks', 'wp-api-request', 'moment' ), - filemtime( gutenberg_dir_path() . 'components/build/index.js' ) + filemtime( gutenberg_dir_path() . 'build/components.js' ) ); wp_register_script( 'wp-blocks', - gutenberg_url( 'blocks/build/index.js' ), + gutenberg_url( 'build/blocks.js' ), array( 'wp-element', 'wp-components', 'wp-utils', 'wp-hooks', 'wp-i18n', 'tinymce-latest', 'tinymce-latest-lists', 'tinymce-latest-paste', 'tinymce-latest-table', 'media-views', 'media-models', 'shortcode' ), - filemtime( gutenberg_dir_path() . 'blocks/build/index.js' ) + filemtime( gutenberg_dir_path() . 'build/blocks.js' ) ); wp_add_inline_script( 'wp-blocks', @@ -161,16 +161,16 @@ function gutenberg_register_scripts_and_styles() { wp_register_script( 'wp-editor', - gutenberg_url( 'editor/build/index.js' ), + gutenberg_url( 'build/editor.js' ), array( 'postbox', 'jquery', 'wp-api', 'wp-data', 'wp-date', 'wp-i18n', 'wp-blocks', 'wp-element', 'wp-components', 'wp-utils', 'word-count', 'editor' ), - filemtime( gutenberg_dir_path() . 'editor/build/index.js' ) + filemtime( gutenberg_dir_path() . 'build/editor.js' ) ); wp_register_script( 'wp-edit-post', - gutenberg_url( 'edit-post/build/index.js' ), + gutenberg_url( 'build/editPost.js' ), array( 'jquery', 'heartbeat', 'wp-element', 'wp-components', 'wp-editor', 'wp-i18n', 'wp-date', 'wp-utils', 'wp-data' ), - filemtime( gutenberg_dir_path() . 'edit-post/build/index.js' ), + filemtime( gutenberg_dir_path() . 'build/editPost.js' ), true ); @@ -897,8 +897,7 @@ function gutenberg_editor_scripts_and_styles( $hook ) { $script .= sprintf( 'var editorSettings = %s;', wp_json_encode( $editor_settings ) ); $script .= << { Object.defineProperty( global.wp, entryPointName, { get: () => require( entryPointName ), diff --git a/webpack.config.js b/webpack.config.js index b886aa80bcdb2..50719351e5856 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -4,6 +4,8 @@ const webpack = require( 'webpack' ); const ExtractTextPlugin = require( 'extract-text-webpack-plugin' ); const WebpackRTLPlugin = require( 'webpack-rtl-plugin' ); +const fs = require( 'fs' ); +const { camelCase, castArray } = require( 'lodash' ); // Main CSS loader for everything but blocks.. const mainCSSExtractTextPlugin = new ExtractTextPlugin( { @@ -53,7 +55,11 @@ const entryPointNames = [ 'i18n', 'utils', 'data', - 'edit-post', + [ 'editPost', 'edit-post' ], + ...fs.readdirSync( './blocks/library' ).map( ( block ) => [ + '__block_' + camelCase( block ), + 'blocks/library/' + block, + ] ), ]; const packageNames = [ @@ -77,8 +83,10 @@ const externals = { const config = { entry: Object.assign( - entryPointNames.reduce( ( memo, entryPointName ) => { - memo[ entryPointName ] = `./${ entryPointName }/index.js`; + entryPointNames.reduce( ( memo, entryPoint ) => { + entryPoint = castArray( entryPoint ); + const [ name, path = name ] = entryPoint; + memo[ name ] = `./${ path }/index.js`; return memo; }, {} ), packageNames.reduce( ( memo, packageName ) => { @@ -87,7 +95,7 @@ const config = { }, {} ) ), output: { - filename: '[name]/build/index.js', + filename: 'build/[name].js', path: __dirname, library: [ 'wp', '[name]' ], libraryTarget: 'this',