-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Plugin: Implement block registering API #289
Conversation
b445c38
to
2694251
Compare
external/@wordpress/blocks/index.js
Outdated
} | ||
|
||
/** | ||
* Returns all registered blocks. | ||
* | ||
* @return {Object} Block settings keyed by block name | ||
* @return {Array} Blocks settings |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not keyed by block name because the block name is not unique, it's unique inside a namespace only.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I'm worried we'll find the namespacing will get in our way more than it helps. I'm not totally convinced about it. It's nice to have the consistency with similar APIs for the REST API, but I wonder if we could just allow a simple name and perhaps encourage a convention around including some namespace in the name itself: like "wp/text"
(or without namespace for "core" types).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are the expected uses of this function? Do you think we will need the ability to pull a specific block out of the list? If so, it might be a good idea to return an array keyed by namespace then block name, as the blocks are stored.
Also, Block settings
is better wording.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are the expected uses of this function?
This is a good point. Seems nice as an external API, but I don't see an obvious use-case for us initially.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From my experience with the multi-instance
prototype. This function was used in two places:
-
Fetching all the blocks to show in the block inserter (Array is better here, because we need to group them by category and not by namespace)
-
Fetching all the blocks to find the blocks that a block can be switched to (The filtering happens using one of the settings key and not the namespace).
So IMO it's better to return a simple array.
Regarding the name, I'm leaning towards removing the namespace and encouraging a convention
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding the name, I'm leaning towards removing the namespace and encouraging a convention
Encouraging a convention is not enough, it needs to be enforced otherwise people won't follow it.
Though this can be done either way -
if ( ! /^\w+/\w+$/\.test( blockName ) ) {
throw new Error( 'Use a namespace please' );
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Repeating my comment elsewhere, I think we can let go of namespace. The name should be unique and descriptive anyways because the user would interact and search for it.
external/@wordpress/blocks/index.js
Outdated
|
||
blocks[ namespace ][ block ] = Object.assign( | ||
{ name: block, namespace }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we call it name
on the object, should we just accept the argument labeled as name
as well?
external/@wordpress/blocks/index.js
Outdated
@@ -1,5 +1,7 @@ | |||
export { default as Editable } from './components/editable'; | |||
|
|||
const blocks = {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be nice to provide a DocBlock for this.
Yes, let's go ahead and do this please :) Whatever we choose should support browser testing as well. I agree I like Mocha better, but core uses QUnit. Do you see this causing problems in the future if we need to integrate both? What are the difficulties in adding QUnit?
+1. WP core already bundles Underscore, though Lodash is nicer to work with and we would be able to include selective imports in a build process.
If we do keep the namespace and name separate, this makes it easier to test and enforce guidelines for block authors using these fields correctly. |
The problem with keeping the name and namespace separate is that each time we'll need to retrieve the block settings we'll do |
Good point, that is not ideal :) As long as we can do something like #289 (comment), then combining the namespace and name makes sense to me. |
I updated the API and dropped the namespace.
My experience with QUnit is equal to Zero :). So after reading the docs, I figured out that integrating it with our build system means having a separate webpack.config for the tests and import all the test files on a test entry point file. Not so handy IMO, but maybe I'm missing a better way to setup qunit. If someone could help on setting up QUnit (could be a separate PR), it would be awesome!!! |
I would very much prefer that we start now with the rule of "do not merge code unless it has tests". Also, mocha is going to be much nicer to work with than QUnit, and thinking about it a bit more, any difficulties with integration are likely to be pretty minor. I'll try to add it here. |
1e4b7b2
to
c2e4c8c
Compare
@mtias I'm replying to your #289 (comment) here because the thread has disappeared after a rebase.
I am not sure whether you mean letting go of namespace as a separate argument, or the concept entirely. I agree that using the namespace as a separate argument is going to lead to more complicated code, removing it in 65d60a6 has already simplified things a good bit. But we really need to require that blocks use a plugin-specific prefix for their internal ID/name/slug/whatever you call it, and in general we need to start thinking about how blocks can be named and how their resulting There is a lot of precedent in WP core for doing similar things. The reasoning is laid out really well in this blog post: https://nacin.com/2010/05/11/in-wordpress-prefix-everything/ Here are a couple more specific examples:
IMO, it's also worth considering whether we need to version blocks similarly to REST API endpoints. This is something we could add later on if we need it, though. |
@nylen yes, sorry for the confusion, I mean using specific argument or |
I'm not planning to spend a lot of time on it, beyond making it work and writing some simple tests, but enforcing a very specific syntax is a good thing. We can always relax the rules later when more needs become apparent, but we can't do the reverse when people misuse the functionality provided. |
external/@wordpress/blocks/index.js
Outdated
*/ | ||
export function getBlocks() { | ||
|
||
return Object.values( blocks ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will probably require pulling in babel-plugin-transform-runtime
, otherwise will error on browsers where this is not yet implemented.
.babelrc
Outdated
@@ -1,9 +1,8 @@ | |||
{ | |||
"presets": [ | |||
[ "latest", { | |||
"es2015": { | |||
"modules": false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was important to have in order to achieve Webpack tree shaking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, interesting. At one point I was getting an error until I removed this (http://stackoverflow.com/a/42834190) but now it is working fine.
.babelrc
Outdated
"modules": false | ||
} | ||
} ] | ||
[ "latest", "es2015" ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, es2015 is included in latest, I think it's not needed here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a further change we should make here? I'm not sure if you can do latest: { modules: false }
for example, or how to test whether this is working as intended.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, the last change is good 👍
Yes, hard to know if it's working correctly. I guess we'll see when we import some function for lodash
. We could check that it's not including the whole library
This now has A few notes about the test setup:
|
test/blocks/index.js
Outdated
import chai, { expect } from 'chai'; | ||
import dirtyChai from 'dirty-chai'; | ||
|
||
import * as blocks from '@wordpress/blocks'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason why you would use * instead of explicit imports?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no preference either way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this particular case, it's not making any difference, but worth noting that in other use cases when importing from external libraries, it can have an impact on tree shaking
import * as _ from 'lodash'; console.log( _.uniqueId() ); // This will include the whole lodash
import { uniqueId } from 'lodash'; console.log( uniqueId() ); // This will include only uniqueId
test/blocks/index.js
Outdated
@@ -0,0 +1,73 @@ | |||
import mocha from 'mocha'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we use the /** External/Internal dependencies **
comments (similar to Calypso)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, probably :)
In e157c9a I changed I'm open to suggestions here, but I don't think it should be called |
On the initial build PR. I've used yarn as well but if we commit the |
This is looking solid for me. Thanks, @nylen for the test infra. Waiting for a 👍 to merge. We could iterate later if we need to change the block slug format or anything else. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you look to see if there's a chance we could integrate QUnit without too much trouble? Seems like it will suffer many of the same gotchas as Mocha, but if we could pull it off would certainly make eventual integration a fair bit less... complicated.
test/blocks/index.js
Outdated
|
||
import * as blocks from '@wordpress/blocks'; | ||
|
||
chai.use( dirtyChai ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're going to pull in and assume plugins to be used consistently, could we somehow apply it as part of the overall test initialization?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I extracted this to a test/boot.js
test/blocks/index.js
Outdated
chai.use( dirtyChai ); | ||
|
||
describe( 'blocks API', () => { | ||
// TODO: We probably want a way to undo this, and split this logic out into |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would blocks.unregisterBlock
be a reasonable reasonable to work around this problem?
webpack.config.test.js
Outdated
|
||
const config = module.exports = Object.assign( {}, baseConfig, { | ||
target: 'node', | ||
externals: [ nodeExternals() ], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see it in mocha-webpack
's docs, and even upon reading the docs of webpack-node-externals
itself, it's still not clear why this is necessary. Does it make the build more performant? Is it any different than:
resolve: {
modules: baseConfig.resolve.modules.filter( ( source ) => source !== 'node_modules' )
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried without it and using your alternative. I don't understand all what's happening here but it's not working without this.
package.json
Outdated
@@ -11,23 +11,30 @@ | |||
"editor" | |||
], | |||
"scripts": { | |||
"test": "mocha-webpack test/", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seeing that mocha-webpack
has a --webpack-config
option and our Webpack config already includes some environment-specific handling, do you have any opinion on whether it might make sense to merge webpack.config.test.js
into the base config and change this to:
"test": "NODE_ENV=test mocha-webpack --webpack-config webpack.config.js test/"
Trying to think of ways to avoid root directory becoming too sprawling with files.
e157c9a
to
5904546
Compare
Issue with
|
- No need for a separate `validateBlockSlug` function - More thorough and more isolated tests
Thanks, @youknowriad and @aduth for working on this and for reviewing. In a512271 I added I'm not having any problems with One remaining question here is whether to use QUnit or Mocha for test infrastructure. I find QUnit very awkward to work with. In terms of eventual integration with WP core, in the worst case this is going to mean that we add a separate Travis CI job to run Mocha tests. I think this is OK, because there will be lots of tests for this project, so they will take a while to run 😉 I think the added developer convenience of using Mocha is well worth it, and maybe we can also start a new standard for core JS tests. So, in short, IMO this is ready to merge so we can move forward. |
This was from `mocha-webpack`, which is no longer used, so this entry is no longer needed.
I don't think it's related to this PR, but we're having errors like |
I found that babel |
Replacing |
65066e1 fixes errors from Webpack. There's another error from |
I'd still like some feedback on my earlier point:
|
@aduth I agree, We shouldn't crash on wrong blocks, but just ignore them. 👍 for console.error for me |
Questions
mocha
maybe?lodash
here seems appropriate, what are your thoughts on adding it?id
(namespace/name
)?