From 3a5d0d921322045a5135c78aff550495c3dfc83d Mon Sep 17 00:00:00 2001 From: Piero Nicolli Date: Mon, 28 Oct 2019 08:04:46 +0100 Subject: [PATCH 01/18] First working version of lazy loading components --- babel.js | 1 + package.json | 7 +- razzle.config.js | 20 ++++ src/components/index.js | 50 +++++----- src/components/manage/Actions/Actions.jsx | 8 +- .../manage/Actions/Actions.test.jsx | 12 ++- .../__snapshots__/Actions.test.jsx.snap | 46 ++++------ src/components/manage/Add/Add.jsx | 5 +- src/components/manage/Contents/Contents.jsx | 8 +- .../Contents/ContentsPropertiesModal.jsx | 5 +- .../Contents/ContentsPropertiesModal.test.jsx | 13 ++- .../manage/Contents/ContentsRenameModal.jsx | 5 +- .../Contents/ContentsRenameModal.test.jsx | 13 ++- .../manage/Contents/ContentsTagsModal.jsx | 5 +- .../Contents/ContentsTagsModal.test.jsx | 13 ++- .../manage/Contents/ContentsWorkflowModal.jsx | 5 +- .../manage/Controlpanels/Controlpanel.jsx | 6 +- .../manage/Controlpanels/Controlpanels.jsx | 5 +- .../manage/Controlpanels/ModerateComments.jsx | 5 +- .../Controlpanels/UsersControlpanel.jsx | 11 ++- src/components/manage/Delete/Delete.jsx | 5 +- src/components/manage/Diff/Diff.jsx | 5 +- src/components/manage/Edit/Edit.jsx | 5 +- src/components/manage/History/History.jsx | 5 +- .../manage/Preferences/ChangePassword.jsx | 6 +- .../Preferences/PersonalInformation.jsx | 5 +- .../Preferences/PersonalPreferences.jsx | 5 +- src/components/manage/Sharing/Sharing.jsx | 5 +- .../manage/Widgets/SchemaWidget.jsx | 8 +- src/components/manage/Workflow/Workflow.jsx | 6 +- .../theme/Comments/CommentEditModal.jsx | 5 +- .../theme/Comments/CommentEditModal.test.jsx | 13 ++- .../theme/ContactForm/ContactForm.jsx | 6 +- src/components/theme/Login/Login.jsx | 5 +- src/components/theme/Logout/Logout.jsx | 2 +- src/components/theme/Register/Register.jsx | 5 +- src/components/theme/Search/Search.jsx | 5 +- src/components/theme/View/View.jsx | 5 +- src/config/Views.jsx | 14 ++- src/helpers/Html/Html.jsx | 27 +++--- src/helpers/Html/Html.test.jsx | 13 ++- .../Html/__snapshots__/Html.test.jsx.snap | 10 +- src/routes.js | 91 ++++++++++++++----- src/server.jsx | 21 +++-- src/start-client.jsx | 23 +++-- yarn.lock | 29 ++++++ 46 files changed, 394 insertions(+), 178 deletions(-) diff --git a/babel.js b/babel.js index e524303611..c74f316940 100644 --- a/babel.js +++ b/babel.js @@ -33,6 +33,7 @@ module.exports = function(api) { messagesDir: './build/messages/', }, ], + '@loadable/babel-plugin', ]; return { diff --git a/package.json b/package.json index 9672311fef..8dac110fc9 100644 --- a/package.json +++ b/package.json @@ -168,6 +168,10 @@ "@babel/plugin-proposal-throw-expressions": "7.2.0", "@babel/plugin-syntax-import-meta": "7.2.0", "@babel/preset-stage-0": "7.0.0", + "@loadable/babel-plugin": "5.10.3", + "@loadable/component": "5.10.3", + "@loadable/server": "5.10.3", + "@loadable/webpack-plugin": "5.7.1", "@testing-library/cypress": "5.0.2", "@testing-library/jest-dom": "4.2.0", "@testing-library/react": "9.3.0", @@ -285,6 +289,5 @@ "svgo-loader": "2.1.0", "tlds": "1.203.1", "xmlrpc": "1.3.2" - }, - "devDependencies": {} + } } diff --git a/razzle.config.js b/razzle.config.js index 8c16b41141..d3822b0871 100644 --- a/razzle.config.js +++ b/razzle.config.js @@ -9,6 +9,7 @@ const autoprefixer = require('autoprefixer'); const makeLoaderFinder = require('razzle-dev-utils/makeLoaderFinder'); const nodeExternals = require('webpack-node-externals'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); +const LoadablePlugin = require('@loadable/webpack-plugin'); const fs = require('fs'); const { map } = require('lodash'); const glob = require('glob').sync; @@ -125,6 +126,25 @@ module.exports = { __SERVER__: false, }), ); + + config.plugins.push( + new LoadablePlugin({ + outputAsset: false, + writeToDisk: { filename: path.resolve(__dirname, 'build') }, + }), + ); + + config.output.filename = dev + ? 'static/js/[name].js' + : 'static/js/[name].[chunkhash:8].js'; + + config.optimization = Object.assign({}, config.optimization, { + runtimeChunk: true, + splitChunks: { + chunks: 'all', + name: dev, + }, + }); } if (target === 'node') { diff --git a/src/components/index.js b/src/components/index.js index f11b41fb51..235f353a72 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -5,7 +5,7 @@ */ export Anontools from '@plone/volto/components/theme/Anontools/Anontools'; export Breadcrumbs from '@plone/volto/components/theme/Breadcrumbs/Breadcrumbs'; -export ContactForm from '@plone/volto/components/theme/ContactForm/ContactForm'; +// export ContactForm from '@plone/volto/components/theme/ContactForm/ContactForm'; export Footer from '@plone/volto/components/theme/Footer/Footer'; export Header from '@plone/volto/components/theme/Header/Header'; export Icon from '@plone/volto/components/theme/Icon/Icon'; @@ -13,32 +13,32 @@ export Logo from '@plone/volto/components/theme/Logo/Logo'; export Navigation from '@plone/volto/components/theme/Navigation/Navigation'; export SearchWidget from '@plone/volto/components/theme/SearchWidget/SearchWidget'; export Title from '@plone/volto/components/theme/Title/Title'; -export App from '@plone/volto/components/theme/App/App'; +// export App from '@plone/volto/components/theme/App/App'; export DefaultView from '@plone/volto/components/theme/View/DefaultView'; export FileView from '@plone/volto/components/theme/View/FileView'; export ImageView from '@plone/volto/components/theme/View/ImageView'; export NewsItemView from '@plone/volto/components/theme/View/NewsItemView'; export ListingView from '@plone/volto/components/theme/View/ListingView'; -export Login from '@plone/volto/components/theme/Login/Login'; -export Logout from '@plone/volto/components/theme/Logout/Logout'; -export NotFound from '@plone/volto/components/theme/NotFound/NotFound'; +// export Login from '@plone/volto/components/theme/Login/Login'; +// export Logout from '@plone/volto/components/theme/Logout/Logout'; +// export NotFound from '@plone/volto/components/theme/NotFound/NotFound'; export Pagination from '@plone/volto/components/theme/Pagination/Pagination'; export SummaryView from '@plone/volto/components/theme/View/SummaryView'; -export Search from '@plone/volto/components/theme/Search/Search'; +// export Search from '@plone/volto/components/theme/Search/Search'; export SearchTags from '@plone/volto/components/theme/Search/SearchTags'; export TabularView from '@plone/volto/components/theme/View/TabularView'; -export View from '@plone/volto/components/theme/View/View'; +// export View from '@plone/volto/components/theme/View/View'; export Comments from '@plone/volto/components/theme/Comments/Comments'; export CommentEditModal from '@plone/volto/components/theme/Comments/CommentEditModal'; export SocialSharing from '@plone/volto/components/theme/SocialSharing/SocialSharing'; export Tags from '@plone/volto/components/theme/Tags/Tags'; -export Register from '@plone/volto/components/theme/Register/Register'; -export PasswordReset from '@plone/volto/components/theme/PasswordReset/PasswordReset'; -export RequestPasswordReset from '@plone/volto/components/theme/PasswordReset/RequestPasswordReset'; +// export Register from '@plone/volto/components/theme/Register/Register'; +// export PasswordReset from '@plone/volto/components/theme/PasswordReset/PasswordReset'; +// export RequestPasswordReset from '@plone/volto/components/theme/PasswordReset/RequestPasswordReset'; export Actions from '@plone/volto/components/manage/Actions/Actions'; -export Add from '@plone/volto/components/manage/Add/Add'; -export Contents from '@plone/volto/components/manage/Contents/Contents'; +// export Add from '@plone/volto/components/manage/Add/Add'; +// export Contents from '@plone/volto/components/manage/Contents/Contents'; export ContentsIndexHeader from '@plone/volto/components/manage/Contents/ContentsIndexHeader'; export ContentsItem from '@plone/volto/components/manage/Contents/ContentsItem'; export ContentsUploadModal from '@plone/volto/components/manage/Contents/ContentsUploadModal'; @@ -46,24 +46,24 @@ export ContentsPropertiesModal from '@plone/volto/components/manage/Contents/Con export ContentsRenameModal from '@plone/volto/components/manage/Contents/ContentsRenameModal'; export ContentsWorkflowModal from '@plone/volto/components/manage/Contents/ContentsWorkflowModal'; export ContentsTagsModal from '@plone/volto/components/manage/Contents/ContentsTagsModal'; -export Controlpanel from '@plone/volto/components/manage/Controlpanels/Controlpanel'; -export Controlpanels from '@plone/volto/components/manage/Controlpanels/Controlpanels'; -export ModerateComments from '@plone/volto/components/manage/Controlpanels/ModerateComments'; -export UsersControlpanel from '@plone/volto/components/manage/Controlpanels/UsersControlpanel'; +// export Controlpanel from '@plone/volto/components/manage/Controlpanels/Controlpanel'; +// export Controlpanels from '@plone/volto/components/manage/Controlpanels/Controlpanels'; +// export ModerateComments from '@plone/volto/components/manage/Controlpanels/ModerateComments'; +// export UsersControlpanel from '@plone/volto/components/manage/Controlpanels/UsersControlpanel'; export UsersControlpanelGroups from '@plone/volto/components/manage/Controlpanels/UsersControlpanelGroups'; export VersionOverview from '@plone/volto/components/manage/Controlpanels/VersionOverview'; -export Delete from '@plone/volto/components/manage/Delete/Delete'; +// export Delete from '@plone/volto/components/manage/Delete/Delete'; export UsersControlpanelUser from '@plone/volto/components/manage/Controlpanels/UsersControlpanelUser'; -export Diff from '@plone/volto/components/manage/Diff/Diff'; +// export Diff from '@plone/volto/components/manage/Diff/Diff'; export DiffField from '@plone/volto/components/manage/Diff/DiffField'; export Display from '@plone/volto/components/manage/Display/Display'; -export Edit from '@plone/volto/components/manage/Edit/Edit'; +// export Edit from '@plone/volto/components/manage/Edit/Edit'; export Form from '@plone/volto/components/manage/Form/Form'; export Field from '@plone/volto/components/manage/Form/Field'; -export ModalForm from '@plone/volto/components/manage/Form/ModalForm'; -export History from '@plone/volto/components/manage/History/History'; +// export ModalForm from '@plone/volto/components/manage/Form/ModalForm'; +// export History from '@plone/volto/components/manage/History/History'; export Messages from '@plone/volto/components/manage/Messages/Messages'; -export ChangePassword from '@plone/volto/components/manage/Preferences/ChangePassword'; +// export ChangePassword from '@plone/volto/components/manage/Preferences/ChangePassword'; export PersonalPreferences from '@plone/volto/components/manage/Preferences/PersonalPreferences'; export PersonalInformation from '@plone/volto/components/manage/Preferences/PersonalInformation'; export ArrayWidget from '@plone/volto/components/manage/Widgets/ArrayWidget'; @@ -78,10 +78,10 @@ export SelectWidget from '@plone/volto/components/manage/Widgets/SelectWidget'; export SidebarTextWidget from '@plone/volto/components/manage/Widgets/SidebarTextWidget'; export Sidebar from '@plone/volto/components/manage/Sidebar/Sidebar'; export SidebarPortal from '@plone/volto/components/manage/Sidebar/SidebarPortal'; -export Sharing from '@plone/volto/components/manage/Sharing/Sharing'; +// export Sharing from '@plone/volto/components/manage/Sharing/Sharing'; export TextareaWidget from '@plone/volto/components/manage/Widgets/TextareaWidget'; export TextWidget from '@plone/volto/components/manage/Widgets/TextWidget'; -export Toolbar from '@plone/volto/components/manage/Toolbar/Toolbar'; +// export Toolbar from '@plone/volto/components/manage/Toolbar/Toolbar'; export WysiwygWidget from '@plone/volto/components/manage/Widgets/WysiwygWidget'; export Workflow from '@plone/volto/components/manage/Workflow/Workflow'; @@ -111,4 +111,4 @@ export ImageSidebar from '@plone/volto/components/manage/Sidebar/ImageSidebar'; export PersonalTools from '@plone/volto/components/manage/Toolbar/PersonalTools'; export More from '@plone/volto/components/manage/Toolbar/More'; export Types from '@plone/volto/components/manage/Toolbar/Types'; -export Toast from '@plone/volto/components/manage/Toast/Toast'; +// export Toast from '@plone/volto/components/manage/Toast/Toast'; diff --git a/src/components/manage/Actions/Actions.jsx b/src/components/manage/Actions/Actions.jsx index 81b17f2073..868fd53b71 100644 --- a/src/components/manage/Actions/Actions.jsx +++ b/src/components/manage/Actions/Actions.jsx @@ -11,10 +11,16 @@ import { Link } from 'react-router-dom'; import { Dropdown, Icon } from 'semantic-ui-react'; import { toast } from 'react-toastify'; import { FormattedMessage, defineMessages, injectIntl } from 'react-intl'; +import loadable from '@loadable/component'; import { cut, copy, copyContent, moveContent } from '../../../actions'; import { getBaseUrl } from '../../../helpers'; -import { ContentsRenameModal, Toast } from '../../../components'; +// import { ContentsRenameModal, Toast } from '../../../components'; + +const ContentsRenameModal = loadable(() => + import('../Contents/ContentsRenameModal'), +); +const Toast = loadable(() => import('../Toast/Toast')); const messages = defineMessages({ cut: { diff --git a/src/components/manage/Actions/Actions.test.jsx b/src/components/manage/Actions/Actions.test.jsx index ba2032f6a1..73934675f2 100644 --- a/src/components/manage/Actions/Actions.test.jsx +++ b/src/components/manage/Actions/Actions.test.jsx @@ -1,8 +1,9 @@ +import '@testing-library/jest-dom/extend-expect'; import React from 'react'; -import renderer from 'react-test-renderer'; import configureStore from 'redux-mock-store'; import { Provider } from 'react-intl-redux'; import { MemoryRouter } from 'react-router-dom'; +import { render, wait } from '@testing-library/react'; import Actions from './Actions'; @@ -13,7 +14,7 @@ jest.mock('../Contents/ContentsRenameModal', () => ); describe('Actions', () => { - it('renders an actions component', () => { + it('renders an actions component', async () => { const store = mockStore({ actions: { actions: { @@ -121,14 +122,15 @@ describe('Actions', () => { messages: {}, }, }); - const component = renderer.create( + const { container } = render( , ); - const json = component.toJSON(); - expect(json).toMatchSnapshot(); + await wait(() => { + expect(container.firstChild).toMatchSnapshot(); + }); }); }); diff --git a/src/components/manage/Actions/__snapshots__/Actions.test.jsx.snap b/src/components/manage/Actions/__snapshots__/Actions.test.jsx.snap index 3b86004e99..af0da70919 100644 --- a/src/components/manage/Actions/__snapshots__/Actions.test.jsx.snap +++ b/src/components/manage/Actions/__snapshots__/Actions.test.jsx.snap @@ -2,91 +2,81 @@ exports[`Actions renders an actions component 1`] = `