diff --git a/presto-ui/src/components/QueryPlanView.jsx b/presto-ui/src/components/QueryPlanView.jsx index 8fa418d1ffc5f..5b22e3413bfd2 100644 --- a/presto-ui/src/components/QueryPlanView.jsx +++ b/presto-ui/src/components/QueryPlanView.jsx @@ -114,7 +114,7 @@ export default function PlanView({show, data}) { widgets.current.svg = d3.select("#plan-canvas"); } updateD3Graph(); - $('[data-bs-toggle="tooltip"]')?.tooltip() + $('[data-bs-toggle="tooltip"]')?.tooltip?.() }, [data, show]); return ( diff --git a/presto-ui/src/components/QueryViewer.jsx b/presto-ui/src/components/QueryViewer.jsx index d5a2b8f161dc0..0694ce95db812 100644 --- a/presto-ui/src/components/QueryViewer.jsx +++ b/presto-ui/src/components/QueryViewer.jsx @@ -23,7 +23,7 @@ import StaticQueryHeader from './StaticQueryHeader'; // A form to select a JSON file and read const FileForm = ({ onChange }) => (
-
+
Select a JSON file of SQL query to process
diff --git a/presto-ui/src/components/StaticQueryHeader.jsx b/presto-ui/src/components/StaticQueryHeader.jsx index 84d16ac206500..79a10006a6a3b 100644 --- a/presto-ui/src/components/StaticQueryHeader.jsx +++ b/presto-ui/src/components/StaticQueryHeader.jsx @@ -121,7 +121,7 @@ export default function StaticQueryHeader({ query, tabs, switchTab, tabIndex = 0
-
+
diff --git a/presto-ui/src/package.json b/presto-ui/src/package.json index af9ffa8e35307..59fe272815bc0 100644 --- a/presto-ui/src/package.json +++ b/presto-ui/src/package.json @@ -40,7 +40,8 @@ "scripts": { "install": "webpack --env=production --config webpack.config.js", "watch": "webpack --config webpack.config.js --watch", - "serve": "webpack serve --config webpack.config.js" + "serve": "webpack serve --config webpack.config.js", + "analyze": "webpack --env=production --config webpack.config.js --profile --json > stats.json && mv stats.json ../target/webapp/ && npx webpack-bundle-analyzer ../target/webapp/stats.json" }, "resolutions": { "d3-color": "3.1.0" diff --git a/presto-ui/src/query_viewer.jsx b/presto-ui/src/query_viewer.jsx index c86e4823d1f71..ca5dfa1c7bbe7 100644 --- a/presto-ui/src/query_viewer.jsx +++ b/presto-ui/src/query_viewer.jsx @@ -1,9 +1,7 @@ import { createRoot } from 'react-dom/client'; -import lazy from "./lazy"; +import QueryViewer from "./components/QueryViewer"; import { PageTitle } from "./components/PageTitle"; -const QueryViewer = lazy('QueryViewer'); - const title = createRoot(document.getElementById('title')); title.render(); diff --git a/presto-ui/src/webpack.config.js b/presto-ui/src/webpack.config.js index bf89c2e4a0576..c526cd5991be9 100644 --- a/presto-ui/src/webpack.config.js +++ b/presto-ui/src/webpack.config.js @@ -11,18 +11,8 @@ module.exports = (env) => { const apiHost = env.apiHost || 'localhost'; const apiPort = env.apiPort || '8080'; const outputDir = 'target/webapp'; - return { + const baseConfig = { entry: { - 'index': './index.jsx', - 'query': './query.jsx', - 'plan': './plan.jsx', - 'query_viewer': {import: './query_viewer.jsx', filename: path.join('dev', '[name].js')}, - 'embedded_plan': './embedded_plan.jsx', - 'stage': './stage.jsx', - 'worker': './worker.jsx', - 'timeline': './timeline.jsx', - 'res_groups': './res_groups.jsx', - 'sql_client': './sql_client.jsx', 'css_loader': path.join(__dirname, 'static', 'vendor', 'css-loaders', 'loader.css'), 'css_presto': path.join(__dirname, 'static', 'assets', 'presto.css'), }, @@ -30,29 +20,13 @@ module.exports = (env) => { // substitutes `require('vis-timeline/standalone')` to `global.vis` 'vis-timeline/standalone': 'vis', }, - plugins: [ - new CopyPlugin({ - patterns: [ - {from: "static", to: path.join(__dirname, "..", outputDir)}, - ] - }), - new HtmlWebpackPlugin({ - inject: 'body', - filename: path.join(__dirname, '..', outputDir, 'dev', 'query_viewer_spa.html'), - template: 'templates/query_viewer.html', - chunks: [ - 'query_viewer', - 'css_loader', - 'css_presto', - ] - }), - new HtmlInlineScriptPlugin({ - htmlMatchPattern: [/query_viewer_spa.html$/], - assetPreservePattern: [ - /.*.js$/, - ] - }), - ], + plugins: [ + new CopyPlugin({ + patterns: [ + {from: "static", to: path.join(__dirname, "..", outputDir)}, + ] + }), + ], mode, module: { rules: [ @@ -97,6 +71,25 @@ module.exports = (env) => { extractComments: false, }), '...'], + }, + }; + + const mainConfig = { + ...baseConfig, + entry: { + 'index': './index.jsx', + 'query': './query.jsx', + 'plan': './plan.jsx', + 'embedded_plan': './embedded_plan.jsx', + 'stage': './stage.jsx', + 'worker': './worker.jsx', + 'timeline': './timeline.jsx', + 'res_groups': './res_groups.jsx', + 'sql_client': './sql_client.jsx', + ...baseConfig.entry, + }, + optimization: { + ...baseConfig.optimization, splitChunks: { chunks: 'async', maxSize: 244000, @@ -107,6 +100,7 @@ module.exports = (env) => { test: /[\\/]node_modules[\\/]/, priority: -10, reuseExistingChunk: true, + filename: '[name].vendor.js', }, default: { minChunks: 2, @@ -130,4 +124,37 @@ module.exports = (env) => { ], }, }; + + const spaConfig = { + ...baseConfig, + plugins: [ + ...baseConfig.plugins, + new HtmlWebpackPlugin({ + inject: 'body', + filename: path.join('dev', 'query_viewer_spa.html'), + template: 'templates/query_viewer.html', + chunks: [ + 'query_viewer', + 'bootstrap_css', + 'css_loader', + 'css_presto', + ] + }), + new HtmlInlineScriptPlugin({ + htmlMatchPattern: [/query_viewer_spa.html$/], + assetPreservePattern: [ + /.*.js$/, + ] + }), + ], + entry: { + 'query_viewer': {import: './query_viewer.jsx', filename: path.join('dev', '[name].js')}, + ...baseConfig.entry, + }, + optimization: { + ...baseConfig.optimization, + splitChunks: false, + } + }; + return [mainConfig, spaConfig] };