From 722988ef8e796f7a1b83dc9c4ad650caf914ed6b Mon Sep 17 00:00:00 2001 From: jesusbotella Date: Mon, 30 Mar 2020 19:01:01 +0200 Subject: [PATCH] Split and Lazy loading for routes, and webpack optimizations --- .../javascripts/dashboard/statics/static.js | 7 +- .../javascripts/new-dashboard/router/index.js | 216 ++---------------- .../router/routes/connected_apps.js | 19 ++ .../new-dashboard/router/routes/data.js | 48 ++++ .../new-dashboard/router/routes/home.js | 19 ++ .../new-dashboard/router/routes/maps.js | 58 +++++ .../router/routes/notifications.js | 18 ++ .../new-dashboard/router/routes/oauth_apps.js | 48 ++++ .../router/{ => routes}/onboarding.js | 5 +- .../new-dashboard/router/routes/search.js | 28 +++ .../new-dashboard/router/routes/solutions.js | 15 ++ webpack/static-pages/webpack.dev.config.js | 23 +- webpack/static-pages/webpack.prod.config.js | 32 ++- webpack/v4/webpack.base.config.js | 5 +- 14 files changed, 320 insertions(+), 221 deletions(-) create mode 100644 lib/assets/javascripts/new-dashboard/router/routes/connected_apps.js create mode 100644 lib/assets/javascripts/new-dashboard/router/routes/data.js create mode 100644 lib/assets/javascripts/new-dashboard/router/routes/home.js create mode 100644 lib/assets/javascripts/new-dashboard/router/routes/maps.js create mode 100644 lib/assets/javascripts/new-dashboard/router/routes/notifications.js create mode 100644 lib/assets/javascripts/new-dashboard/router/routes/oauth_apps.js rename lib/assets/javascripts/new-dashboard/router/{ => routes}/onboarding.js (71%) create mode 100644 lib/assets/javascripts/new-dashboard/router/routes/search.js create mode 100644 lib/assets/javascripts/new-dashboard/router/routes/solutions.js diff --git a/lib/assets/javascripts/dashboard/statics/static.js b/lib/assets/javascripts/dashboard/statics/static.js index df0b5b3314..2a16bf726a 100644 --- a/lib/assets/javascripts/dashboard/statics/static.js +++ b/lib/assets/javascripts/dashboard/statics/static.js @@ -1,9 +1,12 @@ var CartoNode = require('../../../../../vendor/assets/javascripts/carto-node/carto-node.js'); -var PACKAGE = require('../../../../../package.json'); var UrlHelper = require('./helpers/url'); var Redirector = require('../helpers/redirector'); -var version = PACKAGE.version; +/* global __ASSETS_VERSION__:false */ +// __ASSETS_VERSION__ is injected via Webpack to avoid requiring +// whole package.json file +var version = __ASSETS_VERSION__; + var AssetsVersionHelper = require('../helpers/assets-version'); var GOOGLE_MAPS_SCRIPT_SRC = '//maps.googleapis.com/maps/api/js?v=3.32&sensor=false'; var VISUALIZATION_ERROR = 'Visualization not viewable'; diff --git a/lib/assets/javascripts/new-dashboard/router/index.js b/lib/assets/javascripts/new-dashboard/router/index.js index 1435108bb2..db84efc4cc 100644 --- a/lib/assets/javascripts/new-dashboard/router/index.js +++ b/lib/assets/javascripts/new-dashboard/router/index.js @@ -1,33 +1,15 @@ import Vue from 'vue'; import Router from 'vue-router'; -// Pages -import Home from 'new-dashboard/pages/Home/Home'; -import Solutions from 'new-dashboard/pages/Solutions'; -import Maps from 'new-dashboard/pages/Maps/Maps'; -import Carto from 'new-dashboard/pages/Maps/Carto'; -import External from 'new-dashboard/pages/Maps/External'; -import Data from 'new-dashboard/pages/Data/Data'; -import Datasets from 'new-dashboard/pages/Data/Datasets'; -import Catalog from 'new-dashboard/pages/Data/Catalog'; -import CatalogDetail from 'new-dashboard/pages/Data/CatalogDetail'; -import Search from 'new-dashboard/pages/Search'; -import Notifications from 'new-dashboard/pages/Notifications'; -import ConnectedApps from 'new-dashboard/pages/Apps/ConnectedApps'; -import OAuthApps from 'new-dashboard/pages/Apps/OAuthApps'; -import EditApp from 'new-dashboard/components/Apps/EditApp'; -import CreateApp from 'new-dashboard/components/Apps/CreateApp'; -import AppList from 'new-dashboard/components/Apps/AppList'; - -// Hooks -import { mapsBeforeEnter, externalMapsBeforeEnter, datasetsBeforeEnter, catalogDetailBeforeEnter } from 'new-dashboard/router/hooks/check-navigation'; -import updateSearchParams from 'new-dashboard/router/hooks/update-search-params'; -import fetchNotifications from 'new-dashboard/router/hooks/fetch-notifications'; -import { fetchOAuthApps, fetchIfAppNotFound } from 'new-dashboard/router/hooks/fetch-oauth-apps'; -import fetchConnectedApps from 'new-dashboard/router/hooks/fetch-connected-apps'; - -// Modules -import onboarding from './onboarding'; +// Routes +import HomeRoutes from './routes/home'; +import SolutionsRoutes from './routes/solutions'; +import MapsRoutes from './routes/maps'; +import DataRoutes from './routes/data'; +import SearchRoutes from './routes/search'; +import NotificationRoutes from './routes/notifications'; +import OAuthRoutes from './routes/oauth_apps'; +import ConnectedAppsRoutes from './routes/connected_apps'; Vue.use(Router); @@ -44,177 +26,17 @@ const router = new Router({ /* Warning: If any of the following paths is changed, remember to update staticRoute props in NavigationBar component */ routes: [ - { - path: '/', - name: 'home', - component: Home, - meta: { - title: () => 'Home | CARTO' - }, - children: onboarding - }, - { - path: '/solutions', - name: 'solutions', - component: Solutions, - meta: { - title: () => 'Solutions | CARTO' - } - }, - { - path: '/maps/:filter?', - component: Maps, - meta: { - title: () => 'Maps | CARTO' - }, - children: [ - { - path: 'external', - name: 'external', - component: External, - meta: { - title: () => 'Kepler.gl Maps | CARTO' - }, - beforeEnter: externalMapsBeforeEnter - }, - { - path: '', - name: 'maps', - component: Carto, - meta: { - title: () => 'Maps | CARTO' - }, - beforeEnter: mapsBeforeEnter - } - ] - }, - { - path: '/maps/external/:filter', - name: 'external_filtered', - component: Maps, - meta: { - title: () => 'Kepler.gl Maps | CARTO' - }, - children: [ - { - path: '', - name: 'external_filtered', - component: External, - meta: { - title: () => 'Kepler.gl Maps | CARTO' - }, - beforeEnter: externalMapsBeforeEnter - } - ] - }, - { - path: '/datasets/:filter?', - component: Data, - meta: { - title: () => 'Data | CARTO' - }, - children: [ - { - path: 'catalog', - name: 'catalog', - component: Catalog, - meta: { - title: () => 'Catalog | CARTO' - } - }, - { - path: '', - component: Datasets, - name: 'datasets', - meta: { - title: () => 'Data | CARTO' - }, - beforeEnter: datasetsBeforeEnter - } - ] - }, - { - path: '/datasets/catalog/:id', - name: 'catalog_detail', - component: CatalogDetail, - meta: { - title: () => 'Detail Dataset Catalog | CARTO' - }, - beforeEnter: catalogDetailBeforeEnter - }, - { - path: '/search/:query', - name: 'search', - component: Search, - meta: { - title: route => `${route.params.query} · Search | CARTO` - }, - beforeEnter: updateSearchParams - }, - { - path: '/search/tag/:tag', - name: 'tagSearch', - component: Search, - meta: { - title: route => `${route.params.tag} · Search | CARTO` - }, - beforeEnter: updateSearchParams - }, - { - path: '/notifications', - name: 'notifications', - component: Notifications, - meta: { - title: () => 'Notifications | CARTO' - }, - beforeEnter: fetchNotifications - }, - { - path: '/oauth_apps', - component: OAuthApps, - meta: { - title: () => 'OAuth Apps | CARTO' - }, - children: [ - { - path: '', - name: 'oauth_apps_list', - component: AppList, - meta: { - title: () => 'OAuth Apps | CARTO' - }, - beforeEnter: fetchOAuthApps - }, - { - path: 'new', - name: 'oauth_app_new', - component: CreateApp, - meta: { - title: () => 'Create a new OAuth app | CARTO' - } - }, - { - path: 'edit/:id', - name: 'oauth_app_edit', - component: EditApp, - meta: { - title: () => 'Edit an existing OAuth App | CARTO' - }, - beforeEnter: fetchIfAppNotFound - } - ] - }, - { - path: '/connected_apps', - name: 'connected_apps', - component: ConnectedApps, - meta: { - title: () => 'Connected Apps | CARTO' - }, - beforeEnter: fetchConnectedApps - } + ...HomeRoutes, + ...SolutionsRoutes, + ...MapsRoutes, + ...DataRoutes, + ...SearchRoutes, + ...NotificationRoutes, + ...OAuthRoutes, + ...ConnectedAppsRoutes ], - scrollBehavior (to, from, savedPosition) { + + scrollBehavior () { return { x: 0, y: 0 }; } }); diff --git a/lib/assets/javascripts/new-dashboard/router/routes/connected_apps.js b/lib/assets/javascripts/new-dashboard/router/routes/connected_apps.js new file mode 100644 index 0000000000..c1f98b64f3 --- /dev/null +++ b/lib/assets/javascripts/new-dashboard/router/routes/connected_apps.js @@ -0,0 +1,19 @@ +// Lazy Pages +const ConnectedApps = () => import('new-dashboard/pages/Apps/ConnectedApps'); + +// Hooks +import fetchConnectedApps from 'new-dashboard/router/hooks/fetch-connected-apps'; + +const routes = [ + { + path: '/connected_apps', + name: 'connected_apps', + component: ConnectedApps, + meta: { + title: () => 'Connected Apps | CARTO' + }, + beforeEnter: fetchConnectedApps + } +]; + +export default routes; diff --git a/lib/assets/javascripts/new-dashboard/router/routes/data.js b/lib/assets/javascripts/new-dashboard/router/routes/data.js new file mode 100644 index 0000000000..217e362917 --- /dev/null +++ b/lib/assets/javascripts/new-dashboard/router/routes/data.js @@ -0,0 +1,48 @@ +// Lazy Pages +const Data = () => import('new-dashboard/pages/Data/Data'); +const Datasets = () => import('new-dashboard/pages/Data/Datasets'); +const Catalog = () => import('new-dashboard/pages/Data/Catalog'); +const CatalogDetail = () => import('new-dashboard/pages/Data/CatalogDetail'); + +// Hooks +import { datasetsBeforeEnter, catalogDetailBeforeEnter } from 'new-dashboard/router/hooks/check-navigation'; + +const routes = [ + { + path: '/datasets/:filter?', + component: Data, + meta: { + title: () => 'Data | CARTO' + }, + children: [ + { + path: 'catalog', + name: 'catalog', + component: Catalog, + meta: { + title: () => 'Catalog | CARTO' + } + }, + { + path: '', + component: Datasets, + name: 'datasets', + meta: { + title: () => 'Data | CARTO' + }, + beforeEnter: datasetsBeforeEnter + } + ] + }, + { + path: '/datasets/catalog/:id', + name: 'catalog_detail', + component: CatalogDetail, + meta: { + title: () => 'Detail Dataset Catalog | CARTO' + }, + beforeEnter: catalogDetailBeforeEnter + }, +]; + +export default routes; diff --git a/lib/assets/javascripts/new-dashboard/router/routes/home.js b/lib/assets/javascripts/new-dashboard/router/routes/home.js new file mode 100644 index 0000000000..c6511e76c0 --- /dev/null +++ b/lib/assets/javascripts/new-dashboard/router/routes/home.js @@ -0,0 +1,19 @@ +// Lazy Pages +import Home from 'new-dashboard/pages/Home/Home'; + +// Modules +import onboarding from './onboarding'; + +const routes = [ + { + path: '/', + name: 'home', + component: Home, + meta: { + title: () => 'Home | CARTO' + }, + children: onboarding + } +]; + +export default routes; diff --git a/lib/assets/javascripts/new-dashboard/router/routes/maps.js b/lib/assets/javascripts/new-dashboard/router/routes/maps.js new file mode 100644 index 0000000000..17c050afeb --- /dev/null +++ b/lib/assets/javascripts/new-dashboard/router/routes/maps.js @@ -0,0 +1,58 @@ +// Lazy Pages +const Maps = () => import('new-dashboard/pages/Maps/Maps'); +const Carto = () => import('new-dashboard/pages/Maps/Carto'); +const External = () => import('new-dashboard/pages/Maps/Carto'); + +// Hooks +import { mapsBeforeEnter, externalMapsBeforeEnter } from 'new-dashboard/router/hooks/check-navigation'; + +const routes = [ + { + path: '/maps/:filter?', + component: Maps, + meta: { + title: () => 'Maps | CARTO' + }, + children: [ + { + path: '', + name: 'maps', + component: Carto, + meta: { + title: () => 'Maps | CARTO' + }, + beforeEnter: mapsBeforeEnter + }, + { + path: 'external', + name: 'external', + component: External, + meta: { + title: () => 'Kepler.gl Maps | CARTO' + }, + beforeEnter: externalMapsBeforeEnter + } + ] + }, + { + path: '/maps/external/:filter', + name: 'external_filtered', + component: Maps, + meta: { + title: () => 'Kepler.gl Maps | CARTO' + }, + children: [ + { + path: '', + name: 'external_filtered', + component: External, + meta: { + title: () => 'Kepler.gl Maps | CARTO' + }, + beforeEnter: externalMapsBeforeEnter + } + ] + }, +]; + +export default routes; diff --git a/lib/assets/javascripts/new-dashboard/router/routes/notifications.js b/lib/assets/javascripts/new-dashboard/router/routes/notifications.js new file mode 100644 index 0000000000..2f95a608a4 --- /dev/null +++ b/lib/assets/javascripts/new-dashboard/router/routes/notifications.js @@ -0,0 +1,18 @@ +// Lazy Pages +const Notifications = () => import('new-dashboard/pages/Notifications'); + +import fetchNotifications from 'new-dashboard/router/hooks/fetch-notifications'; + +const routes = [ + { + path: '/notifications', + name: 'notifications', + component: Notifications, + meta: { + title: () => 'Notifications | CARTO' + }, + beforeEnter: fetchNotifications + } +]; + +export default routes; diff --git a/lib/assets/javascripts/new-dashboard/router/routes/oauth_apps.js b/lib/assets/javascripts/new-dashboard/router/routes/oauth_apps.js new file mode 100644 index 0000000000..fdfed7b1c3 --- /dev/null +++ b/lib/assets/javascripts/new-dashboard/router/routes/oauth_apps.js @@ -0,0 +1,48 @@ +// Lazy Pages +const OAuthApps = () => import('new-dashboard/pages/Apps/OAuthApps'); +const EditApp = () => import('new-dashboard/components/Apps/EditApp'); +const CreateApp = () => import('new-dashboard/components/Apps/CreateApp'); +const AppList = () => import('new-dashboard/components/Apps/AppList'); + +// Hooks +import { fetchOAuthApps, fetchIfAppNotFound } from 'new-dashboard/router/hooks/fetch-oauth-apps'; + +const routes = [ + { + path: '/oauth_apps', + component: OAuthApps, + meta: { + title: () => 'OAuth Apps | CARTO' + }, + children: [ + { + path: '', + name: 'oauth_apps_list', + component: AppList, + meta: { + title: () => 'OAuth Apps | CARTO' + }, + beforeEnter: fetchOAuthApps + }, + { + path: 'new', + name: 'oauth_app_new', + component: CreateApp, + meta: { + title: () => 'Create a new OAuth app | CARTO' + } + }, + { + path: 'edit/:id', + name: 'oauth_app_edit', + component: EditApp, + meta: { + title: () => 'Edit an existing OAuth App | CARTO' + }, + beforeEnter: fetchIfAppNotFound + } + ] + } +]; + +export default routes; diff --git a/lib/assets/javascripts/new-dashboard/router/onboarding.js b/lib/assets/javascripts/new-dashboard/router/routes/onboarding.js similarity index 71% rename from lib/assets/javascripts/new-dashboard/router/onboarding.js rename to lib/assets/javascripts/new-dashboard/router/routes/onboarding.js index c00783251b..4ce8984f84 100644 --- a/lib/assets/javascripts/new-dashboard/router/onboarding.js +++ b/lib/assets/javascripts/new-dashboard/router/routes/onboarding.js @@ -1,5 +1,6 @@ -import OnboardingWelcome from 'new-dashboard/components/Onboarding/distributor/Distributor'; -import Wizard from 'new-dashboard/components/Onboarding/wizard/Wizard'; +// Lazy Pages +const OnboardingWelcome = () => import('new-dashboard/components/Onboarding/distributor/Distributor'); +const Wizard = () => import('new-dashboard/components/Onboarding/wizard/Wizard'); const onboarding = [ { diff --git a/lib/assets/javascripts/new-dashboard/router/routes/search.js b/lib/assets/javascripts/new-dashboard/router/routes/search.js new file mode 100644 index 0000000000..a42937ef57 --- /dev/null +++ b/lib/assets/javascripts/new-dashboard/router/routes/search.js @@ -0,0 +1,28 @@ +// Lazy Pages +const Search = () => import('new-dashboard/pages/Search'); + +// Hooks +import updateSearchParams from 'new-dashboard/router/hooks/update-search-params'; + +const routes = [ + { + path: '/search/:query', + name: 'search', + component: Search, + meta: { + title: route => `${route.params.query} · Search | CARTO` + }, + beforeEnter: updateSearchParams + }, + { + path: '/search/tag/:tag', + name: 'tagSearch', + component: Search, + meta: { + title: route => `${route.params.tag} · Search | CARTO` + }, + beforeEnter: updateSearchParams + } +]; + +export default routes; diff --git a/lib/assets/javascripts/new-dashboard/router/routes/solutions.js b/lib/assets/javascripts/new-dashboard/router/routes/solutions.js new file mode 100644 index 0000000000..f5c9a485d7 --- /dev/null +++ b/lib/assets/javascripts/new-dashboard/router/routes/solutions.js @@ -0,0 +1,15 @@ +// Lazy Pages +const Solutions = () => import('new-dashboard/pages/Solutions'); + +const routes = [ + { + path: '/solutions', + name: 'solutions', + component: Solutions, + meta: { + title: () => 'Solutions | CARTO' + } + } +]; + +export default routes; diff --git a/webpack/static-pages/webpack.dev.config.js b/webpack/static-pages/webpack.dev.config.js index 301a54bee6..c8fa201a81 100644 --- a/webpack/static-pages/webpack.dev.config.js +++ b/webpack/static-pages/webpack.dev.config.js @@ -1,5 +1,6 @@ const HtmlWebpackPlugin = require('html-webpack-plugin'); const path = require('path'); +const webpack = require('webpack'); const webpackFiles = require('../../lib/build/files/webpack_files'); const Package = require('./../../package.json'); @@ -13,11 +14,19 @@ module.exports = { publicPath: '/assets/' }, devtool: 'source-map', - plugins: Object.keys(webpackFiles).map((entryName) => { - return new HtmlWebpackPlugin({ - filename: path.resolve(__dirname, `../../public/static/${entryName}/index.html`), - template: path.resolve(__dirname, '../../lib/assets/javascripts/dashboard/statics/index.jst.ejs'), - config: webpackFiles[entryName] - }); - }) + plugins: [ + new webpack.DefinePlugin({ + __ASSETS_VERSION__: `'${VERSION}'` + }), + + ...Object.keys(webpackFiles.htmlFiles).map((entryName) => { + return new HtmlWebpackPlugin({ + inject: false, + cache: false, + filename: webpackFiles.htmlFiles[entryName].filename || path.resolve(__dirname, `../../public/static/${entryName}/index.html`), + template: path.resolve(__dirname, '../../lib/assets/javascripts/dashboard/statics/index.jst.ejs'), + config: webpackFiles.htmlFiles[entryName] + }); + }) + ] }; diff --git a/webpack/static-pages/webpack.prod.config.js b/webpack/static-pages/webpack.prod.config.js index c5386ccd75..59edc3d56d 100644 --- a/webpack/static-pages/webpack.prod.config.js +++ b/webpack/static-pages/webpack.prod.config.js @@ -1,27 +1,35 @@ const HtmlWebpackPlugin = require('html-webpack-plugin'); const path = require('path'); +const webpack = require('webpack'); const webpackFiles = require('../../lib/build/files/webpack_files'); const Package = require('./../../package.json'); const VERSION = Package.version; module.exports = { - entry: Object.assign({ - main: './lib/assets/javascripts/dashboard/statics/static.js' - }, webpackFiles.gearEntryPoints), + entry: Object.assign( + { main: './lib/assets/javascripts/dashboard/statics/static.js' }, + webpackFiles.gearEntryPoints + ), output: { filename: `${VERSION}/javascripts/[name].js`, path: path.resolve(__dirname, '../../public/assets'), publicPath: '/assets/' }, devtool: 'source-map', - plugins: Object.keys(webpackFiles.htmlFiles).map((entryName) => { - return new HtmlWebpackPlugin({ - inject: false, - cache: false, - filename: webpackFiles.htmlFiles[entryName].filename || path.resolve(__dirname, `../../public/static/${entryName}/index.html`), - template: path.resolve(__dirname, '../../lib/assets/javascripts/dashboard/statics/index.jst.ejs'), - config: webpackFiles.htmlFiles[entryName] - }); - }) + plugins: [ + new webpack.DefinePlugin({ + __ASSETS_VERSION__: `'${VERSION}'` + }), + + ...Object.keys(webpackFiles.htmlFiles).map((entryName) => { + return new HtmlWebpackPlugin({ + inject: false, + cache: false, + filename: webpackFiles.htmlFiles[entryName].filename || path.resolve(__dirname, `../../public/static/${entryName}/index.html`), + template: path.resolve(__dirname, '../../lib/assets/javascripts/dashboard/statics/index.jst.ejs'), + config: webpackFiles.htmlFiles[entryName] + }); + }) + ] }; diff --git a/webpack/v4/webpack.base.config.js b/webpack/v4/webpack.base.config.js index 4565379ffd..61c3a6818f 100644 --- a/webpack/v4/webpack.base.config.js +++ b/webpack/v4/webpack.base.config.js @@ -18,7 +18,8 @@ module.exports = { entry: entryPoints, output: { filename: `${version}/javascripts/[name].js`, - path: rootDir('public/assets') + path: rootDir('public/assets'), + publicPath: http_path_prefix + '/assets/' }, resolve: { extensions: ['.js', '.vue', '.json', '.scss'], @@ -28,6 +29,8 @@ module.exports = { }, devtool: 'source-map', plugins: [ + new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /en/), + new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery',