[ci-stats] track size of shareable runtime (#133770) (#133954)

* [ci-stats] track size of sharable runtime

* report more than just the total size of the bundle

* put all sharable runtime metrics in a group

* fix entryName find fn

* remove unused import

* update outdated snapshot

* use runtime const and fix misspellings

* remove errant empty comment

(cherry picked from commit 9f78abfbe7)

Co-authored-by: Spencer <spencer@elastic.co>
This commit is contained in:
Kibana Machine 2022-06-08 17:02:51 -04:00 committed by GitHub
parent 4a77166519
commit 1206b0d512
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 337 additions and 12 deletions

View file

@ -511,6 +511,7 @@
"@kbn/import-resolver": "link:bazel-bin/packages/kbn-import-resolver",
"@kbn/jest-serializers": "link:bazel-bin/packages/kbn-jest-serializers",
"@kbn/optimizer": "link:bazel-bin/packages/kbn-optimizer",
"@kbn/optimizer-webpack-helpers": "link:bazel-bin/packages/kbn-optimizer-webpack-helpers",
"@kbn/performance-testing-dataset-extractor": "link:bazel-bin/packages/kbn-performance-testing-dataset-extractor",
"@kbn/plugin-generator": "link:bazel-bin/packages/kbn-plugin-generator",
"@kbn/plugin-helpers": "link:bazel-bin/packages/kbn-plugin-helpers",
@ -663,6 +664,7 @@
"@types/kbn__mapbox-gl": "link:bazel-bin/packages/kbn-mapbox-gl/npm_module_types",
"@types/kbn__monaco": "link:bazel-bin/packages/kbn-monaco/npm_module_types",
"@types/kbn__optimizer": "link:bazel-bin/packages/kbn-optimizer/npm_module_types",
"@types/kbn__optimizer-webpack-helpers": "link:bazel-bin/packages/kbn-optimizer-webpack-helpers/npm_module_types",
"@types/kbn__performance-testing-dataset-extractor": "link:bazel-bin/packages/kbn-performance-testing-dataset-extractor/npm_module_types",
"@types/kbn__plugin-discovery": "link:bazel-bin/packages/kbn-plugin-discovery/npm_module_types",
"@types/kbn__plugin-generator": "link:bazel-bin/packages/kbn-plugin-generator/npm_module_types",

View file

@ -66,6 +66,7 @@ filegroup(
"//packages/kbn-logging:build",
"//packages/kbn-mapbox-gl:build",
"//packages/kbn-monaco:build",
"//packages/kbn-optimizer-webpack-helpers:build",
"//packages/kbn-optimizer:build",
"//packages/kbn-performance-testing-dataset-extractor:build",
"//packages/kbn-plugin-discovery:build",
@ -175,6 +176,7 @@ filegroup(
"//packages/kbn-logging:build_types",
"//packages/kbn-mapbox-gl:build_types",
"//packages/kbn-monaco:build_types",
"//packages/kbn-optimizer-webpack-helpers:build_types",
"//packages/kbn-optimizer:build_types",
"//packages/kbn-performance-testing-dataset-extractor:build_types",
"//packages/kbn-plugin-discovery:build_types",

View file

@ -0,0 +1,115 @@
load("@npm//@bazel/typescript:index.bzl", "ts_config")
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project")
PKG_DIRNAME = "kbn-optimizer-webpack-helpers"
PKG_REQUIRE_NAME = "@kbn/optimizer-webpack-helpers"
SOURCE_FILES = glob(
[
"src/**/*.ts",
],
exclude = [
"**/*.test.*",
],
)
SRCS = SOURCE_FILES
filegroup(
name = "srcs",
srcs = SRCS,
)
NPM_MODULE_EXTRA_FILES = [
"package.json",
]
# In this array place runtime dependencies, including other packages and NPM packages
# which must be available for this code to run.
#
# To reference other packages use:
# "//repo/relative/path/to/package"
# eg. "//packages/kbn-utils"
#
# To reference a NPM package use:
# "@npm//name-of-package"
# eg. "@npm//lodash"
RUNTIME_DEPS = [
]
# In this array place dependencies necessary to build the types, which will include the
# :npm_module_types target of other packages and packages from NPM, including @types/*
# packages.
#
# To reference the types for another package use:
# "//repo/relative/path/to/package:npm_module_types"
# eg. "//packages/kbn-utils:npm_module_types"
#
# References to NPM packages work the same as RUNTIME_DEPS
TYPES_DEPS = [
"@npm//@types/node",
"@npm//@types/jest",
"@npm//@types/webpack",
]
jsts_transpiler(
name = "target_node",
srcs = SRCS,
build_pkg_name = package_name(),
)
ts_config(
name = "tsconfig",
src = "tsconfig.json",
deps = [
"//:tsconfig.base.json",
"//:tsconfig.bazel.json",
],
)
ts_project(
name = "tsc_types",
args = ['--pretty'],
srcs = SRCS,
deps = TYPES_DEPS,
declaration = True,
emit_declaration_only = True,
out_dir = "target_types",
root_dir = "src",
tsconfig = ":tsconfig",
)
js_library(
name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
visibility = ["//visibility:public"],
)
pkg_npm(
name = "npm_module",
deps = [":" + PKG_DIRNAME],
)
filegroup(
name = "build",
srcs = [":npm_module"],
visibility = ["//visibility:public"],
)
pkg_npm_types(
name = "npm_module_types",
srcs = SRCS,
deps = [":tsc_types"],
package_name = PKG_REQUIRE_NAME,
tsconfig = ":tsconfig",
visibility = ["//visibility:public"],
)
filegroup(
name = "build_types",
srcs = [":npm_module_types"],
visibility = ["//visibility:public"],
)

View file

@ -0,0 +1,3 @@
# @kbn/optimizer-webpack-helpers
Empty package generated by @kbn/generate

View file

@ -0,0 +1,13 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
module.exports = {
preset: '@kbn/test/jest_node',
rootDir: '../..',
roots: ['<rootDir>/packages/kbn-optimizer-webpack-helpers'],
};

View file

@ -0,0 +1,10 @@
{
"name": "@kbn/optimizer-webpack-helpers",
"private": true,
"version": "1.0.0",
"main": "./target_node/index.js",
"license": "SSPL-1.0 OR Elastic License 2.0",
"kibana": {
"devOnly": true
}
}

View file

@ -0,0 +1,27 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export type {
WebpackConcatenatedModule,
WebpackDelegatedModule,
WebpackExternalModule,
WebpackIgnoredModule,
WebpackNormalModule,
WebpackResolveData,
} from './webpack_helpers';
export {
isFailureStats,
failedStatsToErrorMessage,
getModulePath,
isConcatenatedModule,
isDelegatedModule,
isExternalModule,
isIgnoredModule,
isNormalModule,
} from './webpack_helpers';

View file

@ -7,7 +7,7 @@
*/
import webpack from 'webpack';
// @ts-ignore
// @ts-expect-error module is not typed
import Stats from 'webpack/lib/Stats';
export function isFailureStats(stats: webpack.Stats) {

View file

@ -0,0 +1,17 @@
{
"extends": "../../tsconfig.bazel.json",
"compilerOptions": {
"declaration": true,
"emitDeclarationOnly": true,
"outDir": "target_types",
"rootDir": "src",
"stripInternal": false,
"types": [
"jest",
"node"
]
},
"include": [
"src/**/*"
]
}

View file

@ -66,6 +66,7 @@ TYPES_DEPS = [
"//packages/kbn-config:npm_module_types",
"//packages/kbn-config-schema:npm_module_types",
"//packages/kbn-dev-utils:npm_module_types",
"//packages/kbn-optimizer-webpack-helpers:npm_module_types",
"//packages/kbn-std:npm_module_types",
"//packages/kbn-ui-shared-deps-npm:npm_module_types",
"//packages/kbn-ui-shared-deps-src:npm_module_types",

View file

@ -66,7 +66,6 @@ it(`finds all the optimizer files relative to it's path`, async () => {
<absolute path>/node_modules/@kbn/optimizer/target_node/worker/run_compilers.js,
<absolute path>/node_modules/@kbn/optimizer/target_node/worker/run_worker.js,
<absolute path>/node_modules/@kbn/optimizer/target_node/worker/theme_loader.js,
<absolute path>/node_modules/@kbn/optimizer/target_node/worker/webpack_helpers.js,
<absolute path>/node_modules/@kbn/optimizer/target_node/worker/webpack.config.js,
]
`);

View file

@ -11,6 +11,14 @@ import Path from 'path';
import { inspect } from 'util';
import webpack from 'webpack';
import {
isExternalModule,
isNormalModule,
isIgnoredModule,
isConcatenatedModule,
isDelegatedModule,
getModulePath,
} from '@kbn/optimizer-webpack-helpers';
import {
Bundle,
@ -21,14 +29,6 @@ import {
ParsedDllManifest,
} from '../common';
import { BundleRefModule } from './bundle_ref_module';
import {
isExternalModule,
isNormalModule,
isIgnoredModule,
isConcatenatedModule,
isDelegatedModule,
getModulePath,
} from './webpack_helpers';
/**
* sass-loader creates about a 40% overhead on the overall optimizer runtime, and

View file

@ -11,10 +11,10 @@ import 'source-map-support/register';
import webpack, { Stats } from 'webpack';
import * as Rx from 'rxjs';
import { mergeMap, map, mapTo, takeUntil } from 'rxjs/operators';
import { isFailureStats, failedStatsToErrorMessage } from '@kbn/optimizer-webpack-helpers';
import { CompilerMsgs, CompilerMsg, maybeMap, Bundle, WorkerConfig, BundleRefs } from '../common';
import { getWebpackConfig } from './webpack.config';
import { isFailureStats, failedStatsToErrorMessage } from './webpack_helpers';
const PLUGIN_NAME = '@kbn/optimizer';

View file

@ -5,10 +5,13 @@
* 2.0.
*/
require('../../../../src/setup_node_env');
const path = require('path');
const webpack = require('webpack');
const { stringifyRequest } = require('loader-utils'); // eslint-disable-line
const { CiStatsPlugin } = require('./webpack/ci_stats_plugin');
const {
KIBANA_ROOT,
SHAREABLE_RUNTIME_OUTPUT,
@ -32,7 +35,6 @@ module.exports = {
[SHAREABLE_RUNTIME_NAME]: require.resolve('./index.ts'),
},
mode: isProd ? 'production' : 'development',
plugins: isProd ? [new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 })] : [],
output: {
path: SHAREABLE_RUNTIME_OUTPUT,
filename: '[name].js',
@ -191,4 +193,10 @@ module.exports = {
fs: 'empty',
child_process: 'empty',
},
plugins: [
isProd ? new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 }) : [],
new CiStatsPlugin({
entryName: SHAREABLE_RUNTIME_NAME,
}),
].flat(),
};

View file

@ -0,0 +1,112 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
/* eslint-disable import/no-extraneous-dependencies */
import Path from 'path';
import webpack from 'webpack';
import { ToolingLog } from '@kbn/tooling-log';
import { REPO_ROOT } from '@kbn/utils';
import normalizePath from 'normalize-path';
import { CiStatsReporter } from '@kbn/ci-stats-reporter';
import { isNormalModule, isConcatenatedModule } from '@kbn/optimizer-webpack-helpers';
import { RUNTIME_SIZE_LIMIT } from './runtime_size_limit';
const IGNORED_EXTNAME = ['.map', '.br', '.gz'];
interface Asset {
name: string;
size: number;
}
export class CiStatsPlugin {
constructor(
private readonly options: {
entryName: string;
}
) {}
public apply(compiler: webpack.Compiler) {
const log = new ToolingLog({
level: 'error',
writeTo: process.stdout,
});
const ciStats = CiStatsReporter.fromEnv(log);
if (!ciStats.isEnabled()) {
return;
}
compiler.hooks.emit.tapAsync('CiStatsPlugin', async (compilation) => {
const { entryName } = this.options;
const assets = Object.entries(compilation.assets)
.map(
([name, source]: [string, any]): Asset => ({
name,
size: source.size(),
})
)
.filter((asset) => {
const filename = Path.basename(asset.name);
if (filename.startsWith('.')) {
return false;
}
const ext = Path.extname(filename);
if (IGNORED_EXTNAME.includes(ext)) {
return false;
}
return true;
});
const entry = assets.find((a) => a.name === `${entryName}.js`);
if (!entry) {
throw new Error(`Unable to find bundle entry named [${entryName}]`);
}
const moduleCount = compilation.modules.reduce((acc, module) => {
if (isNormalModule(module)) {
return acc + 1;
}
if (isConcatenatedModule(module)) {
return acc + module.modules.length;
}
return acc;
}, 0);
if (moduleCount === 0) {
throw new Error(`unable to determine module count`);
}
await ciStats.metrics([
{
group: `canvas shareable runtime`,
id: 'total size',
value: entry.size,
limit: RUNTIME_SIZE_LIMIT,
limitConfigPath: normalizePath(
Path.relative(REPO_ROOT, require.resolve('./runtime_size_limit'))
),
},
{
group: `canvas shareable runtime`,
id: 'misc asset size',
value: assets.filter((a) => a !== entry).reduce((acc: number, a) => acc + a.size, 0),
},
{
group: `canvas shareable runtime`,
id: 'module count',
value: moduleCount,
},
]);
});
}
}

View file

@ -0,0 +1,8 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
export const RUNTIME_SIZE_LIMIT = 8_200_000;

View file

@ -3134,6 +3134,10 @@
version "0.0.0"
uid ""
"@kbn/optimizer-webpack-helpers@link:bazel-bin/packages/kbn-optimizer-webpack-helpers":
version "0.0.0"
uid ""
"@kbn/optimizer@link:bazel-bin/packages/kbn-optimizer":
version "0.0.0"
uid ""
@ -6364,6 +6368,10 @@
version "0.0.0"
uid ""
"@types/kbn__optimizer-webpack-helpers@link:bazel-bin/packages/kbn-optimizer-webpack-helpers/npm_module_types":
version "0.0.0"
uid ""
"@types/kbn__optimizer@link:bazel-bin/packages/kbn-optimizer/npm_module_types":
version "0.0.0"
uid ""