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]
};