Skip to content

Module and import strategy #941

@nylen

Description

@nylen

We need to give some thought to the way we offer our code to be consumed by various pieces of software:

  1. within Gutenberg itself
  2. within other parts of WordPress, especially given that we will eventually be integrating Webpack into more places
  3. in plugins, which may or may not use any kind of JS build tooling.

Previously, we were duplicating a lot of code in our built files - in particular, things in components are duplicated across blocks/build/index.js and editor/build/index.js. Some details at #929 (comment).

Current status

#929 addressed this particular concern by de-duplicating our Webpack build and making all of our exported code available via global variables like wp.components.Button for example. We can still use import in our ES6 code here (and in other projects that use Webpack). This is the approach I would recommend, at least for now, because it allows us to support all of the 3 goals above pretty transparently.

In order to avoid this duplication going forward, this implies that any import statement in a WordPress dependencies block needs to have the following form:

/**
 * WordPress dependencies
 */
import { Button, withFocusReturn } from 'components';

(note, components corresponds directly to wp.components, and there is no path associated with the components directory).

Concerns

@youknowriad raised the concern that it would be nice to import higher-order components differently:

import { withFocusReturn } from 'components/higher-order';

After #929 this would cause withFocusReturn to be included in the blocks build (if this import was performed from within the blocks code), and it would be duplicated across multiple builds if imported this way in multiple builds.

Alternatives and Next Steps

I'm not aware of a clean Webpack configuration that addresses this issue, and I'm not sure if we would want to do that anyway (requiring imports from only the top level of other builds seems nice and clean to me).

An alternative would be to drop the import statement, recognizing that we are actually playing inside a large ecosystem that needs to make its code available for various uses other than ES6 modules compiled within the same Webpack build:

/**
 * WordPress dependencies
 */
const { Button } = wp.components;
const { withFocusReturn } = wp.components.higherOrder;

Whatever we choose here, we should probably also create some lint rules to ensure consistency.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions