-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
Proposal: make block modules side-effect free #5875
Comments
@rachel-fenichel I believe the above summarises our conversation yesterday, with a few additional ideas that have occurred to me in the mean time. Input from the Blockly team as well as external developers welcome. |
Related to step 3, should the block plugins provided in samples also be changed to have some kind of installation step? I'm not sure if fixing the inconsistency is worth the extra work or not. |
Yes: if we make the blocks modules in |
I think we can do this without introducing a breaking change this quarter, and would greatly prefer to keep to that goal. Let's provide new modules that behave as described (can be individually imported, no side effects, etc.) while maintaining the old modules that keep the current behavior for now. That gives developers some time to move over to the new format without mandating they switch immediately. The change to the generator imports was actually pretty disruptive/painful to some partners and I'd rather not do another one right on the heels of it. Let's wait a while longer and batch up the breaking changes until we hit something that's unavoidable to break, or we have a big enough batch. |
Yes, I concur. That's basically what we've done with generators. I think for both blocks and generators we want to provide one or more new |
Background
At the moment, the blocks modules (
Blockly.blocks.*
, inblocks/
) generally do not have any exports; instead, importing one causes the created blocks definitions to be loaded into the block definitions dictionary (Blockly.Blocks
, or more specifically theBlocks
export of theBlockly.blocks
module) as a side effect. Various extensions are also registered (again as a side-effect) via theregister*
exports of theBlockly.Extensions
module.Additionally, library block modules are normally imported via a single
import 'blockly/blocks' statement, which imports the
Blockly.blocks.allmodule, which in turn imports the rest of the individual
Blockly.blocks.*` modules.This creates some problems for developers:
import 'blockly/blocks'
is all-or-nothing: only developers using the Closure module system can usegoog.require
to load only a specific module (e.g.Blockly.blocks.loops
).Blockly.Blocks
(as well as unregister any unwanted extensions).import
statements to access exports from individual block module (e.g., theloopTypes
export fromBlockly.blocks.loops
)—see There is no mechanism to register custom loops anymore since the 2021 Q4 release #5819.Proposed solution
Refactor the block modules in several steps, as follows:
Add a standard set of
exports
to the block modules:blocks
: a dictionary object (@type {!Object<string, !Object>}
), keyed by block type, of the block definitions that that module creates.extensions
: a dictionary object (@type {!Object<string, !Object>}
) keyed by extension name, of the extensions registered by the module.loopTypes
).The
blockly.blocks.all
module will provideblocks
andextensions
dictionaries that include all the entries form all of the individual block modules. Additionally, it will re-export the exports objects from each of those modules using the corresponding names (e.g.colour
,lists
,loops
, etc.)This will enable importers to see the full set of blocks (and extensions) that are loaded, as well as access any other exports provided by individual block modules (e.g.,
loops.loopTypes
).This will be a breaking change to the exports provided by importing
blockly/blocks
:blockly/blocks
provides a default export of the wholeBlockly.Blocks
dictionary.blocks/
(and not any which might have been added toBlockly.Blocks
before or afterblockly/blocks
was imported), in addition to other named exports.…but it is not believed that very many external developers will be impacted by it.
Optional intermediate step: refactor block modules so that rather than creating block definitions in the
Blockly.Blocks
dictionary and then extracting them for theblocks
export, they are created in theblocks
exported dictionary and then added toBlockly.Blocks
—and similarly for extensions. This will not be a breaking change.Refactor the block modules so that they do not by default add block (and extension) definitions to Blockly. Instead, provide a method on Blockly to copy block definitions from a provided dictionary into
Blockly.Blocks
upon request. This will be a breaking change necessitating developers to manually request block and extension definition installation—but thereby allowing them to choose exactly which definitions they wish to install.For convenience, an exported function (perhaps
registerAll
or'installBlocks
) could be provided on each block module to facilitate making the correct install the block definitions and register extensions from that module.Alternatives
Some alternatives to the proposal above (which have not yet been fully considered):
blocks
andextensions
as separate named exports, they could be encapsulated into a single named export (possibly of a type such asBlocksAndExtensions
with instance properties.blocks
and.extensions
) which could be passed to an install-and-register function onBlockly
. This might slightly ease the transition for developers.Current status
CodeGenerator
#7086)?blocks
dictionary and then installed inBlockly.Blocks
.Blockly.Blocks
. (Breaking change!)The text was updated successfully, but these errors were encountered: