Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure Content Block views are always loaded #1018

Merged
merged 1 commit into from
Apr 10, 2019
Merged

Ensure Content Block views are always loaded #1018

merged 1 commit into from
Apr 10, 2019

Conversation

jesstelford
Copy link
Contributor

Previous behaviour was to rely on manually importing a block for it to
be included (eg; unordered-list imports the list-item block). While
this is currently always the case, it doesn't necessarily have to be.

One example might be a 3rd party block which wants to create
heading+subheading pair, and set a dependency on the heading block
without ever importing it (instead; referencing it by its type name from
within the 3rd party block).

By surfacing the type on the server / during webpack build we're able to
do a couple more checks such as for duplicates and also replace the
sparse config array with a keyed object.

Finally, we can pull up the default paragraph block into the pre-build
step and remove that logic from the client code, making it a bit
cleaner.

// Add the blocks config to the views object for usage in the admin UI
// (ie; { Cell: , Field: , Filters: , blocks: ...})
extendViews(views) {
return {
...views,
blocks: this.blocks.map(block => (Array.isArray(block) ? block[0] : block).viewPath),
blocks: unique(
flatMap(this.blocks, block => flattenBlockViews(Array.isArray(block) ? block[0] : block))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensuring all the dependency's views are included in this list so they're always bundled even if they're not imported by another block.

@@ -0,0 +1,6 @@
const path = require('path');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I started out with all this in the index.js, but broke them out into individual files like this once I realised I need the paragraph.js for setting the default in Implementation.js.

I don't mind them being split out into separate files like this; it's reminiscent of the field types themselves. OTOH; I'm not against moving them back into index.js, it just means we'll end up with duplicate definitions for paragraph.js which is a bit icky. (same goes for the dependencies)

@@ -0,0 +1,7 @@
{
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making sure that every block type is bundled, even the dependencies, in case they're not imported directly.


if (dependencies !== undefined) {
// Recurse on the dependencies
flattenBlocks(dependencies, outputBlocks);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dependencies are already flattened pre-build in Implemenation.js, so there's nothing to do here.

@JedWatson
Copy link
Member

@jesstelford looking good!

One thing that occurred to me; if the blocks are all loaded, always, is it worth having separate entrypoints for them? or could a higher level index just export { all, block, types }

I do like the individual files for block types (esp. that they are following patterns established by field types) but couldn't tell how having separate entrypoints interacts with your point about having extracted them all from the index and the reduced duplication.

Feel free to act / not act on this feedback, as-is looks good ✅

@mitchellhamilton this might be something to consider for #993, if that could work for block types as well as field types?

@jesstelford
Copy link
Contributor Author

jesstelford commented Apr 10, 2019

if the blocks are all loaded, always, is it worth having separate entrypoints for them?

All the blocks for that field are loaded.

For example;

Keystone.createList('User', {
  fields: {
    bio: {
      type: Content,
      blocks: [
        Content.blocks.link
      ]
    }
  }
});

Would load the link and the default paragraph blocks when landing on the Field view for the User list (ie; editing or adding a User).

Keystone.createList('Post', {
  fields: {
    bio: {
      type: Content,
      blocks: [
        Content.blocks.header,
        Content.blocks.unorderedList,
      ]
    }
  }
});

Would load the unorderedList, its dependency of listItem, and the default paragraph blocks when landing on the Field view for the Post list (ie; editing or adding a Post).

This way it only loads exactly what is required per field 👍

how having separate entrypoints interacts with your point about having extracted them all from the index and the reduced duplication.

The main one was the paragraph type; it's a dependency for a couple of the others and is referenced in the default list. Once I deduplicated that by putting it in its own file, I figured why not do it for the rest too.

@jesstelford
Copy link
Contributor Author

Looks like I broke the tests - will fix them up then merge.

Previous behaviour was to rely on manually importing a block for it to
be included (eg; `unordered-list` imports the `list-item` block). While
this is currently always the case, it doesn't necessarily have to be.

One example might be a 3rd party block which wants to create
heading+subheading pair, and set a dependency on the `heading` block
without ever importing it (instead; referencing it by its type name from
within the 3rd party block).

By surfacing the type on the server / during webpack build we're able to
do a couple more checks such as for duplicates and also replace the
sparse config array with a keyed object.

Finally, we can pull up the default `paragraph` block into the pre-build
step and remove that logic from the client code, making it a bit
cleaner.
@emmatown
Copy link
Member

@mitchellhamilton this might be something to consider for #993, if that could work for block types as well as field types?

It'll 100% work for block types.

@jesstelford jesstelford merged commit bfde3e6 into master Apr 10, 2019
@jesstelford jesstelford deleted the blocks branch April 10, 2019 22:03
jesstelford added a commit that referenced this pull request Apr 16, 2019
jesstelford added a commit that referenced this pull request Apr 16, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants