From 1a3b8cdcf334ff64ebeeadcb7bc5c528e7b580e5 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Mon, 8 May 2017 17:37:08 -0400 Subject: [PATCH 1/2] Document imports behavior --- docs/coding-guidelines.md | 47 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/docs/coding-guidelines.md b/docs/coding-guidelines.md index f271d8336da1e..fc06a5430f6d7 100644 --- a/docs/coding-guidelines.md +++ b/docs/coding-guidelines.md @@ -31,3 +31,50 @@ For optional variations of an element or its descendants, you may use a modifier In all of the above cases, except in separating the top-level element from its descendants, you **must** use dash delimiters when expressing multiple terms of a name. You may observe that these conventions adhere closely to the [BEM (Blocks, Elements, Modifiers)](http://getbem.com/introduction/) CSS methodology, with minor adjustments to the application of modifiers. + +## JavaScript + +### Imports + +In the Gutenberg project, we use [the ES2015 import syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) to enable us to create modular code with clear separations between code of a specific feature, code shared across distinct WordPress features, and third-party dependencies. + +These separations are identified by multi-line comments at the top of a file which imports code from another file or source. + +#### External Dependencies + +An external dependency is third-party code that is not maintained by WordPress contributors, but instead [included in WordPress as a default script](https://developer.wordpress.org/reference/functions/wp_enqueue_script/#default-scripts-included-and-registered-by-wordpress) or referenced from an outside package manager like [npm](https://www.npmjs.com/). + +Example: + +```js +/** + * External dependencies + */ +import TinyMCE from 'tinymce'; +``` + +#### WordPress Dependencies + +To encourage reusability between features, our JavaScript is split into domain-specific modules which [`export`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export) one or more functions or objects. In the Gutenberg project, we've distinguished these modules under top-level directories `blocks`, `components`, `editor`, `element`, and `i18n`. These each serve an independent purpose, and often code is shared between them. For example, in order to localize its text, editor code will need to include functions from the `i18n` module. + +Example: + +```js +/** + * WordPress dependencies + */ +import { __ } from 'i18n'; +``` + +#### Internal Dependencies + +Within a specific feature, code is organized into separate files and folders. As is the case with external and WordPress dependencies, you can bring this code into scope by using the `import` keyword. The main distinction here is that when importing internal files, you should use relative paths specific to top-level directory you're working in. + +Example: + +```js +/** + * Internal dependencies + */ +import VisualEditor from '../visual-editor'; +``` From 84575a0d8452cd0539486cf86ff27f0541543c27 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Mon, 8 May 2017 17:37:48 -0400 Subject: [PATCH 2/2] Resolve modules from project root directory --- blocks/components/editable/format-toolbar.js | 8 +++----- blocks/components/editable/index.js | 8 +++++--- blocks/library/button/index.js | 10 +++++++--- blocks/library/embed/index.js | 13 ++++++++----- blocks/library/freeform/index.js | 2 +- blocks/library/heading/index.js | 4 ++-- blocks/library/image/index.js | 13 ++++++++----- blocks/library/list/index.js | 4 ++-- blocks/library/pullquote/index.js | 4 ++-- blocks/library/quote/index.js | 4 ++-- blocks/library/separator/index.js | 2 +- blocks/library/text/index.js | 6 +++--- editor/components/block-mover/index.js | 2 +- editor/components/block-switcher/index.js | 2 +- editor/components/inserter/index.js | 2 +- editor/components/inserter/menu.js | 2 +- editor/components/toolbar/index.js | 2 +- editor/header/mode-switcher/index.js | 2 +- editor/header/tools/publish-button.js | 4 ++-- editor/layout/index.js | 8 ++++---- editor/modes/text-editor/index.js | 2 +- editor/modes/visual-editor/block.js | 6 +++--- editor/modes/visual-editor/index.js | 4 ++-- editor/state.js | 2 +- package.json | 1 - webpack.config.js | 6 ++++-- 26 files changed, 67 insertions(+), 56 deletions(-) diff --git a/blocks/components/editable/format-toolbar.js b/blocks/components/editable/format-toolbar.js index 467223a92f7aa..559dec1dd0dce 100644 --- a/blocks/components/editable/format-toolbar.js +++ b/blocks/components/editable/format-toolbar.js @@ -1,10 +1,8 @@ /** - * Internal dependencies + * WordPress dependencies */ - // TODO: We mustn't import by relative path traversing from blocks to editor - // as we're doing here; instead, we should consider a common components path. -import IconButton from '../../../editor/components/icon-button'; -import Toolbar from '../../../editor/components/toolbar'; +import IconButton from 'editor/components/icon-button'; +import Toolbar from 'editor/components/toolbar'; const FORMATTING_CONTROLS = [ { diff --git a/blocks/components/editable/index.js b/blocks/components/editable/index.js index 991e743060a00..8c25063256c70 100644 --- a/blocks/components/editable/index.js +++ b/blocks/components/editable/index.js @@ -7,15 +7,17 @@ import { nodeListToReact } from 'dom-react'; import { Fill } from 'react-slot-fill'; import 'element-closest'; +/** + * WordPress dependencies + */ +import Toolbar from 'editor/components/toolbar'; + /** * Internal dependencies */ import './style.scss'; import FormatToolbar from './format-toolbar'; import TinyMCE from './tinymce'; - // TODO: We mustn't import by relative path traversing from blocks to editor - // as we're doing here; instead, we should consider a common components path. -import Toolbar from '../../../editor/components/toolbar'; const KEYCODE_BACKSPACE = 8; diff --git a/blocks/library/button/index.js b/blocks/library/button/index.js index 0dc22cc14938e..e33fbb8049dc7 100644 --- a/blocks/library/button/index.js +++ b/blocks/library/button/index.js @@ -1,10 +1,14 @@ +/** + * WordPress dependencies + */ +import IconButton from 'editor/components/icon-button'; + /** * Internal dependencies */ import './style.scss'; -import { registerBlock, query } from 'api'; -import Editable from 'components/editable'; -import IconButton from '../../../editor/components/icon-button'; +import { registerBlock, query } from '../../api'; +import Editable from '../../components/editable'; const { attr, children } = query; diff --git a/blocks/library/embed/index.js b/blocks/library/embed/index.js index bd757a96a1d94..c028094335288 100644 --- a/blocks/library/embed/index.js +++ b/blocks/library/embed/index.js @@ -1,11 +1,14 @@ +/** + * WordPress dependencies + */ +import Dashicon from 'editor/components/dashicon'; +import Button from 'editor/components/button'; + /** * Internal dependencies */ -import { registerBlock, query } from 'api'; -import Editable from 'components/editable'; -// TODO: Revisit when we have a common components solution -import Dashicon from '../../../editor/components/dashicon'; -import Button from '../../../editor/components/button'; +import { registerBlock, query } from '../../api'; +import Editable from '../../components/editable'; const { attr, children } = query; diff --git a/blocks/library/freeform/index.js b/blocks/library/freeform/index.js index 6869417377fe1..be4f69fec5a86 100644 --- a/blocks/library/freeform/index.js +++ b/blocks/library/freeform/index.js @@ -1,7 +1,7 @@ /** * Internal dependencies */ -import { registerBlock, query, setUnknownTypeHandler } from 'api'; +import { registerBlock, query, setUnknownTypeHandler } from '../../api'; const { html } = query; diff --git a/blocks/library/heading/index.js b/blocks/library/heading/index.js index 0b121478265ea..94063f94458df 100644 --- a/blocks/library/heading/index.js +++ b/blocks/library/heading/index.js @@ -2,8 +2,8 @@ * Internal dependencies */ import './style.scss'; -import { registerBlock, query } from 'api'; -import Editable from 'components/editable'; +import { registerBlock, query } from '../../api'; +import Editable from '../../components/editable'; const { children, prop } = query; diff --git a/blocks/library/image/index.js b/blocks/library/image/index.js index a424f9cda0995..f21a9749fb528 100644 --- a/blocks/library/image/index.js +++ b/blocks/library/image/index.js @@ -1,12 +1,15 @@ +/** + * WordPress dependencies + */ +import Dashicon from 'editor/components/dashicon'; +import Button from 'editor/components/button'; + /** * Internal dependencies */ import './style.scss'; -import { registerBlock, query } from 'api'; -import Editable from 'components/editable'; -// TODO: Revisit when we have a common components solution -import Dashicon from '../../../editor/components/dashicon'; -import Button from '../../../editor/components/button'; +import { registerBlock, query } from '../../api'; +import Editable from '../../components/editable'; const { attr, children } = query; diff --git a/blocks/library/list/index.js b/blocks/library/list/index.js index a292a558d6ae0..38ee80081a010 100644 --- a/blocks/library/list/index.js +++ b/blocks/library/list/index.js @@ -2,8 +2,8 @@ * Internal dependencies */ import './style.scss'; -import { registerBlock, query as hpq } from 'api'; -import Editable from 'components/editable'; +import { registerBlock, query as hpq } from '../../api'; +import Editable from '../../components/editable'; const { children, prop } = hpq; diff --git a/blocks/library/pullquote/index.js b/blocks/library/pullquote/index.js index 52a7a76638cb7..0df3166174ca3 100644 --- a/blocks/library/pullquote/index.js +++ b/blocks/library/pullquote/index.js @@ -2,8 +2,8 @@ * Internal dependencies */ import './style.scss'; -import { registerBlock, query as hpq } from 'api'; -import Editable from 'components/editable'; +import { registerBlock, query as hpq } from '../../api'; +import Editable from '../../components/editable'; const { children, query } = hpq; diff --git a/blocks/library/quote/index.js b/blocks/library/quote/index.js index 690dfd7946d95..f3dbc9acae70e 100644 --- a/blocks/library/quote/index.js +++ b/blocks/library/quote/index.js @@ -2,8 +2,8 @@ * Internal dependencies */ import './style.scss'; -import { registerBlock, query as hpq } from 'api'; -import Editable from 'components/editable'; +import { registerBlock, query as hpq } from '../../api'; +import Editable from '../../components/editable'; const { children, query } = hpq; diff --git a/blocks/library/separator/index.js b/blocks/library/separator/index.js index 86c630f020cfa..b757caf97d0dd 100644 --- a/blocks/library/separator/index.js +++ b/blocks/library/separator/index.js @@ -2,7 +2,7 @@ * Internal dependencies */ import './style.scss'; -import { registerBlock } from 'api'; +import { registerBlock } from '../../api'; registerBlock( 'core/separator', { title: wp.i18n.__( 'Separator' ), diff --git a/blocks/library/text/index.js b/blocks/library/text/index.js index d788e81f2f24b..5ba3a76ae10b5 100644 --- a/blocks/library/text/index.js +++ b/blocks/library/text/index.js @@ -1,8 +1,8 @@ /** * Internal dependencies */ -import { registerBlock, query } from 'api'; -import Editable from 'components/editable'; +import { registerBlock, createBlock, query } from '../../api'; +import Editable from '../../components/editable'; const { children } = query; @@ -42,7 +42,7 @@ registerBlock( 'core/text', { onFocus={ setFocus } onSplit={ ( before, after ) => { setAttributes( { content: before } ); - insertBlockAfter( wp.blocks.createBlock( 'core/text', { + insertBlockAfter( createBlock( 'core/text', { content: after } ) ); } } diff --git a/editor/components/block-mover/index.js b/editor/components/block-mover/index.js index e872113855cc5..0282ff03104d6 100644 --- a/editor/components/block-mover/index.js +++ b/editor/components/block-mover/index.js @@ -8,7 +8,7 @@ import { first, last } from 'lodash'; * Internal dependencies */ import './style.scss'; -import IconButton from 'components/icon-button'; +import IconButton from '../icon-button'; function BlockMover( { onMoveUp, onMoveDown, isFirst, isLast } ) { return ( diff --git a/editor/components/block-switcher/index.js b/editor/components/block-switcher/index.js index e8a17163459b7..20546ce6eb7fc 100644 --- a/editor/components/block-switcher/index.js +++ b/editor/components/block-switcher/index.js @@ -9,7 +9,7 @@ import clickOutside from 'react-click-outside'; * Internal dependencies */ import './style.scss'; -import IconButton from 'components/icon-button'; +import IconButton from '../icon-button'; class BlockSwitcher extends wp.element.Component { constructor() { diff --git a/editor/components/inserter/index.js b/editor/components/inserter/index.js index 891ca84308c35..39e42b2a34e34 100644 --- a/editor/components/inserter/index.js +++ b/editor/components/inserter/index.js @@ -7,7 +7,7 @@ import clickOutside from 'react-click-outside'; * Internal dependencies */ import InserterMenu from './menu'; -import IconButton from 'components/icon-button'; +import IconButton from '../icon-button'; class Inserter extends wp.element.Component { constructor() { diff --git a/editor/components/inserter/menu.js b/editor/components/inserter/menu.js index 4de924cfd3705..d7e39465379bf 100644 --- a/editor/components/inserter/menu.js +++ b/editor/components/inserter/menu.js @@ -8,7 +8,7 @@ import { flow } from 'lodash'; * Internal dependencies */ import './style.scss'; -import Dashicon from 'components/dashicon'; +import Dashicon from '../dashicon'; class InserterMenu extends wp.element.Component { constructor() { diff --git a/editor/components/toolbar/index.js b/editor/components/toolbar/index.js index 698372d463f0d..c1c8f080a8c10 100644 --- a/editor/components/toolbar/index.js +++ b/editor/components/toolbar/index.js @@ -7,7 +7,7 @@ import classNames from 'classnames'; * Internal dependencies */ import './style.scss'; -import IconButton from 'components/icon-button'; +import IconButton from '../icon-button'; function Toolbar( { controls } ) { if ( ! controls || ! controls.length ) { diff --git a/editor/header/mode-switcher/index.js b/editor/header/mode-switcher/index.js index 0c4e0d893eb44..59985814db823 100644 --- a/editor/header/mode-switcher/index.js +++ b/editor/header/mode-switcher/index.js @@ -7,7 +7,7 @@ import { connect } from 'react-redux'; * Internal dependencies */ import './style.scss'; -import Dashicon from 'components/dashicon'; +import Dashicon from '../../components/dashicon'; /** * Set of available mode options. diff --git a/editor/header/tools/publish-button.js b/editor/header/tools/publish-button.js index 8ec6d2095e7d2..748dfd8b1997a 100644 --- a/editor/header/tools/publish-button.js +++ b/editor/header/tools/publish-button.js @@ -6,8 +6,8 @@ import { connect } from 'react-redux'; /** * Internal dependencies */ -import Button from 'components/button'; -import { savePost } from 'actions'; +import Button from '../../components/button'; +import { savePost } from '../../actions'; function PublishButton( { post, diff --git a/editor/layout/index.js b/editor/layout/index.js index 757ea78a89e22..17e90ae822ae3 100644 --- a/editor/layout/index.js +++ b/editor/layout/index.js @@ -8,10 +8,10 @@ import classnames from 'classnames'; * Internal dependencies */ import './style.scss'; -import Header from 'header'; -import Sidebar from 'sidebar'; -import TextEditor from 'modes/text-editor'; -import VisualEditor from 'modes/visual-editor'; +import Header from '../header'; +import Sidebar from '../sidebar'; +import TextEditor from '../modes/text-editor'; +import VisualEditor from '../modes/visual-editor'; function Layout( { mode, isSidebarOpened } ) { const className = classnames( 'editor-layout', { diff --git a/editor/modes/text-editor/index.js b/editor/modes/text-editor/index.js index 86ae4735a86e7..9aeb94ed26d21 100644 --- a/editor/modes/text-editor/index.js +++ b/editor/modes/text-editor/index.js @@ -8,7 +8,7 @@ import Textarea from 'react-autosize-textarea'; * Internal dependencies */ import './style.scss'; -import PostTitle from 'post-title'; +import PostTitle from '../../post-title'; function TextEditor( { blocks, onChange } ) { return ( diff --git a/editor/modes/visual-editor/block.js b/editor/modes/visual-editor/block.js index bf28af782ab17..4dfc13429d074 100644 --- a/editor/modes/visual-editor/block.js +++ b/editor/modes/visual-editor/block.js @@ -9,9 +9,9 @@ import { partial } from 'lodash'; /** * Internal dependencies */ -import Toolbar from 'components/toolbar'; -import BlockMover from 'components/block-mover'; -import BlockSwitcher from 'components/block-switcher'; +import Toolbar from '../../components/toolbar'; +import BlockMover from '../../components/block-mover'; +import BlockSwitcher from '../../components/block-switcher'; class VisualEditorBlock extends wp.element.Component { constructor() { diff --git a/editor/modes/visual-editor/index.js b/editor/modes/visual-editor/index.js index 35e57b9fb9514..d9919e63fd4de 100644 --- a/editor/modes/visual-editor/index.js +++ b/editor/modes/visual-editor/index.js @@ -7,9 +7,9 @@ import { connect } from 'react-redux'; * Internal dependencies */ import './style.scss'; -import Inserter from 'components/inserter'; +import Inserter from '../../components/inserter'; import VisualEditorBlock from './block'; -import PostTitle from 'post-title'; +import PostTitle from '../../post-title'; function VisualEditor( { blocks } ) { return ( diff --git a/editor/state.js b/editor/state.js index a3935bf5f6351..c2e76efddd1e1 100644 --- a/editor/state.js +++ b/editor/state.js @@ -7,7 +7,7 @@ import { keyBy, last, omit, without } from 'lodash'; /** * Internal dependencies */ -import { combineUndoableReducers } from 'utils/undoable-reducer'; +import { combineUndoableReducers } from './utils/undoable-reducer'; /** * Undoable reducer returning the editor post state, including blocks parsed diff --git a/package.json b/package.json index cf3d4f11e2be6..ceb40c5f19321 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,6 @@ "pegjs-loader": "^0.5.1", "postcss-loader": "^1.3.3", "raw-loader": "^0.5.1", - "resolve-entry-modules-webpack-plugin": "^1.0.0", "sass-loader": "^6.0.3", "sinon": "^2.1.0", "sinon-chai": "^2.9.0", diff --git a/webpack.config.js b/webpack.config.js index 352778f3eedfc..44940b9befd26 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -5,7 +5,6 @@ const glob = require( 'glob' ); const webpack = require( 'webpack' ); const ExtractTextPlugin = require( 'extract-text-webpack-plugin' ); -const ResolveEntryModulesPlugin = require( 'resolve-entry-modules-webpack-plugin' ); const config = { entry: { @@ -26,6 +25,10 @@ const config = { 'react-dom/server': 'ReactDOMServer' }, resolve: { + modules: [ + __dirname, + 'node_modules' + ], alias: { // There are currently resolution errors on RSF's "mitt" dependency // when imported as native ES module @@ -64,7 +67,6 @@ const config = { ] }, plugins: [ - new ResolveEntryModulesPlugin(), new ExtractTextPlugin( { filename: './[name]/build/style.css' } ),