Closed izaera closed 3 years ago
An idea that came to mind is to create internal webpack bundles + entry points which require each js module inside the project and reexports it. These would be called internal exports
and would be generated automatically by the bundler.
Also, to honor 1, we would call these entry points something like internal_do_not_use/...
or mangle their names using hashes to make people aware that they shouldn't consume them from other bundles.
create internal webpack bundles + entry points which require each js module inside the project and reexports it
Would these be "bundles" in the sense that they include their transitive dependencies? How would we avoid redundantly bundling the same dependencies over and over? And are you proposing autodetecting with modules should be entry points (due to internal usage), or just assuming that any module could be consumed internally?
[...] just assuming that any module could be consumed internally?
This π
How would we avoid redundantly bundling the same dependencies over and over?
I was hoping maybe we could configure webpack common chunks to deal with this...
I was hoping maybe we could configure webpack common chunks to deal with this...
I can't see how that would work then. Because if anything can be an entry point, then the entire dependency graph is probably reachable in multiple ways. There will be no leaf nodes, even, that could be packed into a common bundle, because any of those could be an entry point (and via induction, the same is true for any other module).
You might be right... any suggestion that comes to mind? We could always do this by convention rather than configuration...
Right now we only split in:
Everything in 2 is loaded for every entry point, while all those in 1 are only loaded if the module is used.
AFAIK webpack may be configured more finely to have more than one bundle of type 2, but I haven't investigated it in depth yet.
So, with the current situation, it depends on the dependency graph how much optimization you can get with the two extreme scenarios being:
As I said, if we fine tune webpack I think we may have more than one shared bundle and webpack takes care of loading only the subgraphs that are needed for each entry point.
:point_right: https://webpack.js.org/plugins/split-chunks-plugin/
I didn't read this :sweat_smile:
There will be no leaf nodes, even, that could be packed into a common bundle, because any of those could be an entry point (and via induction, the same is true for any other module).
However, I don't think it applies.
Because if webpack lets the bundles duplicate code, the tree shaking could be perfect at the cost of more size in the JAR (one bundle per entry point with only the needed subgraph; obviously with lots of duplication).
And then, you can have something between the middle with shared bundles that contain common code for a selected group of entry points. I'll attach a hand drawing to show what I mean.
Yeah, you'd have to try it and see what webpack does. Thinking about a small example graph:
A--B--C---*
\ \ \
D-----E---F
\ /
G-----*
\
H
Where A
is the main
entry point, and we'd need "bundles" for each of A
through H
. What does "perfect" tree-shaking mean in this scenario? ("one bundle per entry point with only the needed subgraph; obviously with lots of duplication" doesn't really sound perfect to me at all.)
Your ASCII art was faster than my webcam + GIMP editing :joy:
Depending on the connectivity of the graph, the level of redundancy in the bundles could be tremendous (at a glance, I'm thinking total size could grow quadratically, which with a big library could quickly become untenable).
Yes that's true.
The webpack split plugin has settings based on max/min size of the bundles and number of bundles needed to load the whole graph (to avoid several multiple connections).
Thinking about it, looks like perfect tree shaking is impossible for all scenarios. :thinking:
But it seems true that the more entry points you have, the more you will be constrained when tree shaking...
I would say that if we can't think of any other solution we can analyze what happens first and then decide if it is too horrible to implement it or we can live with it.
But if we can have another candidate solution before starting the analysis it would be great. :sweat_smile:
My intuition is that it is infeasible, even without trying it. I only mention seeing what webpack does out of curiosity.
This feels like it's running into conflict with the original design motivation for the Liferay bundler/loader, and why we even have one. We have one because we can't know ahead of time what is going to be needed for a particular page, so we don't have the luxury of preparing prepacked, optimal bundles for each route on a site. So, we made this thing (v2) that has a build-time part (preparing individual modules for delivery) and a run-time part (the server-side registry the module resolver endpoint, and the combo servlet) which allow us to effectively make and deliver bundles on the fly.
v3 evolves that model a little bit by making these prebuilt bundles using webpack in the name of speeding up the build. But, what we're talking about in this PR goes waaaaay beyond that. It's right back in the territory of "we don't know ahead of time what's needed", but this time the answer isn't "figure it out just-in-time"; it's "prepare a bundle for every possible eventuality" β and my gut says that we're going to run afoul of quadratic growth if we try this.
I would say we need to keep the thinking cap on for a little bit on this one. π¬
Bad news: if we create multiple chunks (shared bundles) we need to load them. And to load them, we:
So, it seems like this will break the tree shaking no matter what we do...
"we don't know ahead of time what's needed"
:thinking: the truth is we may know it scanning the code, except for dynamically generated module names which we could:
By dynamically generated module names I mean things like:
<%
MyDisplayContext myDisplayContext = new MyDisplayContext();
%>
<aui:script require="<%= myDisplayContext.gimmeTheModuleName() %>"/>
which are not resolvable at build time, for obvious reasons.
we could:
- forbid
- warn about so that the user configures them by hand
So to know whether that is feasible, we'd need to know how many of them there are (not the exact number; just a ballpark figure), and I would also want to think through the implications for people using the bundler outside of liferay-portal repo.
We could delegate the parsing task to gradle/npm-scripts to make them create a correct configuration file for the bundler.
Also, if we want to make this internal exports less accessible, it's a matter of gradle/npm-scripts generating the correct entry point names as suggested here.
So to know whether that is feasible, we'd need to know how many of them there are
Any -web
or -taglilb
module have several as soon as they need to use JavaScript. I would say we don't even need to count them because it's the most usual pattern. :shrug:
using the bundler outside of liferay-portal repo
Yeah, that would leave the forbid option out, I think.
Still, I don't think it is usual to have dynamic module names. I'll look for them and report.
Around 10 for <aui:script require>
. However, I've noticed that even though they look dynamic, some of them are just hard coded values disguised in java strings (mostly because of the npmResolvedPackageName
injected JSP variable which I think it's not needed any more).
0 for <liferay-frontend:component module/>
I would say that it is very unusual, but we should not forbid dynamic module names (just discourage them) because they may be needed when creating extensible interfaces. For instance, think of a multiplexing JSP that depending on the context renders a different JS module based on a configuration value. And people can contribute more JS modules with fragments after the JSP has been published. Things like that....
Another thing that comes to my mind is if the hypothesis that having more entry points is worse holds true....
All this is happening in the context of a single project so, unless people have dead core around in their projects, all of it will end up being loaded in one moment or other so, the worse thing that could happen is that we load more than we need in advance, not that we load unused things.
But it may not be so catastrophic as we think. Or at least not as catastrophic as it would be configuring all the JS files in react
or angular
as entry points.
But it may not be so catastrophic as we think. Or at least not as catastrophic as it would be configuring all the JS files in
react
orangular
as entry points.
Pick something like layout-content-page-editor-web
and see if it scales:
src
βββ main
βββ resources
βββ META-INF
βββ resources
βββ page_editor
βββ app
βΒ Β βββ actions
βΒ Β βΒ Β βββ addFragmentComposition.js
βΒ Β βΒ Β βββ addFragmentEntryLinkComment.js
βΒ Β βΒ Β βββ addFragmentEntryLinks.js
βΒ Β βΒ Β βββ addItem.js
βΒ Β βΒ Β βββ addMappedInfoItem.js
βΒ Β βΒ Β βββ addUsedWidgets.js
βΒ Β βΒ Β βββ deleteFragmentEntryLinkComment.js
βΒ Β βΒ Β βββ deleteItem.js
βΒ Β βΒ Β βββ deleteWidgets.js
βΒ Β βΒ Β βββ duplicateItem.js
βΒ Β βΒ Β βββ editFragmentEntryLinkComment.js
βΒ Β βΒ Β βββ index.js
βΒ Β βΒ Β βββ loadReducer.js
βΒ Β βΒ Β βββ moveItem.js
βΒ Β βΒ Β βββ switchSidebarPanel.js
βΒ Β βΒ Β βββ switchViewportSize.js
βΒ Β βΒ Β βββ togglePermission.js
βΒ Β βΒ Β βββ toggleShowResolvedComments.js
βΒ Β βΒ Β βββ types.js
βΒ Β βΒ Β βββ unloadReducer.js
βΒ Β βΒ Β βββ updateColSize.js
βΒ Β βΒ Β βββ updateEditableValues.js
βΒ Β βΒ Β βββ updateFragmentEntryLinkConfiguration.js
βΒ Β βΒ Β βββ updateFragmentEntryLinkContent.js
βΒ Β βΒ Β βββ updateItemConfig.js
βΒ Β βΒ Β βββ updateLanguageId.js
βΒ Β βΒ Β βββ updateLayoutData.js
βΒ Β βΒ Β βββ updateNetwork.js
βΒ Β βΒ Β βββ updatePageContents.js
βΒ Β βββ components
βΒ Β βΒ Β βββ AllowedFragmentSelector.js
βΒ Β βΒ Β βββ AllowedFragmentTreeNode.js
βΒ Β βΒ Β βββ App.js
βΒ Β βΒ Β βββ CollectionItemContext.js
βΒ Β βΒ Β βββ Controls.js
βΒ Β βΒ Β βββ DisabledArea.js
βΒ Β βΒ Β βββ DragPreview.js
βΒ Β βΒ Β βββ ExperimentsLabel.js
βΒ Β βΒ Β βββ Frame.js
βΒ Β βΒ Β βββ Layout.js
βΒ Β βΒ Β βββ LayoutViewport.js
βΒ Β βΒ Β βββ ManageAllowedFragmentButton.js
βΒ Β βΒ Β βββ ManageAllowedFragmentModal.js
βΒ Β βΒ Β βββ MasterLayout.js
βΒ Β βΒ Β βββ NetworkStatusBar.js
βΒ Β βΒ Β βββ Sidebar.js
βΒ Β βΒ Β βββ Toolbar.js
βΒ Β βΒ Β βββ Topper.js
βΒ Β βΒ Β βββ TopperEmpty.js
βΒ Β βΒ Β βββ Translation.js
βΒ Β βΒ Β βββ UnsafeHTML.js
βΒ Β βΒ Β βββ ViewportSizeSelector.js
βΒ Β βΒ Β βββ floating-toolbar
βΒ Β βΒ Β βΒ Β βββ CollectionConfigurationPanel.js
βΒ Β βΒ Β βΒ Β βββ ContainerConfigurationPanel.js
βΒ Β βΒ Β βΒ Β βββ FloatingToolbar.js
βΒ Β βΒ Β βΒ Β βββ FragmentConfigurationPanel.js
βΒ Β βΒ Β βΒ Β βββ ImagePropertiesPanel.js
βΒ Β βΒ Β βΒ Β βββ LinkPanel.js
βΒ Β βΒ Β βΒ Β βββ MappingPanel.js
βΒ Β βΒ Β βΒ Β βββ RowConfigurationPanel.js
βΒ Β βΒ Β βΒ Β βββ SaveFragmentCompositionModal.js
βΒ Β βΒ Β βΒ Β βββ SectionConfigurationPanel.js
βΒ Β βΒ Β βββ fragment-configuration-fields
βΒ Β βΒ Β βΒ Β βββ CheckboxField.js
βΒ Β βΒ Β βΒ Β βββ CollectionSelectorField.js
βΒ Β βΒ Β βΒ Β βββ ColorPaletteField.js
βΒ Β βΒ Β βΒ Β βββ ItemSelectorField.js
βΒ Β βΒ Β βΒ Β βββ SelectField.js
βΒ Β βΒ Β βΒ Β βββ TextField.js
βΒ Β βΒ Β βΒ Β βββ index.js
βΒ Β βΒ Β βββ fragment-content
βΒ Β βΒ Β βΒ Β βββ EditableProcessorContext.js
βΒ Β βΒ Β βΒ Β βββ FragmentContent.js
βΒ Β βΒ Β βΒ Β βββ FragmentContentFloatingToolbar.js
βΒ Β βΒ Β βΒ Β βββ FragmentContentInteractionsFilter.js
βΒ Β βΒ Β βΒ Β βββ FragmentContentProcessor.js
βΒ Β βΒ Β βΒ Β βββ getAllEditables.js
βΒ Β βΒ Β βΒ Β βββ getEditableElement.js
βΒ Β βΒ Β βΒ Β βββ getEditableElementId.js
βΒ Β βΒ Β βΒ Β βββ getEditableUniqueId.js
βΒ Β βΒ Β βΒ Β βββ isMapped.js
βΒ Β βΒ Β βΒ Β βββ resolveEditableValue.js
βΒ Β βΒ Β βββ layout-data-items
βΒ Β βΒ Β βΒ Β βββ Collection.js
βΒ Β βΒ Β βΒ Β βββ CollectionItemWithControls.js
βΒ Β βΒ Β βΒ Β βββ CollectionWithControls.js
βΒ Β βΒ Β βΒ Β βββ Column.js
βΒ Β βΒ Β βΒ Β βββ ColumnOverlayGrid.js
βΒ Β βΒ Β βΒ Β βββ ColumnWithControls.js
βΒ Β βΒ Β βΒ Β βββ Container.js
βΒ Β βΒ Β βΒ Β βββ ContainerWithControls.js
βΒ Β βΒ Β βΒ Β βββ DropZoneWithControls.js
βΒ Β βΒ Β βΒ Β βββ FragmentWithControls.js
βΒ Β βΒ Β βΒ Β βββ FragmentsEditorShim.js
βΒ Β βΒ Β βΒ Β βββ Root.js
βΒ Β βΒ Β βΒ Β βββ Row.js
βΒ Β βΒ Β βΒ Β βββ RowWithControls.js
βΒ Β βΒ Β βΒ Β βββ Section.js
βΒ Β βΒ Β βΒ Β βββ SectionWithControls.js
βΒ Β βΒ Β βΒ Β βββ hasDropZoneChild.js
βΒ Β βΒ Β βΒ Β βββ index.js
βΒ Β βΒ Β βββ undo
βΒ Β βΒ Β βββ Undo.js
βΒ Β βΒ Β βββ UndoHistory.js
βΒ Β βΒ Β βββ getActionLabel.js
βΒ Β βΒ Β βββ undoActions.js
βΒ Β βΒ Β βββ undoDelete.js
βΒ Β βΒ Β βββ undoDuplicateItem.js
βΒ Β βΒ Β βββ undoEditableValuesAction.js
βΒ Β βΒ Β βββ undoFragmentConfiguration.js
βΒ Β βΒ Β βββ undoFragmentEntryLinks.js
βΒ Β βΒ Β βββ undoLayoutDataAction.js
βΒ Β βΒ Β βββ undoSelectExperience.js
βΒ Β βΒ Β βββ undoUpdateLanguage.js
βΒ Β βΒ Β βββ useUndo.js
βΒ Β βββ config
βΒ Β βΒ Β βββ constants
βΒ Β βΒ Β βΒ Β βββ backgroundImageFragmentEntryProcessor.js
βΒ Β βΒ Β βΒ Β βββ compatibleTypes.js
βΒ Β βΒ Β βΒ Β βββ editableFloatingToolbarButtons.js
βΒ Β βΒ Β βΒ Β βββ editableFloatingToolbarClassNames.js
βΒ Β βΒ Β βΒ Β βββ editableFragmentEntryProcessor.js
βΒ Β βΒ Β βΒ Β βββ editableTypes.js
βΒ Β βΒ Β βΒ Β βββ floatingToolbarConfigurations.js
βΒ Β βΒ Β βΒ Β βββ fragmentTypes.js
βΒ Β βΒ Β βΒ Β βββ freemarkerFragmentEntryProcessor.js
βΒ Β βΒ Β βΒ Β βββ highlightedCommentIdKey.js
βΒ Β βΒ Β βΒ Β βββ itemActivationOrigins.js
βΒ Β βΒ Β βΒ Β βββ itemTypes.js
βΒ Β βΒ Β βΒ Β βββ keycodes.js
βΒ Β βΒ Β βΒ Β βββ layoutDataFloatingToolbarButtons.js
βΒ Β βΒ Β βΒ Β βββ layoutDataItemTypeLabels.js
βΒ Β βΒ Β βΒ Β βββ layoutDataItemTypes.js
βΒ Β βΒ Β βΒ Β βββ moveItemDirections.js
βΒ Β βΒ Β βΒ Β βββ pageTypes.js
βΒ Β βΒ Β βΒ Β βββ serviceNetworkStatusTypes.js
βΒ Β βΒ Β βΒ Β βββ translationStatusType.js
βΒ Β βΒ Β βΒ Β βββ viewportSizes.js
βΒ Β βΒ Β βββ index.js
βΒ Β βββ index.js
βΒ Β βββ processors
βΒ Β βΒ Β βββ BackgroundImageProcessor.js
βΒ Β βΒ Β βββ FallbackProcessor.js
βΒ Β βΒ Β βββ HTMLProcessor.js
βΒ Β βΒ Β βββ ImageProcessor.js
βΒ Β βΒ Β βββ LinkProcessor.js
βΒ Β βΒ Β βββ RichTextProcessor.js
βΒ Β βΒ Β βββ TextProcessor.js
βΒ Β βΒ Β βββ getAlloyEditorProcessor.js
βΒ Β βΒ Β βββ getLinkableEditableEditorWrapper.js
βΒ Β βΒ Β βββ index.js
βΒ Β βββ reducers
βΒ Β βΒ Β βββ baseReducer.js
βΒ Β βΒ Β βββ collectionsReducer.js
βΒ Β βΒ Β βββ fragmentEntryLinksReducer.js
βΒ Β βΒ Β βββ fragmentsReducer.js
βΒ Β βΒ Β βββ index.js
βΒ Β βΒ Β βββ languageIdReducer.js
βΒ Β βΒ Β βββ languageReducer.js
βΒ Β βΒ Β βββ layoutDataReducer.js
βΒ Β βΒ Β βββ mappedInfoItemsReducer.js
βΒ Β βΒ Β βββ networkReducer.js
βΒ Β βΒ Β βββ pageContentsReducer.js
βΒ Β βΒ Β βββ permissionsReducer.js
βΒ Β βΒ Β βββ selectedViewportSizeReducer.js
βΒ Β βΒ Β βββ showResolvedCommentsReducer.js
βΒ Β βΒ Β βββ sidebarReducer.js
βΒ Β βΒ Β βββ undoReducer.js
βΒ Β βΒ Β βββ widgetsReducer.js
βΒ Β βββ selectors
βΒ Β βΒ Β βββ selectAvailablePanels.js
βΒ Β βΒ Β βββ selectAvailableSidebarPanels.js
βΒ Β βΒ Β βββ selectCanUpdate.js
βΒ Β βΒ Β βββ selectCanUpdateLayoutContent.js
βΒ Β βΒ Β βββ selectEditableValue.js
βΒ Β βΒ Β βββ selectEditableValueConfig.js
βΒ Β βΒ Β βββ selectEditableValueContent.js
βΒ Β βΒ Β βββ selectSegmentsExperienceId.js
βΒ Β βββ services
βΒ Β βΒ Β βββ CollectionService.js
βΒ Β βΒ Β βββ ExperienceService.js
βΒ Β βΒ Β βββ FragmentService.js
βΒ Β βΒ Β βββ InfoItemService.js
βΒ Β βΒ Β βββ LayoutService.js
βΒ Β βΒ Β βββ WidgetService.js
βΒ Β βΒ Β βββ serviceFetch.js
βΒ Β βββ store
βΒ Β βΒ Β βββ index.js
βΒ Β βββ thunks
βΒ Β βΒ Β βββ addFragment.js
βΒ Β βΒ Β βββ addFragmentComment.js
βΒ Β βΒ Β βββ addFragmentComposition.js
βΒ Β βΒ Β βββ addItem.js
βΒ Β βΒ Β βββ addWidget.js
βΒ Β βΒ Β βββ deleteFragmentComment.js
βΒ Β βΒ Β βββ deleteItem.js
βΒ Β βΒ Β βββ duplicateItem.js
βΒ Β βΒ Β βββ editFragmentComment.js
βΒ Β βΒ Β βββ moveItem.js
βΒ Β βΒ Β βββ multipleUndo.js
βΒ Β βΒ Β βββ resizeColumns.js
βΒ Β βΒ Β βββ undo.js
βΒ Β βΒ Β βββ updateEditableValues.js
βΒ Β βΒ Β βββ updateFragmentConfiguration.js
βΒ Β βΒ Β βββ updateItemConfig.js
βΒ Β βΒ Β βββ updateRowColumns.js
βΒ Β βββ utils
βΒ Β βββ getLayoutDataItemLabel.js
βΒ Β βββ getResponsiveConfig.js
βΒ Β βββ getWidgetPath.js
βΒ Β βββ setWidgetUsage.js
βΒ Β βββ useDragAndDrop.js
βΒ Β βββ useId.js
βΒ Β βββ useParseURL.js
βββ common
βΒ Β βββ components
βΒ Β βΒ Β βββ Button.js
βΒ Β βΒ Β βββ Collapse.js
βΒ Β βΒ Β βββ CollectionSelector.js
βΒ Β βΒ Β βββ ColorPalette.js
βΒ Β βΒ Β βββ Editor.js
βΒ Β βΒ Β βββ FormRow.js
βΒ Β βΒ Β βββ ImageSelector.js
βΒ Β βΒ Β βββ InlineConfirm.js
βΒ Β βΒ Β βββ InvisibleFieldset.js
βΒ Β βΒ Β βββ ItemSelector.js
βΒ Β βΒ Β βββ Loader.js
βΒ Β βΒ Β βββ MappingSelector.js
βΒ Β βΒ Β βββ SearchForm.js
βΒ Β βΒ Β βββ SidebarPanelContent.js
βΒ Β βΒ Β βββ SidebarPanelHeader.js
βΒ Β βΒ Β βββ Textarea.js
βΒ Β βΒ Β βββ UserIcon.js
βΒ Β βββ index.js
βββ core
βΒ Β βββ AppContext.js
βΒ Β βββ createDNDBackend.js
βΒ Β βββ debounceRAF.js
βΒ Β βββ hooks
βΒ Β βΒ Β βββ useLazy.js
βΒ Β βΒ Β βββ useLoad.js
βΒ Β βΒ Β βββ usePlugins.js
βΒ Β βΒ Β βββ useSetRef.js
βΒ Β βΒ Β βββ useStateSafe.js
βΒ Β βΒ Β βββ useThunk.js
βΒ Β βββ openImageSelector.js
βΒ Β βββ openInfoItemSelector.js
βββ plugins
βΒ Β βββ comments
βΒ Β βΒ Β βββ components
βΒ Β βΒ Β βΒ Β βββ AddCommentForm.js
βΒ Β βΒ Β βΒ Β βββ CommentForm.js
βΒ Β βΒ Β βΒ Β βββ CommentsSidebar.js
βΒ Β βΒ Β βΒ Β βββ EditCommentForm.js
βΒ Β βΒ Β βΒ Β βββ FragmentComment.js
βΒ Β βΒ Β βΒ Β βββ FragmentComments.js
βΒ Β βΒ Β βΒ Β βββ FragmentEntryLinksWithComments.js
βΒ Β βΒ Β βΒ Β βββ NoCommentsMessage.js
βΒ Β βΒ Β βΒ Β βββ NoCommentsMessageIcon.js
βΒ Β βΒ Β βΒ Β βββ ReplyCommentForm.js
βΒ Β βΒ Β βΒ Β βββ ResolveButton.js
βΒ Β βΒ Β βΒ Β βββ ResolvedCommentsToggle.js
βΒ Β βΒ Β βββ index.js
βΒ Β βββ contents
βΒ Β βΒ Β βββ components
βΒ Β βΒ Β βΒ Β βββ ContentsSidebar.js
βΒ Β βΒ Β βΒ Β βββ NoPageContents.js
βΒ Β βΒ Β βΒ Β βββ PageContent.js
βΒ Β βΒ Β βΒ Β βββ PageContents.js
βΒ Β βΒ Β βββ index.js
βΒ Β βββ experience
βΒ Β βΒ Β βββ actions
βΒ Β βΒ Β βΒ Β βββ createExperience.js
βΒ Β βΒ Β βΒ Β βββ deleteExperience.js
βΒ Β βΒ Β βΒ Β βββ selectExperience.js
βΒ Β βΒ Β βΒ Β βββ types.js
βΒ Β βΒ Β βΒ Β βββ updateExperience.js
βΒ Β βΒ Β βΒ Β βββ updateExperiencePriority.js
βΒ Β βΒ Β βββ actions.js
βΒ Β βΒ Β βββ components
βΒ Β βΒ Β βΒ Β βββ ExperienceItem.js
βΒ Β βΒ Β βΒ Β βββ ExperienceModal.js
βΒ Β βΒ Β βΒ Β βββ ExperienceSelector.js
βΒ Β βΒ Β βΒ Β βββ ExperienceToolbarSection.js
βΒ Β βΒ Β βΒ Β βββ ExperiencesList.js
βΒ Β βΒ Β βΒ Β βββ ExperimentLabel.js
βΒ Β βΒ Β βΒ Β βββ Popover.js
βΒ Β βΒ Β βββ index.js
βΒ Β βΒ Β βββ reducers
βΒ Β βΒ Β βΒ Β βββ createExperience.js
βΒ Β βΒ Β βΒ Β βββ deleteExperience.js
βΒ Β βΒ Β βΒ Β βββ index.js
βΒ Β βΒ Β βΒ Β βββ selectExperience.js
βΒ Β βΒ Β βΒ Β βββ updateExperience.js
βΒ Β βΒ Β βΒ Β βββ updateExperiencePriority.js
βΒ Β βΒ Β βΒ Β βββ utils.js
βΒ Β βΒ Β βββ statuses.js
βΒ Β βΒ Β βββ thunks
βΒ Β βΒ Β βΒ Β βββ createExperience.js
βΒ Β βΒ Β βΒ Β βββ removeExperience.js
βΒ Β βΒ Β βΒ Β βββ selectExperience.js
βΒ Β βΒ Β βΒ Β βββ updateExperience.js
βΒ Β βΒ Β βΒ Β βββ updateExperiencePriority.js
βΒ Β βΒ Β βββ types.js
βΒ Β βΒ Β βββ utils.js
βΒ Β βββ fragments
βΒ Β βΒ Β βββ components
βΒ Β βΒ Β βΒ Β βββ CollectionDisplay.js
βΒ Β βΒ Β βΒ Β βββ FragmentCard.js
βΒ Β βΒ Β βΒ Β βββ FragmentsSidebar.js
βΒ Β βΒ Β βΒ Β βββ LayoutElements.js
βΒ Β βΒ Β βββ index.js
βΒ Β βββ mapping
βΒ Β βΒ Β βββ components
βΒ Β βΒ Β βΒ Β βββ MappingSidebar.js
βΒ Β βΒ Β βββ index.js
βΒ Β βββ page-structure
βΒ Β βΒ Β βββ components
βΒ Β βΒ Β βΒ Β βββ PageStructureSidebar.js
βΒ Β βΒ Β βΒ Β βββ StructureTreeNode.js
βΒ Β βΒ Β βββ index.js
βΒ Β βββ widgets
βΒ Β βββ components
βΒ Β βΒ Β βββ Widget.js
βΒ Β βΒ Β βββ WidgetsSidebar.js
βΒ Β βββ index.js
βββ prop-types
βββ BackgroundImagePropTypes.js
βββ ConfigurationFieldPropTypes.js
βββ LayoutDataPropTypes.js
βββ getEditableItemPropTypes.js
βββ getLayoutDataItemPropTypes.js
βββ index.js
45 directories, 296 files
As expected, with the current setup, everything ends up in the vendor.bundle.js
file, which the one and only shared chunk we allow webpack to generate (as it is now).
Then, there is one single line webpack bundle per entry point (referring to the vendor bundle) plus an additional bridge to make it available through the loader.
So:
Seems worse than bundler 2.
Now I'm going to tweak the SplitChunksPlugin
to see what happens :crossed_fingers: .
I have made a test with just 5 entry points:
exports: {
__page_editor_common_index_js: './page_editor/common/index.js',
__page_editor_common_components_UserIcon_js: './page_editor/common/components/UserIcon.js',
__page_editor_common_components_Collapse_js: './page_editor/common/components/Collapse.js',
__page_editor_common_components_InvisibleFieldset_js: './page_editor/common/components/InvisibleFieldset.js',
__page_editor_common_components_SidebarPanelHeader_js: './page_editor/common/components/SidebarPanelHeader.js',
}
And the result has been an empty vendor bundle (no shared code) and replication of some code inside the entry point bundles.
So, for example, both index.js
and Collapse.js
bundles contain the code for the original Collapse.js
file, as it can be in the following executions of wp-inspect
(a script I've made to dump the contents of a webpack bundle file):
$ wp-inspect build/node/packageRunBuild/resources/__page_editor_common_index_js.bundle.js
AMD module name:
layout-content-page-editor-web@2.0.34/__page_editor_common_index_js.bundle
AMD dependencies:
module
require
./webpack.manifest
frontend-js-react-web$react
frontend-js-react-web$prop-types
frontend-js-react-web$classnames
@frontend-taglib-clay$clayui/icon
@frontend-taglib-clay$clayui/form
Webpack entry [ '__page_editor_common_index_js' ] :
Implementations:
./build/node/bundler/generated/__page_editor_common_index_js.js
./src/main/resources/META-INF/resources/page_editor/common/components/Collapse.js
./src/main/resources/META-INF/resources/page_editor/common/components/SearchForm.js
./src/main/resources/META-INF/resources/page_editor/common/components/SidebarPanelHeader.js
./src/main/resources/META-INF/resources/page_editor/common/index.js
and
$ wp-inspect build/node/packageRunBuild/resources/__page_editor_common_components_Collapse_js.bundle.js
AMD module name:
layout-content-page-editor-web@2.0.34/__page_editor_common_components_Collapse_js.bundle
AMD dependencies:
module
require
./webpack.manifest
frontend-js-react-web$react
frontend-js-react-web$prop-types
frontend-js-react-web$classnames
@frontend-taglib-clay$clayui/icon
Webpack entry [ '__page_editor_common_components_Collapse_js' ] :
Implementations:
./build/node/bundler/generated/__page_editor_common_components_Collapse_js.js
./src/main/resources/META-INF/resources/page_editor/common/components/Collapse.js
Conclusions:
SplitChunksPlugin
decides how to split the bundles based on the constraints the user configures (as specified in its documentation) and it may decide to duplicate or share code depending on its algorithm.~2. Exporting all modules is -with high probability- going to make webpack to put all the shared code in a bundle and load it from every entry point.~ (edited because of the reasons given in the last lines of this comment).
vendor.bundle.js
exists, thus we need to decide which shared bundles to load and when. Well, that just sucks.
Changing the configuration of the plugin alters how the bundles are split. For example, if I use the settings in this example:
{
optimization: {
splitChunks: {
chunks: "all",
maxInitialRequests: 20, // for HTTP2
maxAsyncRequests: 20, // for HTTP2
minSize: 40 // for example only: chosen to match 2 modules
// omit minSize in real use case to use the default of 30kb
}
}
}
I don't get the duplication any more, because the common code for Collapse.js
is put in a separate bundle:
__page_editor_common_components_Collapse_js.bundle.js
__page_editor_common_components_Collapse_js~__page_editor_common_index_js.bundle.js
__page_editor_common_components_InvisibleFieldset_js.bundle.js
__page_editor_common_components_SidebarPanelHeader_js.bundle.js
__page_editor_common_components_SidebarPanelHeader_js~__page_editor_common_index_js.bundle.js
__page_editor_common_components_UserIcon_js.bundle.js
__page_editor_common_index_js.bundle.js
runtime.bundle.js
Sadly, it looks like I was looking at the wrong directory and my first test is not relevant (this one specifically).
However, the second and third (this) are right and the conclusions in this comment still hold except for number 2.
If it's not too hard, and because you have this neat tool to dump the output, would now be the right time to stress test this a little bit with a challenging example (like the layout-content-page-editor-web
example that I mentioned earlier)?
I've done that and it does magic. So much magic that I can't understand anything :sweat_smile: .
If I force it to having more bundles at the cost of having more network request, it looks like the splitting is superb. In particular, with all files exported as entry points I get all these chunks in webpack's output directory:
__page_editor_app_actions_addFragmentComposition_js.bundle.js
__page_editor_app_actions_addFragmentComposition_js~__page_editor_app_actions_addFragmentEntryLinkCo~8bbc10ae.bundle.js
__page_editor_app_actions_addFragmentComposition_js~__page_editor_app_actions_index_js~__page_editor~52e05c40.bundle.js
__page_editor_app_actions_addFragmentEntryLinkComment_js.bundle.js
__page_editor_app_actions_addFragmentEntryLinkComment_js~__page_editor_app_actions_index_js~__page_e~fb5eddd9.bundle.js
__page_editor_app_actions_addFragmentEntryLinks_js.bundle.js
__page_editor_app_actions_addFragmentEntryLinks_js~__page_editor_app_actions_index_js~__page_editor_~d8d31b2c.bundle.js
__page_editor_app_actions_addItem_js.bundle.js
__page_editor_app_actions_addMappedInfoItem_js.bundle.js
__page_editor_app_actions_addMappedInfoItem_js~__page_editor_app_actions_index_js~__page_editor_app_~ca3c8b1e.bundle.js
__page_editor_app_actions_addUsedWidgets_js.bundle.js
__page_editor_app_actions_deleteFragmentEntryLinkComment_js.bundle.js
__page_editor_app_actions_deleteFragmentEntryLinkComment_js~__page_editor_app_actions_index_js~__pag~f4180d21.bundle.js
__page_editor_app_actions_deleteItem_js.bundle.js
__page_editor_app_actions_deleteWidgets_js.bundle.js
__page_editor_app_actions_duplicateItem_js.bundle.js
__page_editor_app_actions_editFragmentEntryLinkComment_js.bundle.js
__page_editor_app_actions_editFragmentEntryLinkComment_js~__page_editor_app_actions_index_js~__page_~2122682e.bundle.js
__page_editor_app_actions_index_js.bundle.js
__page_editor_app_actions_index_js~__page_editor_app_actions_loadReducer_js~__page_editor_app_compon~22a7733f.bundle.js
__page_editor_app_actions_index_js~__page_editor_app_actions_switchSidebarPanel_js~__page_editor_app~e09e580d.bundle.js
__page_editor_app_actions_index_js~__page_editor_app_actions_switchViewportSize_js~__page_editor_app~9dd49b9c.bundle.js
__page_editor_app_actions_index_js~__page_editor_app_actions_toggleShowResolvedComments_js~__page_ed~6678419d.bundle.js
__page_editor_app_actions_index_js~__page_editor_app_actions_unloadReducer_js~__page_editor_app_comp~8bdae623.bundle.js
__page_editor_app_actions_index_js~__page_editor_app_actions_updateColSize_js~__page_editor_app_comp~00901c62.bundle.js
__page_editor_app_actions_index_js~__page_editor_app_actions_updateEditableValues_js~__page_editor_a~7d8a279c.bundle.js
__page_editor_app_actions_index_js~__page_editor_app_actions_updateFragmentEntryLinkContent_js~__pag~dca60c80.bundle.js
__page_editor_app_actions_index_js~__page_editor_app_actions_updateLanguageId_js~__page_editor_app_c~138fdcc7.bundle.js
__page_editor_app_actions_index_js~__page_editor_app_actions_updateLayoutData_js~__page_editor_app_c~ff891ccd.bundle.js
__page_editor_app_actions_index_js~__page_editor_app_actions_updateNetwork_js~__page_editor_app_comp~b4120c31.bundle.js
__page_editor_app_actions_index_js~__page_editor_app_components_undo_undoUpdateLanguage_js.bundle.js
__page_editor_app_actions_loadReducer_js.bundle.js
__page_editor_app_actions_moveItem_js.bundle.js
__page_editor_app_actions_switchSidebarPanel_js.bundle.js
__page_editor_app_actions_switchViewportSize_js.bundle.js
__page_editor_app_actions_togglePermission_js.bundle.js
__page_editor_app_actions_toggleShowResolvedComments_js.bundle.js
__page_editor_app_actions_types_js.bundle.js
__page_editor_app_actions_unloadReducer_js.bundle.js
__page_editor_app_actions_updateColSize_js.bundle.js
__page_editor_app_actions_updateEditableValues_js.bundle.js
__page_editor_app_actions_updateFragmentEntryLinkConfiguration_js.bundle.js
__page_editor_app_actions_updateFragmentEntryLinkContent_js.bundle.js
__page_editor_app_actions_updateItemConfig_js.bundle.js
__page_editor_app_actions_updateLanguageId_js.bundle.js
__page_editor_app_actions_updateLayoutData_js.bundle.js
__page_editor_app_actions_updateNetwork_js.bundle.js
__page_editor_app_actions_updatePageContents_js.bundle.js
__page_editor_app_components_AllowedFragmentSelector_js.bundle.js
__page_editor_app_components_AllowedFragmentSelector_js~__page_editor_app_components_App_js~__page_e~e5c8a31f.bundle.js
__page_editor_app_components_AllowedFragmentTreeNode_js.bundle.js
__page_editor_app_components_App_js.bundle.js
__page_editor_app_components_CollectionItemContext_js.bundle.js
__page_editor_app_components_Controls_js.bundle.js
__page_editor_app_components_DisabledArea_js.bundle.js
__page_editor_app_components_DragPreview_js.bundle.js
__page_editor_app_components_ExperimentsLabel_js.bundle.js
__page_editor_app_components_floating_toolbar_CollectionConfigurationPanel_js.bundle.js
__page_editor_app_components_floating_toolbar_ContainerConfigurationPanel_js.bundle.js
__page_editor_app_components_floating_toolbar_FloatingToolbar_js.bundle.js
__page_editor_app_components_floating_toolbar_FragmentConfigurationPanel_js.bundle.js
__page_editor_app_components_floating_toolbar_ImagePropertiesPanel_js.bundle.js
__page_editor_app_components_floating_toolbar_LinkPanel_js.bundle.js
__page_editor_app_components_floating_toolbar_MappingPanel_js.bundle.js
__page_editor_app_components_floating_toolbar_RowConfigurationPanel_js.bundle.js
__page_editor_app_components_floating_toolbar_SaveFragmentCompositionModal_js.bundle.js
__page_editor_app_components_floating_toolbar_SectionConfigurationPanel_js.bundle.js
__page_editor_app_components_fragment_configuration_fields_CheckboxField_js.bundle.js
__page_editor_app_components_fragment_configuration_fields_CheckboxField_js~__page_editor_app_compon~06f68a98.bundle.js
__page_editor_app_components_fragment_configuration_fields_CheckboxField_js~__page_editor_app_compon~07525cbe.bundle.js
__page_editor_app_components_fragment_configuration_fields_CheckboxField_js~__page_editor_app_compon~28d9423a.bundle.js
__page_editor_app_components_fragment_configuration_fields_CheckboxField_js~__page_editor_app_compon~65dc546c.bundle.js
__page_editor_app_components_fragment_configuration_fields_CheckboxField_js~__page_editor_app_compon~708aa4d7.bundle.js
__page_editor_app_components_fragment_configuration_fields_CheckboxField_js~__page_editor_app_compon~95e9c79f.bundle.js
__page_editor_app_components_fragment_configuration_fields_CheckboxField_js~__page_editor_app_compon~cf55b5a4.bundle.js
__page_editor_app_components_fragment_configuration_fields_CollectionSelectorField_js.bundle.js
__page_editor_app_components_fragment_configuration_fields_ColorPaletteField_js.bundle.js
__page_editor_app_components_fragment_configuration_fields_ColorPaletteField_js~__page_editor_app_ut~1a3ee97b.bundle.js
__page_editor_app_components_fragment_configuration_fields_ColorPaletteField_js~__page_editor_common~f4fcf996.bundle.js
__page_editor_app_components_fragment_configuration_fields_index_js.bundle.js
__page_editor_app_components_fragment_configuration_fields_ItemSelectorField_js.bundle.js
__page_editor_app_components_fragment_configuration_fields_SelectField_js.bundle.js
__page_editor_app_components_fragment_configuration_fields_TextField_js.bundle.js
__page_editor_app_components_fragment_content_EditableProcessorContext_js.bundle.js
__page_editor_app_components_fragment_content_FragmentContentFloatingToolbar_js.bundle.js
__page_editor_app_components_fragment_content_FragmentContentInteractionsFilter_js.bundle.js
__page_editor_app_components_fragment_content_FragmentContent_js.bundle.js
__page_editor_app_components_fragment_content_FragmentContentProcessor_js.bundle.js
__page_editor_app_components_fragment_content_getAllEditables_js.bundle.js
__page_editor_app_components_fragment_content_getAllEditables_js~__page_editor_app_config_constants_~e3f2a7af.bundle.js
__page_editor_app_components_fragment_content_getAllEditables_js~__page_editor_app_processors_Backgr~a3fc757e.bundle.js
__page_editor_app_components_fragment_content_getAllEditables_js~__page_editor_app_processors_Backgr~e3871234.bundle.js
__page_editor_app_components_fragment_content_getAllEditables_js~__page_editor_app_processors_Fallba~264817bf.bundle.js
__page_editor_app_components_fragment_content_getAllEditables_js~__page_editor_app_processors_HTMLPr~8854422f.bundle.js
__page_editor_app_components_fragment_content_getAllEditables_js~__page_editor_app_processors_ImageP~29882f09.bundle.js
__page_editor_app_components_fragment_content_getAllEditables_js~__page_editor_app_processors_index_js.bundle.js
__page_editor_app_components_fragment_content_getAllEditables_js~__page_editor_app_processors_LinkPr~00dbd2b4.bundle.js
__page_editor_app_components_fragment_content_getAllEditables_js~__page_editor_app_processors_LinkPr~380c90ce.bundle.js
__page_editor_app_components_fragment_content_getAllEditables_js~__page_editor_app_processors_LinkPr~c817ea8d.bundle.js
__page_editor_app_components_fragment_content_getAllEditables_js~__page_editor_app_processors_RichTe~4092e0e4.bundle.js
__page_editor_app_components_fragment_content_getAllEditables_js~__page_editor_app_processors_TextPr~214359dd.bundle.js
__page_editor_app_components_fragment_content_getEditableElementId_js.bundle.js
__page_editor_app_components_fragment_content_getEditableElement_js.bundle.js
__page_editor_app_components_fragment_content_getEditableUniqueId_js.bundle.js
__page_editor_app_components_fragment_content_isMapped_js.bundle.js
__page_editor_app_components_fragment_content_resolveEditableValue_js.bundle.js
__page_editor_app_components_Frame_js.bundle.js
__page_editor_app_components_layout_data_items_CollectionItemWithControls_js.bundle.js
__page_editor_app_components_layout_data_items_Collection_js.bundle.js
__page_editor_app_components_layout_data_items_CollectionWithControls_js.bundle.js
__page_editor_app_components_layout_data_items_Column_js.bundle.js
__page_editor_app_components_layout_data_items_ColumnOverlayGrid_js.bundle.js
__page_editor_app_components_layout_data_items_ColumnOverlayGrid_js~__page_editor_app_components_lay~3247b8e5.bundle.js
__page_editor_app_components_layout_data_items_ColumnWithControls_js.bundle.js
__page_editor_app_components_layout_data_items_Container_js.bundle.js
__page_editor_app_components_layout_data_items_ContainerWithControls_js.bundle.js
__page_editor_app_components_layout_data_items_DropZoneWithControls_js.bundle.js
__page_editor_app_components_layout_data_items_FragmentsEditorShim_js.bundle.js
__page_editor_app_components_layout_data_items_FragmentWithControls_js.bundle.js
__page_editor_app_components_layout_data_items_hasDropZoneChild_js.bundle.js
__page_editor_app_components_layout_data_items_hasDropZoneChild_js~__page_editor_app_config_constant~5fa95d1f.bundle.js
__page_editor_app_components_layout_data_items_index_js.bundle.js
__page_editor_app_components_layout_data_items_Root_js.bundle.js
__page_editor_app_components_layout_data_items_Row_js.bundle.js
__page_editor_app_components_layout_data_items_RowWithControls_js.bundle.js
__page_editor_app_components_layout_data_items_Section_js.bundle.js
__page_editor_app_components_layout_data_items_SectionWithControls_js.bundle.js
__page_editor_app_components_Layout_js.bundle.js
__page_editor_app_components_LayoutViewport_js.bundle.js
__page_editor_app_components_ManageAllowedFragmentButton_js.bundle.js
__page_editor_app_components_ManageAllowedFragmentModal_js.bundle.js
__page_editor_app_components_MasterLayout_js.bundle.js
__page_editor_app_components_NetworkStatusBar_js.bundle.js
__page_editor_app_components_NetworkStatusBar_js~__page_editor_app_config_constants_serviceNetworkSt~abda65a5.bundle.js
__page_editor_app_components_Sidebar_js.bundle.js
__page_editor_app_components_Toolbar_js.bundle.js
__page_editor_app_components_TopperEmpty_js.bundle.js
__page_editor_app_components_Topper_js.bundle.js
__page_editor_app_components_Translation_js.bundle.js
__page_editor_app_components_Translation_js~__page_editor_app_components_fragment_content_getAllEdit~01bc661c.bundle.js
__page_editor_app_components_undo_getActionLabel_js.bundle.js
__page_editor_app_components_undo_getActionLabel_js~__page_editor_plugins_experience_actions_js~__pa~a69a6d2f.bundle.js
__page_editor_app_components_undo_undoActions_js.bundle.js
__page_editor_app_components_undo_undoDelete_js.bundle.js
__page_editor_app_components_undo_undoDuplicateItem_js.bundle.js
__page_editor_app_components_undo_undoEditableValuesAction_js.bundle.js
__page_editor_app_components_undo_undoFragmentConfiguration_js.bundle.js
__page_editor_app_components_undo_undoFragmentEntryLinks_js.bundle.js
__page_editor_app_components_undo_UndoHistory_js.bundle.js
__page_editor_app_components_undo_Undo_js.bundle.js
__page_editor_app_components_undo_undoLayoutDataAction_js.bundle.js
__page_editor_app_components_undo_undoSelectExperience_js.bundle.js
__page_editor_app_components_undo_undoUpdateLanguage_js.bundle.js
__page_editor_app_components_undo_useUndo_js.bundle.js
__page_editor_app_components_UnsafeHTML_js.bundle.js
__page_editor_app_components_ViewportSizeSelector_js.bundle.js
__page_editor_app_config_constants_backgroundImageFragmentEntryProcessor_js.bundle.js
__page_editor_app_config_constants_compatibleTypes_js.bundle.js
__page_editor_app_config_constants_editableFloatingToolbarButtons_js.bundle.js
__page_editor_app_config_constants_editableFloatingToolbarClassNames_js.bundle.js
__page_editor_app_config_constants_editableFragmentEntryProcessor_js.bundle.js
__page_editor_app_config_constants_editableTypes_js.bundle.js
__page_editor_app_config_constants_floatingToolbarConfigurations_js.bundle.js
__page_editor_app_config_constants_fragmentTypes_js.bundle.js
__page_editor_app_config_constants_freemarkerFragmentEntryProcessor_js.bundle.js
__page_editor_app_config_constants_highlightedCommentIdKey_js.bundle.js
__page_editor_app_config_constants_itemActivationOrigins_js.bundle.js
__page_editor_app_config_constants_itemTypes_js.bundle.js
__page_editor_app_config_constants_keycodes_js.bundle.js
__page_editor_app_config_constants_layoutDataFloatingToolbarButtons_js.bundle.js
__page_editor_app_config_constants_layoutDataItemTypeLabels_js.bundle.js
__page_editor_app_config_constants_layoutDataItemTypeLabels_js~__page_editor_app_utils_getLayoutData~20ce4e0c.bundle.js
__page_editor_app_config_constants_layoutDataItemTypes_js.bundle.js
__page_editor_app_config_constants_moveItemDirections_js.bundle.js
__page_editor_app_config_constants_pageTypes_js.bundle.js
__page_editor_app_config_constants_serviceNetworkStatusTypes_js.bundle.js
__page_editor_app_config_constants_translationStatusType_js.bundle.js
__page_editor_app_config_constants_viewportSizes_js.bundle.js
__page_editor_app_config_constants_viewportSizes_js~__page_editor_app_utils_getResponsiveConfig_js.bundle.js
__page_editor_app_config_index_js.bundle.js
__page_editor_app_index_js.bundle.js
__page_editor_app_processors_BackgroundImageProcessor_js.bundle.js
__page_editor_app_processors_FallbackProcessor_js.bundle.js
__page_editor_app_processors_getAlloyEditorProcessor_js.bundle.js
__page_editor_app_processors_getLinkableEditableEditorWrapper_js.bundle.js
__page_editor_app_processors_HTMLProcessor_js.bundle.js
__page_editor_app_processors_ImageProcessor_js.bundle.js
__page_editor_app_processors_index_js.bundle.js
__page_editor_app_processors_LinkProcessor_js.bundle.js
__page_editor_app_processors_RichTextProcessor_js.bundle.js
__page_editor_app_processors_TextProcessor_js.bundle.js
__page_editor_app_reducers_baseReducer_js.bundle.js
__page_editor_app_reducers_collectionsReducer_js.bundle.js
__page_editor_app_reducers_fragmentEntryLinksReducer_js.bundle.js
__page_editor_app_reducers_fragmentsReducer_js.bundle.js
__page_editor_app_reducers_index_js.bundle.js
__page_editor_app_reducers_languageIdReducer_js.bundle.js
__page_editor_app_reducers_languageReducer_js.bundle.js
__page_editor_app_reducers_layoutDataReducer_js.bundle.js
__page_editor_app_reducers_mappedInfoItemsReducer_js.bundle.js
__page_editor_app_reducers_networkReducer_js.bundle.js
__page_editor_app_reducers_pageContentsReducer_js.bundle.js
__page_editor_app_reducers_permissionsReducer_js.bundle.js
__page_editor_app_reducers_selectedViewportSizeReducer_js.bundle.js
__page_editor_app_reducers_showResolvedCommentsReducer_js.bundle.js
__page_editor_app_reducers_sidebarReducer_js.bundle.js
__page_editor_app_reducers_undoReducer_js.bundle.js
__page_editor_app_reducers_widgetsReducer_js.bundle.js
__page_editor_app_reducers_widgetsReducer_js~__page_editor_app_utils_getWidgetPath_js.bundle.js
__page_editor_app_reducers_widgetsReducer_js~__page_editor_app_utils_setWidgetUsage_js.bundle.js
__page_editor_app_selectors_selectAvailablePanels_js.bundle.js
__page_editor_app_selectors_selectAvailablePanels_js~__page_editor_app_selectors_selectAvailableSide~ac5968d2.bundle.js
__page_editor_app_selectors_selectAvailableSidebarPanels_js.bundle.js
__page_editor_app_selectors_selectCanUpdate_js.bundle.js
__page_editor_app_selectors_selectCanUpdateLayoutContent_js.bundle.js
__page_editor_app_selectors_selectEditableValueConfig_js.bundle.js
__page_editor_app_selectors_selectEditableValueConfig_js~__page_editor_app_selectors_selectEditableV~b6d0eac4.bundle.js
__page_editor_app_selectors_selectEditableValueContent_js.bundle.js
__page_editor_app_selectors_selectEditableValue_js.bundle.js
__page_editor_app_selectors_selectSegmentsExperienceId_js.bundle.js
__page_editor_app_services_CollectionService_js.bundle.js
__page_editor_app_services_ExperienceService_js.bundle.js
__page_editor_app_services_FragmentService_js.bundle.js
__page_editor_app_services_InfoItemService_js.bundle.js
__page_editor_app_services_LayoutService_js.bundle.js
__page_editor_app_services_serviceFetch_js.bundle.js
__page_editor_app_services_WidgetService_js.bundle.js
__page_editor_app_store_index_js.bundle.js
__page_editor_app_thunks_addFragmentComment_js.bundle.js
__page_editor_app_thunks_addFragmentComposition_js.bundle.js
__page_editor_app_thunks_addFragment_js.bundle.js
__page_editor_app_thunks_addItem_js.bundle.js
__page_editor_app_thunks_addWidget_js.bundle.js
__page_editor_app_thunks_deleteFragmentComment_js.bundle.js
__page_editor_app_thunks_deleteItem_js.bundle.js
__page_editor_app_thunks_duplicateItem_js.bundle.js
__page_editor_app_thunks_editFragmentComment_js.bundle.js
__page_editor_app_thunks_moveItem_js.bundle.js
__page_editor_app_thunks_multipleUndo_js.bundle.js
__page_editor_app_thunks_resizeColumns_js.bundle.js
__page_editor_app_thunks_undo_js.bundle.js
__page_editor_app_thunks_updateEditableValues_js.bundle.js
__page_editor_app_thunks_updateFragmentConfiguration_js.bundle.js
__page_editor_app_thunks_updateItemConfig_js.bundle.js
__page_editor_app_thunks_updateRowColumns_js.bundle.js
__page_editor_app_utils_getLayoutDataItemLabel_js.bundle.js
__page_editor_app_utils_getResponsiveConfig_js.bundle.js
__page_editor_app_utils_getWidgetPath_js.bundle.js
__page_editor_app_utils_setWidgetUsage_js.bundle.js
__page_editor_app_utils_useDragAndDrop_js.bundle.js
__page_editor_app_utils_useId_js.bundle.js
__page_editor_app_utils_useParseURL_js.bundle.js
__page_editor_common_components_Button_js.bundle.js
__page_editor_common_components_Button_js~__page_editor_common_components_InlineConfirm_js~__page_ed~20f79c11.bundle.js
__page_editor_common_components_Button_js~__page_editor_common_components_InlineConfirm_js~__page_ed~de566fe5.bundle.js
__page_editor_common_components_Collapse_js.bundle.js
__page_editor_common_components_Collapse_js~__page_editor_common_index_js.bundle.js
__page_editor_common_components_CollectionSelector_js.bundle.js
__page_editor_common_components_ColorPalette_js.bundle.js
__page_editor_common_components_Editor_js.bundle.js
__page_editor_common_components_Editor_js~__page_editor_plugins_comments_components_CommentForm_js.bundle.js
__page_editor_common_components_FormRow_js.bundle.js
__page_editor_common_components_ImageSelector_js.bundle.js
__page_editor_common_components_InlineConfirm_js.bundle.js
__page_editor_common_components_InvisibleFieldset_js.bundle.js
__page_editor_common_components_InvisibleFieldset_js~__page_editor_plugins_comments_components_CommentForm_js.bundle.js
__page_editor_common_components_ItemSelector_js.bundle.js
__page_editor_common_components_Loader_js.bundle.js
__page_editor_common_components_MappingSelector_js.bundle.js
__page_editor_common_components_SearchForm_js.bundle.js
__page_editor_common_components_SearchForm_js~__page_editor_common_index_js.bundle.js
__page_editor_common_components_SidebarPanelContent_js.bundle.js
__page_editor_common_components_SidebarPanelContent_js~__page_editor_plugins_mapping_components_Mapp~fc55a771.bundle.js
__page_editor_common_components_SidebarPanelHeader_js.bundle.js
__page_editor_common_components_SidebarPanelHeader_js~__page_editor_common_index_js~__page_editor_pl~80927b30.bundle.js
__page_editor_common_components_Textarea_js.bundle.js
__page_editor_common_components_UserIcon_js.bundle.js
__page_editor_common_index_js.bundle.js
__page_editor_core_AppContext_js.bundle.js
__page_editor_core_AppContext_js~__page_editor_plugins_mapping_index_js.bundle.js
__page_editor_core_createDNDBackend_js.bundle.js
__page_editor_core_debounceRAF_js.bundle.js
__page_editor_core_hooks_useLazy_js.bundle.js
__page_editor_core_hooks_useLoad_js.bundle.js
__page_editor_core_hooks_usePlugins_js.bundle.js
__page_editor_core_hooks_useSetRef_js.bundle.js
__page_editor_core_hooks_useStateSafe_js.bundle.js
__page_editor_core_hooks_useThunk_js.bundle.js
__page_editor_core_openImageSelector_js.bundle.js
__page_editor_core_openInfoItemSelector_js.bundle.js
__page_editor_plugins_comments_components_AddCommentForm_js.bundle.js
__page_editor_plugins_comments_components_CommentForm_js.bundle.js
__page_editor_plugins_comments_components_CommentsSidebar_js.bundle.js
__page_editor_plugins_comments_components_EditCommentForm_js.bundle.js
__page_editor_plugins_comments_components_FragmentComment_js.bundle.js
__page_editor_plugins_comments_components_FragmentComments_js.bundle.js
__page_editor_plugins_comments_components_FragmentEntryLinksWithComments_js.bundle.js
__page_editor_plugins_comments_components_NoCommentsMessageIcon_js.bundle.js
__page_editor_plugins_comments_components_NoCommentsMessageIcon_js~__page_editor_plugins_comments_co~f26625e8.bundle.js
__page_editor_plugins_comments_components_NoCommentsMessage_js.bundle.js
__page_editor_plugins_comments_components_ReplyCommentForm_js.bundle.js
__page_editor_plugins_comments_components_ResolveButton_js.bundle.js
__page_editor_plugins_comments_components_ResolvedCommentsToggle_js.bundle.js
__page_editor_plugins_comments_index_js.bundle.js
__page_editor_plugins_contents_components_ContentsSidebar_js.bundle.js
__page_editor_plugins_contents_components_NoPageContents_js.bundle.js
__page_editor_plugins_contents_components_PageContent_js.bundle.js
__page_editor_plugins_contents_components_PageContents_js.bundle.js
__page_editor_plugins_contents_index_js.bundle.js
__page_editor_plugins_experience_actions_createExperience_js.bundle.js
__page_editor_plugins_experience_actions_createExperience_js~__page_editor_plugins_experience_action~24e0eecf.bundle.js
__page_editor_plugins_experience_actions_deleteExperience_js.bundle.js
__page_editor_plugins_experience_actions_js.bundle.js
__page_editor_plugins_experience_actions_selectExperience_js.bundle.js
__page_editor_plugins_experience_actions_types_js.bundle.js
__page_editor_plugins_experience_actions_updateExperience_js.bundle.js
__page_editor_plugins_experience_actions_updateExperiencePriority_js.bundle.js
__page_editor_plugins_experience_components_ExperienceItem_js.bundle.js
__page_editor_plugins_experience_components_ExperienceItem_js~__page_editor_plugins_experience_compo~259decba.bundle.js
__page_editor_plugins_experience_components_ExperienceItem_js~__page_editor_plugins_experience_compo~382b8a0d.bundle.js
__page_editor_plugins_experience_components_ExperienceItem_js~__page_editor_plugins_experience_compo~6afa04c8.bundle.js
__page_editor_plugins_experience_components_ExperienceItem_js~__page_editor_plugins_experience_compo~c9a36109.bundle.js
__page_editor_plugins_experience_components_ExperienceModal_js.bundle.js
__page_editor_plugins_experience_components_ExperienceSelector_js.bundle.js
__page_editor_plugins_experience_components_ExperiencesList_js.bundle.js
__page_editor_plugins_experience_components_ExperienceToolbarSection_js.bundle.js
__page_editor_plugins_experience_components_ExperimentLabel_js.bundle.js
__page_editor_plugins_experience_components_Popover_js.bundle.js
__page_editor_plugins_experience_index_js.bundle.js
__page_editor_plugins_experience_reducers_createExperience_js.bundle.js
__page_editor_plugins_experience_reducers_createExperience_js~__page_editor_plugins_experience_reduc~313e599c.bundle.js
__page_editor_plugins_experience_reducers_createExperience_js~__page_editor_plugins_experience_reduc~8d26602f.bundle.js
__page_editor_plugins_experience_reducers_deleteExperience_js.bundle.js
__page_editor_plugins_experience_reducers_deleteExperience_js~__page_editor_plugins_experience_reduc~3fc74691.bundle.js
__page_editor_plugins_experience_reducers_index_js.bundle.js
__page_editor_plugins_experience_reducers_index_js~__page_editor_plugins_experience_reducers_selectE~8a7eb176.bundle.js
__page_editor_plugins_experience_reducers_index_js~__page_editor_plugins_experience_reducers_updateE~4f051fd9.bundle.js
__page_editor_plugins_experience_reducers_index_js~__page_editor_plugins_experience_reducers_updateE~f12de0f1.bundle.js
__page_editor_plugins_experience_reducers_selectExperience_js.bundle.js
__page_editor_plugins_experience_reducers_updateExperience_js.bundle.js
__page_editor_plugins_experience_reducers_updateExperiencePriority_js.bundle.js
__page_editor_plugins_experience_reducers_utils_js.bundle.js
__page_editor_plugins_experience_statuses_js.bundle.js
__page_editor_plugins_experience_thunks_createExperience_js.bundle.js
__page_editor_plugins_experience_thunks_removeExperience_js.bundle.js
__page_editor_plugins_experience_thunks_selectExperience_js.bundle.js
__page_editor_plugins_experience_thunks_updateExperience_js.bundle.js
__page_editor_plugins_experience_thunks_updateExperiencePriority_js.bundle.js
__page_editor_plugins_experience_types_js.bundle.js
__page_editor_plugins_experience_utils_js.bundle.js
__page_editor_plugins_fragments_components_CollectionDisplay_js.bundle.js
__page_editor_plugins_fragments_components_FragmentCard_js.bundle.js
__page_editor_plugins_fragments_components_FragmentsSidebar_js.bundle.js
__page_editor_plugins_fragments_components_LayoutElements_js.bundle.js
__page_editor_plugins_fragments_index_js.bundle.js
__page_editor_plugins_mapping_components_MappingSidebar_js.bundle.js
__page_editor_plugins_mapping_components_MappingSidebar_js~__page_editor_plugins_mapping_index_js.bundle.js
__page_editor_plugins_mapping_index_js.bundle.js
__page_editor_plugins_page_structure_components_PageStructureSidebar_js.bundle.js
__page_editor_plugins_page_structure_components_StructureTreeNode_js.bundle.js
__page_editor_plugins_page_structure_index_js.bundle.js
__page_editor_plugins_widgets_components_Widget_js.bundle.js
__page_editor_plugins_widgets_components_WidgetsSidebar_js.bundle.js
__page_editor_plugins_widgets_index_js.bundle.js
__page_editor_prop_types_BackgroundImagePropTypes_js.bundle.js
__page_editor_prop_types_ConfigurationFieldPropTypes_js.bundle.js
__page_editor_prop_types_getEditableItemPropTypes_js.bundle.js
__page_editor_prop_types_getLayoutDataItemPropTypes_js.bundle.js
__page_editor_prop_types_index_js.bundle.js
__page_editor_prop_types_LayoutDataPropTypes_js.bundle.js
And, for example, the wp-inspect
of the index entry point shows this:
$ wp-inspect build/node/bundler/webpack/__page_editor_common_index_js.bundle.js
Webpack entry [ '__page_editor_common_index_js' ] :
Implementations:
./build/node/bundler/generated/__page_editor_common_index_js.js
./src/main/resources/META-INF/resources/page_editor/common/index.js
Dependencies:
./build/node/bundler/generated/__page_editor_common_index_js.js
runtime
__page_editor_common_components_SidebarPanelHeader_js~__page_editor_common_index_js~__page_editor_pl~80927b30
__page_editor_common_components_Collapse_js~__page_editor_common_index_js
__page_editor_common_components_SearchForm_js~__page_editor_common_index_js
So, it looks like webpack knows how to do a good work of optimization.
I suppose this shows that the export everything approach is feasible.
However we now need to:
vendor.js
for every entry point). This looks somewhat costly, but feasible, because it's what the HtmlWebpackPlugin does.If point 3 is decided, we can alleviate point 4 because the user will always be able to change the optimization configuration to ease debugging (much in the same way they do when they use webpack alone, I guess).
We should also look at the sizes of the output directories in the extremes of the scale to know how much overhead in the form of copy-paste is created when splitting too aggresively. Maybe the wp-inspect
script can be modified to look at the directory as a whole and report duplication inside the bundles.
Another thing that comes to my mind is that we have a "problem" because we go against the assumptions made by webpack:
I mean, webpack assumes that each entry point will be loaded in its own HTML page, so it doesn't care about copy-paste in the same way we do, because if two different chunks that are loaded in two different pages (exclusively) share code nothing happens (apart from using hard disk and bandwidth the first time it's downloaded to the cache).
But in our case, because the AMD loader will hold those chunks in memory, every copy-paste counts against us. So we may want to avoid copy-paste due to splitting as much as we can if we want a decent performance.
Doing some autumn cleaning as we move this project to https://github.com/liferay/liferay-frontend-projects#js-toolkit
We'll be curating these and creating new ones mostly from scratch to have a better sense of where we want to go.
While developing #582 we have detected that there's a use case where an OSGi bundle wants to use its own JS modules for internal purposes, but doesn't want to export them for external use.
For example,
account-admin-web
needs these exports:so that code in JSPs like:
works.
Ideally we would like that:
account-admin-web
uses them.