[8.16] chore(NA): upgrade to webpack 5 (#191106) (#211152)

# Backport

This will backport the following commits from `main` to `8.16`:
- [chore(NA): upgrade to webpack 5
(#191106)](https://github.com/elastic/kibana/pull/191106)

<!--- Backport version: 9.6.4 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sorenlouv/backport)

<!--BACKPORT [{"author":{"name":"Tiago
Costa","email":"tiago.costa@elastic.co"},"sourceCommit":{"committedDate":"2025-02-14T03:01:36Z","message":"chore(NA):
upgrade to webpack 5 (#191106)\n\n### Summary\r\n\r\n- Closes
#89741\r\n\r\nThis PR contains the resulting work of a massive effort
that ports our\r\non top bundler abstraction (called @kbn/optimizer)
from Webpack v4 into\r\nWebpack v5. It's essential in terms of long term
maintenance since v4\r\nwas not receiving updates any longer but will
also unblock some new\r\nfeatures that could be beneficial for our
future DevEx endeavours.\r\n\r\nNext you can find a small list of all
the accomplished tasks on this\r\njourney.\r\n\r\n### Completed
Tasks\r\n- [x] Upgrade dependencies to match the ones on webpack v5\r\n-
[x] Fix null-loader usages\r\n- [x] Fix raw-loader usages\r\n- [x] Fix
file-loader usages\r\n- [x] Fix url-loader usages\r\n- [x] Fix
`@kbn/optimizer-webpack-helpers` to support webpack v5 \r\n- [x] Adopt
previous webpack v4 polyfill-all strategy
with\r\nnode-polyfill-webpack-plugin\r\n- [x] Fix theme-loader on
@kbn/optimizer\r\n- [x] Migrate configurations and ad-hoc loader options
on all webpack\r\nconfigs from v4 to v5\r\n- [x] Fix @kbn/test jest
resolver for file-loader cases\r\n- [x] Migrate public-path loader on
UiSharedDeps\r\n- [x] Fix all usages of webpack-merge\r\n- [x] Migrate
BundleRemoteModule\r\n- [x] Migrate BundleRemotesPlugin\r\n- [x]
Correctly migrate PopulateBundleCachePlugin\r\n- [x] Correctly migrate
BundleMetricsPlugin\r\n- [x] Check if the profiling plugins still work
(--profile flag)\r\n- [x] Recover if possible the previous webpack v4
cacheGroup chunks\r\nrename to something like
`data.plugin.chunk.0.js`\r\n- [x] Run `/ci` and make sure we get our
first green CI, otherwise work\r\non the errors until we do\r\n- [x]
Profile and solve bottlenecks until we get a cold build\r\nperformance
similar to the one we had on webpack v4
(`node\r\nscripts/build_kibana_platform_plugins --no-cache`).\r\n- [x]
OpenSSL Legacy Warnings: try to remove `--openssl-legacy-provider\r\n`
flags\r\n- [x] Add Webpack to Renovate config\r\n- [x] Explore removing
`NodePolyfillPlugin`\r\n([here](https://www.npmjs.com/package/node-polyfill-webpack-plugin))
and\r\nadd each polyfill needed individually per each webpack config to
check\r\nif we get smaller bundles. If we do it's better to go with the
case by\r\ncase need approach instead of deploying a bunch of polyfills
with\r\nNodePolyfillPlugin. As another alternative, create a custom
smaller\r\nplugin with only the union of all needed polyfills.\r\n- [x]
Evaluate if we want to touch the resolutions on mainFields
and\r\nconditionNames\r\n- [x] Understand why `@import
'src/core/public/mixins'` does not work\r\nanymore (not a problem, we
should use relative paths anyway but we want\r\nto track why it changed
from v4 to v5)\r\n- [x] BUG: Child compilers are having errors hidden
and/or changed from\r\nerror to warning\r\n- [x] Fix license check
for\r\n[Artistic-2.0](https://spdx.org/licenses/Artistic-2.0.html) is
the\r\nlicense
for\r\n[domain-browser](https://github.com/bevry/domain-browser?tab=License-1-ov-file).\r\nThis
package is a dependency
of\r\n[NodePolyfillPlugin](https://www.npmjs.com/package/node-polyfill-webpack-plugin).\r\nArtistic
2.0 license is [classified
as\r\nyellow](https://github.com/elastic/open-source/blob/main/elastic-product-policy.md#yellow-list)\r\nand
should only be used for dev dependencies.\r\n- [x] Make sure
`resourceQuery: { not: /raw/ }` is not necessary on\r\nother webpack
configs like storybook one\r\n- [x] Find what is being wrongly removed
by usedExports optimization;\r\nhint: I believe it is identifying a lot
of exports inside the sync entry\r\nof plugins as unused exports and
removing them. Then `__kbnBootstrap__`\r\ncan't be found\r\n- [x]
Rebalance @kbn/optimizer pickMaxWorkerCount\r\n- [x] Re-open the issue
to fix
sass-warnings\r\n[#190345](https://github.com/elastic/kibana/issues/190345)
or downgrade\r\nsass-loader to v10\r\n- [x] Remove previous esm no parse
rules\r\n- [x] Confirm esm support is working\r\n- [x] Confirm console
override is needed\r\n- [x] Confirm react prod builds on ui shared deps
for distributable\r\n- [x] Remove customization
for\r\n[xyflow](https://github.com/xyflow/xyflow) from webpack
configs\r\n- [x] Clean all the code\r\n- [x] Make sure collected metrics
from stats are still aligned with what\r\nwe were collecting before;
also verify if the modules used for optimizer\r\ncaches etc are well
generated (@kbn/node-libs-browser)\r\n- [x] Fix watch
performance\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine
<42973632+kibanamachine@users.noreply.github.com>\r\nCo-authored-by:
Brad White
<brad.white@elastic.co>","sha":"203bc284781cc830049b3f7948c8fcafa8b7d9a1","branchLabelMapping":{"^v9.1.0$":"main","^v8.19.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["chore","Team:Operations","release_note:skip","Team:Fleet","v9.0.0","backport:all-open","ci:build-webpack-bundle-analyzer","Team:obs-ux-infra_services","v9.1.0"],"title":"chore(NA):
upgrade to webpack
5","number":191106,"url":"https://github.com/elastic/kibana/pull/191106","mergeCommit":{"message":"chore(NA):
upgrade to webpack 5 (#191106)\n\n### Summary\r\n\r\n- Closes
#89741\r\n\r\nThis PR contains the resulting work of a massive effort
that ports our\r\non top bundler abstraction (called @kbn/optimizer)
from Webpack v4 into\r\nWebpack v5. It's essential in terms of long term
maintenance since v4\r\nwas not receiving updates any longer but will
also unblock some new\r\nfeatures that could be beneficial for our
future DevEx endeavours.\r\n\r\nNext you can find a small list of all
the accomplished tasks on this\r\njourney.\r\n\r\n### Completed
Tasks\r\n- [x] Upgrade dependencies to match the ones on webpack v5\r\n-
[x] Fix null-loader usages\r\n- [x] Fix raw-loader usages\r\n- [x] Fix
file-loader usages\r\n- [x] Fix url-loader usages\r\n- [x] Fix
`@kbn/optimizer-webpack-helpers` to support webpack v5 \r\n- [x] Adopt
previous webpack v4 polyfill-all strategy
with\r\nnode-polyfill-webpack-plugin\r\n- [x] Fix theme-loader on
@kbn/optimizer\r\n- [x] Migrate configurations and ad-hoc loader options
on all webpack\r\nconfigs from v4 to v5\r\n- [x] Fix @kbn/test jest
resolver for file-loader cases\r\n- [x] Migrate public-path loader on
UiSharedDeps\r\n- [x] Fix all usages of webpack-merge\r\n- [x] Migrate
BundleRemoteModule\r\n- [x] Migrate BundleRemotesPlugin\r\n- [x]
Correctly migrate PopulateBundleCachePlugin\r\n- [x] Correctly migrate
BundleMetricsPlugin\r\n- [x] Check if the profiling plugins still work
(--profile flag)\r\n- [x] Recover if possible the previous webpack v4
cacheGroup chunks\r\nrename to something like
`data.plugin.chunk.0.js`\r\n- [x] Run `/ci` and make sure we get our
first green CI, otherwise work\r\non the errors until we do\r\n- [x]
Profile and solve bottlenecks until we get a cold build\r\nperformance
similar to the one we had on webpack v4
(`node\r\nscripts/build_kibana_platform_plugins --no-cache`).\r\n- [x]
OpenSSL Legacy Warnings: try to remove `--openssl-legacy-provider\r\n`
flags\r\n- [x] Add Webpack to Renovate config\r\n- [x] Explore removing
`NodePolyfillPlugin`\r\n([here](https://www.npmjs.com/package/node-polyfill-webpack-plugin))
and\r\nadd each polyfill needed individually per each webpack config to
check\r\nif we get smaller bundles. If we do it's better to go with the
case by\r\ncase need approach instead of deploying a bunch of polyfills
with\r\nNodePolyfillPlugin. As another alternative, create a custom
smaller\r\nplugin with only the union of all needed polyfills.\r\n- [x]
Evaluate if we want to touch the resolutions on mainFields
and\r\nconditionNames\r\n- [x] Understand why `@import
'src/core/public/mixins'` does not work\r\nanymore (not a problem, we
should use relative paths anyway but we want\r\nto track why it changed
from v4 to v5)\r\n- [x] BUG: Child compilers are having errors hidden
and/or changed from\r\nerror to warning\r\n- [x] Fix license check
for\r\n[Artistic-2.0](https://spdx.org/licenses/Artistic-2.0.html) is
the\r\nlicense
for\r\n[domain-browser](https://github.com/bevry/domain-browser?tab=License-1-ov-file).\r\nThis
package is a dependency
of\r\n[NodePolyfillPlugin](https://www.npmjs.com/package/node-polyfill-webpack-plugin).\r\nArtistic
2.0 license is [classified
as\r\nyellow](https://github.com/elastic/open-source/blob/main/elastic-product-policy.md#yellow-list)\r\nand
should only be used for dev dependencies.\r\n- [x] Make sure
`resourceQuery: { not: /raw/ }` is not necessary on\r\nother webpack
configs like storybook one\r\n- [x] Find what is being wrongly removed
by usedExports optimization;\r\nhint: I believe it is identifying a lot
of exports inside the sync entry\r\nof plugins as unused exports and
removing them. Then `__kbnBootstrap__`\r\ncan't be found\r\n- [x]
Rebalance @kbn/optimizer pickMaxWorkerCount\r\n- [x] Re-open the issue
to fix
sass-warnings\r\n[#190345](https://github.com/elastic/kibana/issues/190345)
or downgrade\r\nsass-loader to v10\r\n- [x] Remove previous esm no parse
rules\r\n- [x] Confirm esm support is working\r\n- [x] Confirm console
override is needed\r\n- [x] Confirm react prod builds on ui shared deps
for distributable\r\n- [x] Remove customization
for\r\n[xyflow](https://github.com/xyflow/xyflow) from webpack
configs\r\n- [x] Clean all the code\r\n- [x] Make sure collected metrics
from stats are still aligned with what\r\nwe were collecting before;
also verify if the modules used for optimizer\r\ncaches etc are well
generated (@kbn/node-libs-browser)\r\n- [x] Fix watch
performance\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine
<42973632+kibanamachine@users.noreply.github.com>\r\nCo-authored-by:
Brad White
<brad.white@elastic.co>","sha":"203bc284781cc830049b3f7948c8fcafa8b7d9a1"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"9.0","label":"v9.0.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"url":"https://github.com/elastic/kibana/pull/211145","number":211145,"state":"OPEN"},{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/191106","number":191106,"mergeCommit":{"message":"chore(NA):
upgrade to webpack 5 (#191106)\n\n### Summary\r\n\r\n- Closes
#89741\r\n\r\nThis PR contains the resulting work of a massive effort
that ports our\r\non top bundler abstraction (called @kbn/optimizer)
from Webpack v4 into\r\nWebpack v5. It's essential in terms of long term
maintenance since v4\r\nwas not receiving updates any longer but will
also unblock some new\r\nfeatures that could be beneficial for our
future DevEx endeavours.\r\n\r\nNext you can find a small list of all
the accomplished tasks on this\r\njourney.\r\n\r\n### Completed
Tasks\r\n- [x] Upgrade dependencies to match the ones on webpack v5\r\n-
[x] Fix null-loader usages\r\n- [x] Fix raw-loader usages\r\n- [x] Fix
file-loader usages\r\n- [x] Fix url-loader usages\r\n- [x] Fix
`@kbn/optimizer-webpack-helpers` to support webpack v5 \r\n- [x] Adopt
previous webpack v4 polyfill-all strategy
with\r\nnode-polyfill-webpack-plugin\r\n- [x] Fix theme-loader on
@kbn/optimizer\r\n- [x] Migrate configurations and ad-hoc loader options
on all webpack\r\nconfigs from v4 to v5\r\n- [x] Fix @kbn/test jest
resolver for file-loader cases\r\n- [x] Migrate public-path loader on
UiSharedDeps\r\n- [x] Fix all usages of webpack-merge\r\n- [x] Migrate
BundleRemoteModule\r\n- [x] Migrate BundleRemotesPlugin\r\n- [x]
Correctly migrate PopulateBundleCachePlugin\r\n- [x] Correctly migrate
BundleMetricsPlugin\r\n- [x] Check if the profiling plugins still work
(--profile flag)\r\n- [x] Recover if possible the previous webpack v4
cacheGroup chunks\r\nrename to something like
`data.plugin.chunk.0.js`\r\n- [x] Run `/ci` and make sure we get our
first green CI, otherwise work\r\non the errors until we do\r\n- [x]
Profile and solve bottlenecks until we get a cold build\r\nperformance
similar to the one we had on webpack v4
(`node\r\nscripts/build_kibana_platform_plugins --no-cache`).\r\n- [x]
OpenSSL Legacy Warnings: try to remove `--openssl-legacy-provider\r\n`
flags\r\n- [x] Add Webpack to Renovate config\r\n- [x] Explore removing
`NodePolyfillPlugin`\r\n([here](https://www.npmjs.com/package/node-polyfill-webpack-plugin))
and\r\nadd each polyfill needed individually per each webpack config to
check\r\nif we get smaller bundles. If we do it's better to go with the
case by\r\ncase need approach instead of deploying a bunch of polyfills
with\r\nNodePolyfillPlugin. As another alternative, create a custom
smaller\r\nplugin with only the union of all needed polyfills.\r\n- [x]
Evaluate if we want to touch the resolutions on mainFields
and\r\nconditionNames\r\n- [x] Understand why `@import
'src/core/public/mixins'` does not work\r\nanymore (not a problem, we
should use relative paths anyway but we want\r\nto track why it changed
from v4 to v5)\r\n- [x] BUG: Child compilers are having errors hidden
and/or changed from\r\nerror to warning\r\n- [x] Fix license check
for\r\n[Artistic-2.0](https://spdx.org/licenses/Artistic-2.0.html) is
the\r\nlicense
for\r\n[domain-browser](https://github.com/bevry/domain-browser?tab=License-1-ov-file).\r\nThis
package is a dependency
of\r\n[NodePolyfillPlugin](https://www.npmjs.com/package/node-polyfill-webpack-plugin).\r\nArtistic
2.0 license is [classified
as\r\nyellow](https://github.com/elastic/open-source/blob/main/elastic-product-policy.md#yellow-list)\r\nand
should only be used for dev dependencies.\r\n- [x] Make sure
`resourceQuery: { not: /raw/ }` is not necessary on\r\nother webpack
configs like storybook one\r\n- [x] Find what is being wrongly removed
by usedExports optimization;\r\nhint: I believe it is identifying a lot
of exports inside the sync entry\r\nof plugins as unused exports and
removing them. Then `__kbnBootstrap__`\r\ncan't be found\r\n- [x]
Rebalance @kbn/optimizer pickMaxWorkerCount\r\n- [x] Re-open the issue
to fix
sass-warnings\r\n[#190345](https://github.com/elastic/kibana/issues/190345)
or downgrade\r\nsass-loader to v10\r\n- [x] Remove previous esm no parse
rules\r\n- [x] Confirm esm support is working\r\n- [x] Confirm console
override is needed\r\n- [x] Confirm react prod builds on ui shared deps
for distributable\r\n- [x] Remove customization
for\r\n[xyflow](https://github.com/xyflow/xyflow) from webpack
configs\r\n- [x] Clean all the code\r\n- [x] Make sure collected metrics
from stats are still aligned with what\r\nwe were collecting before;
also verify if the modules used for optimizer\r\ncaches etc are well
generated (@kbn/node-libs-browser)\r\n- [x] Fix watch
performance\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine
<42973632+kibanamachine@users.noreply.github.com>\r\nCo-authored-by:
Brad White
<brad.white@elastic.co>","sha":"203bc284781cc830049b3f7948c8fcafa8b7d9a1"}},{"url":"https://github.com/elastic/kibana/pull/211146","number":211146,"branch":"8.x","state":"OPEN"},{"url":"https://github.com/elastic/kibana/pull/211147","number":211147,"branch":"8.18","state":"OPEN"},{"url":"https://github.com/elastic/kibana/pull/211148","number":211148,"branch":"8.17","state":"OPEN"}]}]
BACKPORT-->

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Tiago Costa 2025-02-19 04:15:36 +00:00 committed by GitHub
parent 6377f543ed
commit 9621d8dd51
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
90 changed files with 1910 additions and 945 deletions

View file

@ -2,7 +2,7 @@ steps:
- command: .buildkite/scripts/steps/webpack_bundle_analyzer/build_and_upload.sh
label: 'Build Webpack Bundle Analyzer reports'
agents:
machineType: n2-standard-4
machineType: n2-standard-8
preemptible: true
key: webpack_bundle_analyzer
timeout_in_minutes: 60

View file

@ -14,5 +14,5 @@ echo "--- Profiling Cypress Tests"
cd "$XPACK_DIR"
NODE_OPTIONS=--openssl-legacy-provider node plugins/observability_solution/profiling/scripts/test/e2e.js \
node plugins/observability_solution/profiling/scripts/test/e2e.js \
--kibana-install-dir "$KIBANA_BUILD_LOCATION" \

View file

@ -39,7 +39,11 @@ const build = () => {
console.log('--- Building Storybooks');
for (const storybook of Object.keys(storybookAliases)) {
exec(`STORYBOOK_BASE_URL=${STORYBOOK_BASE_URL}`, `yarn storybook --site ${storybook}`);
exec(
`STORYBOOK_BASE_URL=${STORYBOOK_BASE_URL}`,
`NODE_OPTIONS=--max-old-space-size=6144`,
`yarn storybook --site ${storybook}`
);
}
};

1
.github/CODEOWNERS vendored
View file

@ -643,6 +643,7 @@ src/plugins/navigation @elastic/appex-sharedux
src/plugins/newsfeed @elastic/kibana-core
test/common/plugins/newsfeed @elastic/kibana-core
src/plugins/no_data_page @elastic/appex-sharedux
packages/kbn-node-libs-browser-webpack-plugin @elastic/kibana-operations
x-pack/plugins/notifications @elastic/appex-sharedux
packages/kbn-object-versioning @elastic/appex-sharedux
packages/kbn-object-versioning-utils @elastic/appex-sharedux

View file

@ -11,7 +11,7 @@ import React from 'react';
import { css } from '@emotion/react';
import { EuiMarkdownFormat } from '@elastic/eui';
// @ts-ignore
import overviewMarkdown from '!!raw-loader!@kbn/embeddable-plugin/README.md';
import overviewMarkdown from '@kbn/embeddable-plugin/README.md?raw';
export const Overview = () => {
return (

View file

@ -10,13 +10,13 @@
import React from 'react';
import { EuiCodeBlock, EuiSpacer, EuiText } from '@elastic/eui';
// @ts-ignore
import registerSearchEmbeddableSource from '!!raw-loader!../react_embeddables/search/register_search_embeddable';
import registerSearchEmbeddableSource from '../react_embeddables/search/register_search_embeddable?raw';
// @ts-ignore
import registerAttachActionSource from '!!raw-loader!../react_embeddables/search/register_add_search_panel_action';
import registerAttachActionSource from '../react_embeddables/search/register_add_search_panel_action?raw';
// @ts-ignore
import registerFieldListEmbeddableSource from '!!raw-loader!../react_embeddables/field_list/register_field_list_embeddable';
import registerFieldListEmbeddableSource from '../react_embeddables/field_list/register_field_list_embeddable?raw';
// @ts-ignore
import registerReactEmbeddableSavedObjectSource from '!!raw-loader!../react_embeddables/register_saved_object_example';
import registerReactEmbeddableSavedObjectSource from '../react_embeddables/register_saved_object_example?raw';
export const RegisterEmbeddable = () => {
return (

View file

@ -24,15 +24,15 @@ import { FieldFormatsStart } from '@kbn/field-formats-plugin/public';
import * as example1 from './examples/1_using_existing_format';
import * as example2 from './examples/2_creating_custom_formatter';
// @ts-ignore
import example1SampleCode from '!!raw-loader!./examples/1_using_existing_format';
import example1SampleCode from './examples/1_using_existing_format?raw';
// @ts-ignore
import example2SampleCodePart1 from '!!raw-loader!../common/example_currency_format';
import example2SampleCodePart1 from '../common/example_currency_format?raw';
// @ts-ignore
import example2SampleCodePart2 from '!!raw-loader!./examples/2_creating_custom_formatter';
import example2SampleCodePart2 from './examples/2_creating_custom_formatter?raw';
// @ts-ignore
import example2SampleCodePart3 from '!!raw-loader!../server/examples/2_creating_custom_formatter';
import example2SampleCodePart3 from '../server/examples/2_creating_custom_formatter?raw';
// @ts-ignore
import example3SampleCode from '!!raw-loader!./examples/3_creating_custom_format_editor';
import example3SampleCode from './examples/3_creating_custom_format_editor?raw';
export interface Deps {
fieldFormats: FieldFormatsStart;

View file

@ -62,7 +62,7 @@
"serverless-security": "node scripts/kibana --dev --serverless=security",
"spec_to_console": "node scripts/spec_to_console",
"start": "node scripts/kibana --dev",
"storybook": "node --openssl-legacy-provider scripts/storybook",
"storybook": "node --no-deprecation scripts/storybook",
"test:ftr": "node scripts/functional_tests",
"test:ftr:runner": "node scripts/functional_test_runner",
"test:ftr:server": "node scripts/functional_tests_server",
@ -680,6 +680,7 @@
"@kbn/newsfeed-plugin": "link:src/plugins/newsfeed",
"@kbn/newsfeed-test-plugin": "link:test/common/plugins/newsfeed",
"@kbn/no-data-page-plugin": "link:src/plugins/no_data_page",
"@kbn/node-libs-browser-webpack-plugin": "link:packages/kbn-node-libs-browser-webpack-plugin",
"@kbn/notifications-plugin": "link:x-pack/plugins/notifications",
"@kbn/object-versioning": "link:packages/kbn-object-versioning",
"@kbn/object-versioning-utils": "link:packages/kbn-object-versioning-utils",
@ -1058,7 +1059,7 @@
"@turf/length": "^6.0.2",
"@xstate/react": "^3.2.2",
"@xstate5/react": "npm:@xstate/react@^4.1.2",
"@xyflow/react": "^12.3.0",
"@xyflow/react": "^12.4.1",
"adm-zip": "^0.5.9",
"ai": "^2.2.33",
"ajv": "^8.12.0",
@ -1313,7 +1314,6 @@
"@babel/plugin-proposal-optional-chaining": "^7.21.0",
"@babel/plugin-proposal-private-methods": "^7.18.6",
"@babel/plugin-transform-class-properties": "^7.24.7",
"@babel/plugin-transform-logical-assignment-operators": "^7.24.7",
"@babel/plugin-transform-numeric-separator": "^7.24.7",
"@babel/plugin-transform-optional-chaining": "^7.24.8",
"@babel/plugin-transform-runtime": "^7.24.7",
@ -1327,7 +1327,7 @@
"@bazel/typescript": "4.6.2",
"@cypress/debugging-proxy": "2.0.1",
"@cypress/grep": "^4.0.1",
"@cypress/webpack-preprocessor": "^6.0.1",
"@cypress/webpack-preprocessor": "^6.0.2",
"@elastic/eslint-plugin-eui": "0.0.2",
"@elastic/makelogs": "^6.1.1",
"@elastic/synthetics": "^1.12.1",
@ -1511,11 +1511,13 @@
"@storybook/addon-storyshots": "^6.5.16",
"@storybook/addons": "^6.5.16",
"@storybook/api": "^6.5.16",
"@storybook/builder-webpack5": "^6.5.16",
"@storybook/client-api": "^6.5.16",
"@storybook/components": "^6.5.16",
"@storybook/core": "^6.5.16",
"@storybook/core-common": "^6.5.16",
"@storybook/core-events": "^6.5.16",
"@storybook/manager-webpack5": "^6.5.16",
"@storybook/node-logger": "^6.5.16",
"@storybook/preview-web": "^6.5.16",
"@storybook/react": "^6.5.16",
@ -1656,11 +1658,10 @@
"@types/vinyl": "^2.0.4",
"@types/vinyl-fs": "^3.0.2",
"@types/watchpack": "^1.1.5",
"@types/webpack": "^4.41.3",
"@types/webpack": "^5.28.5",
"@types/webpack-bundle-analyzer": "^4.7.0",
"@types/webpack-env": "^1.15.3",
"@types/webpack-merge": "^4.1.5",
"@types/webpack-sources": "^0.1.4",
"@types/webpack-env": "^1.18.5",
"@types/webpack-sources": "^3.2.3",
"@types/xml2js": "^0.4.11",
"@types/yargs": "^15.0.0",
"@types/yauzl": "^2.9.1",
@ -1676,12 +1677,13 @@
"autoprefixer": "^10.4.7",
"axe-core": "^4.10.0",
"babel-jest": "^29.7.0",
"babel-loader": "^8.2.5",
"babel-loader": "^9.1.3",
"babel-plugin-add-module-exports": "^1.0.4",
"babel-plugin-istanbul": "^6.1.1",
"babel-plugin-require-context-hook": "^1.0.0",
"babel-plugin-styled-components": "^2.1.4",
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
"babel-plugin-transform-require-default": "^0.1.7",
"babel-plugin-transform-typescript-metadata": "^0.3.2",
"backport": "^9.6.6",
"blob-polyfill": "^7.0.20220408",
@ -1689,12 +1691,12 @@
"callsites": "^3.1.0",
"chance": "1.0.18",
"chromedriver": "^133.0.0",
"clean-webpack-plugin": "^3.0.0",
"clean-webpack-plugin": "^4.0.0",
"cli-progress": "^3.12.0",
"cli-table3": "^0.6.1",
"content-security-policy-parser": "^0.6.0",
"cpy": "^8.1.1",
"css-loader": "^3.4.2",
"css-loader": "^7.1.2",
"cssnano": "^5.1.12",
"cssnano-preset-default": "^5.2.12",
"csstype": "^3.0.2",
@ -1730,7 +1732,7 @@
"eslint-traverse": "^1.0.0",
"exit-hook": "^2.2.0",
"expect": "^29.7.0",
"expose-loader": "^0.7.5",
"expose-loader": "^5.0.0",
"express": "^4.21.2",
"faker": "^5.1.0",
"fetch-mock": "^7.3.9",
@ -1743,7 +1745,7 @@
"gulp-terser": "^2.1.0",
"has-ansi": "^3.0.0",
"html": "1.0.0",
"html-loader": "^1.3.2",
"html-loader": "^5.1.0",
"http-proxy": "^1.18.1",
"http2-proxy": "^5.0.53",
"http2-wrapper": "^2.2.1",
@ -1767,10 +1769,9 @@
"license-checker": "^25.0.1",
"listr2": "^8.2.5",
"lmdb": "^2.9.2",
"loader-utils": "^2.0.4",
"marge": "^1.0.1",
"micromatch": "^4.0.8",
"mini-css-extract-plugin": "1.1.0",
"mini-css-extract-plugin": "2.9.1",
"minimist": "^1.2.8",
"mocha": "^10.3.0",
"mocha-junit-reporter": "^2.0.2",
@ -1784,7 +1785,7 @@
"mutation-observer": "^1.0.3",
"native-hdr-histogram": "^1.0.0",
"nock": "12.0.3",
"null-loader": "^3.0.0",
"node-libs-browser": "^2.2.1",
"nyc": "^15.1.0",
"oboe": "^2.1.4",
"openapi-types": "^12.1.3",
@ -1800,27 +1801,26 @@
"playwright-chromium": "1.49.0",
"pngjs": "^3.4.0",
"postcss": "^8.4.31",
"postcss-loader": "^4.2.0",
"postcss-loader": "^8.1.1",
"postcss-prefix-selector": "^1.16.0",
"postcss-scss": "^4.0.4",
"prettier": "^2.8.8",
"proxy": "^2.1.1",
"raw-loader": "^3.1.0",
"react-test-renderer": "^17.0.2",
"recast": "^0.23.9",
"regenerate": "^1.4.0",
"resolve": "^1.22.0",
"rxjs-marbles": "^7.0.1",
"sass-embedded": "^1.78.0",
"sass-loader": "^10.5.1",
"sass-loader": "^10.5.2",
"selenium-webdriver": "^4.28.1",
"sharp": "0.32.6",
"simple-git": "^3.16.0",
"sinon": "^7.4.2",
"sort-package-json": "^1.53.1",
"source-map": "^0.7.4",
"string-replace-loader": "^2.2.0",
"style-loader": "^1.1.3",
"string-replace-loader": "^3.1.0",
"style-loader": "^4.0.0",
"stylelint": "^14.9.1",
"stylelint-scss": "^4.3.0",
"superagent": "^9.0.2",
@ -1831,24 +1831,22 @@
"table": "^6.8.2",
"tape": "^5.9.0",
"terser": "^5.36.0",
"terser-webpack-plugin": "^4.2.3",
"terser-webpack-plugin": "^5.3.10",
"tough-cookie": "^5.0.0",
"tree-kill": "^1.2.2",
"ts-morph": "^15.1.0",
"tsd": "^0.31.1",
"typescript": "5.1.6",
"url-loader": "^2.2.0",
"val-loader": "^1.1.1",
"val-loader": "^6.0.0",
"vinyl-fs": "^4.0.0",
"watchpack": "^1.6.0",
"web-streams-polyfill": "^4.0.0",
"webpack": "^4.41.5",
"webpack-bundle-analyzer": "^4.5.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.9.3",
"webpack-merge": "^4.2.2",
"webpack-sources": "^1.4.1",
"webpack-visualizer-plugin2": "^1.1.0",
"webpack": "^5.95.0",
"webpack-bundle-analyzer": "^4.10.2",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^5.0.4",
"webpack-merge": "^6.0.1",
"webpack-sources": "^3.2.3",
"xml-crypto": "^6.0.0",
"xmlbuilder": "13.0.2",
"yargs": "^15.4.1",

View file

@ -9,7 +9,7 @@
import { BehaviorSubject } from 'rxjs';
jest.mock('!!raw-loader!./disable_animations.css', () => 'MOCK DISABLE ANIMATIONS CSS');
jest.mock('./disable_animations.css?raw', () => 'MOCK DISABLE ANIMATIONS CSS');
import { StylesService } from './styles_service';
import { uiSettingsServiceMock } from '@kbn/core-ui-settings-browser-mocks';

View file

@ -12,7 +12,7 @@ import { Subscription } from 'rxjs';
import type { CoreService } from '@kbn/core-base-browser-internal';
import type { IUiSettingsClient } from '@kbn/core-ui-settings-browser';
// @ts-expect-error
import disableAnimationsCss from '!!raw-loader!./disable_animations.css';
import disableAnimationsCss from './disable_animations.css?raw';
interface StartDeps {
uiSettings: IUiSettingsClient;

View file

@ -36,3 +36,15 @@ declare module '*.mdx' {
// eslint-disable-next-line import/no-default-export
export default MDXComponent;
}
declare module '*?asUrl' {
const content: string;
// eslint-disable-next-line import/no-default-export
export default string;
}
declare module '*?raw' {
const content: string;
// eslint-disable-next-line import/no-default-export
export default string;
}

View file

@ -41,6 +41,7 @@ RUNTIME_DEPS = [
"@npm//babel-plugin-styled-components",
"@npm//babel-plugin-transform-react-remove-prop-types",
"@npm//babel-plugin-transform-typescript-metadata",
"@npm//babel-plugin-transform-require-default",
]
js_library(

View file

@ -10,7 +10,12 @@
const { USES_STYLED_COMPONENTS } = require('./styled_components_files');
/** @type {import('@babel/core').ConfigFunction} */
module.exports = (api, options = {}) => {
module.exports = (
api,
options = {
useTransformRequireDefault: false,
}
) => {
return {
presets: [
[
@ -27,6 +32,18 @@ module.exports = (api, options = {}) => {
],
[require('./common_preset'), options],
],
plugins: [
// Conditionally include babel-plugin-transform-require-default
//
// We need to include this plugin in the main worker webpack config that handles our
// non node modules code base in order to support resolving esm
// as a priority over cjs (if that's defined in the mainFields). Without that we might run into
// cases where we have a repo wide cjs code that requires an esm module (coming from the ui-shared-deps that also prioritizes esm)
// which will not be applying the .default key in the require itself.
...(options.useTransformRequireDefault
? [require.resolve('babel-plugin-transform-require-default')]
: []),
],
env: {
production: {
plugins: [

View file

@ -10,6 +10,7 @@
import { v4 as uuid } from 'uuid';
import { defineConfig } from 'cypress';
import wp from '@cypress/webpack-preprocessor';
import { NodeLibsBrowserPlugin } from '@kbn/node-libs-browser-webpack-plugin';
export function defineCypressConfig(options?: Cypress.ConfigOptions<any>) {
return defineConfig({
@ -43,6 +44,7 @@ export function defineCypressConfig(options?: Cypress.ConfigOptions<any>) {
},
],
},
plugins: [new NodeLibsBrowserPlugin()],
},
})(file);
});

View file

@ -13,5 +13,7 @@
"exclude": [
"target/**/*"
],
"kbn_references": []
"kbn_references": [
"@kbn/node-libs-browser-webpack-plugin",
]
}

View file

@ -104,8 +104,8 @@ export const NoBoundaryCrossingRule: Rule.RuleModule = {
return visitAllImportStatements((req, { node, importer, type }) => {
if (
req === null ||
// we can ignore imports using the raw-loader, they will need to be resolved but can be managed on a case by case basis
req.startsWith('!!raw-loader') ||
// we can ignore imports using the ?raw (replacing legacy raw-loader), they will need to be resolved but can be managed on a case by case basis
req.endsWith('?raw') ||
// type only imports can stretch across all the boundaries
isTypeOnlyImport(importer)
) {

View file

@ -231,8 +231,8 @@ export class ImportResolver {
resolve(req: string, dirname: string): ResolveResult | null {
// transform webpack loader requests and focus on the actual file selected
const lastExI = req.lastIndexOf('!');
if (lastExI > -1) {
const quesI = req.lastIndexOf('?');
const quesI = req.lastIndexOf('?');
if (lastExI > -1 || quesI > -1) {
const prefix = req.slice(0, lastExI + 1);
const postfix = quesI > -1 ? req.slice(quesI) : '';
const result = this.resolve(req.slice(lastExI + 1, quesI > -1 ? quesI : undefined), dirname);

View file

@ -33,10 +33,8 @@ import type {
// @ts-expect-error
import maplibreglDist from 'maplibre-gl/dist/maplibre-gl-csp';
// @ts-expect-error
import mbRtlPlugin from '!!file-loader!@mapbox/mapbox-gl-rtl-text/mapbox-gl-rtl-text.min.js';
// @ts-expect-error
import mbWorkerUrl from '!!file-loader!maplibre-gl/dist/maplibre-gl-csp-worker';
import mbRtlPlugin from '@mapbox/mapbox-gl-rtl-text/mapbox-gl-rtl-text.min.js?asUrl';
import mbWorkerUrl from 'maplibre-gl/dist/maplibre-gl-csp-worker?asUrl';
import 'maplibre-gl/dist/maplibre-gl.css';
const maplibregl: any = maplibreglDist;

View file

@ -2,7 +2,7 @@
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "target/types",
"types": []
"types": ["@kbn/ambient-ui-types"]
},
"include": [
"**/*.ts",

View file

@ -28,6 +28,7 @@ SHARED_DEPS = [
"//packages/kbn-ui-theme",
"//packages/kbn-esql-validation-autocomplete",
"//packages/kbn-esql-ast",
"//packages/kbn-node-libs-browser-webpack-plugin",
"@npm//antlr4",
"@npm//monaco-editor",
"@npm//monaco-yaml",
@ -41,7 +42,6 @@ webpack_cli(
"@npm//terser-webpack-plugin",
"@npm//@babel/runtime",
"@npm//babel-loader",
"@npm//raw-loader",
"@npm//rxjs",
"webpack.config.js",
@ -59,11 +59,9 @@ webpack_cli(
env = select({
"//:dist": {
"NODE_ENV": "production",
"NODE_OPTIONS": "--openssl-legacy-provider",
},
"//conditions:default": {
"NODE_ENV": "development",
"NODE_OPTIONS": "--openssl-legacy-provider",
},
}),
visibility = ["//visibility:public"],

View file

@ -8,6 +8,7 @@
*/
const path = require('path');
const { NodeLibsBrowserPlugin } = require('@kbn/node-libs-browser-webpack-plugin');
const getWorkerEntry = (language) => {
switch (language) {
@ -30,7 +31,8 @@ const workerConfig = (languages) => ({
entries[language] = getWorkerEntry(language);
return entries;
}, {}),
devtool: process.env.NODE_ENV === 'production' ? false : '#cheap-source-map',
devtool: process.env.NODE_ENV === 'production' ? false : 'cheap-source-map',
target: 'web',
output: {
path: path.resolve(__dirname, 'target_workers'),
filename: ({ chunk }) => `${chunk.name}.editor.worker.js`,
@ -42,6 +44,7 @@ const workerConfig = (languages) => ({
'vscode-uri$': require.resolve('vscode-uri').replace(/\/umd\/index.js/, '/esm/index.mjs'),
},
},
plugins: [new NodeLibsBrowserPlugin()],
stats: 'errors-only',
module: {
rules: [

View file

@ -0,0 +1,40 @@
load("@npm//@bazel/typescript:index.bzl", "ts_config")
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
load("//src/dev/bazel:index.bzl", "pkg_npm", "ts_project")
SRCS = glob(
[
"**/*.js",
"**/*.ts",
],
exclude = [
"**/*.config.js",
"**/*.mock.*",
"**/*.test.*",
"**/*.stories.*",
"**/__snapshots__/**",
"**/integration_tests/**",
"**/mocks/**",
"**/scripts/**",
"**/storybook/**",
"**/test_fixtures/**",
"**/test_helpers/**",
],
)
BUNDLER_DEPS = [
"@npm//node-libs-browser",
]
filegroup(
name = 'root_pkg_json',
srcs = ["//:package.json"]
)
js_library(
name = "kbn-node-libs-browser-webpack-plugin",
package_name = "@kbn/node-libs-browser-webpack-plugin",
srcs = ["package.json"] + SRCS,
deps = BUNDLER_DEPS,
visibility = ["//visibility:public"],
)

View file

@ -0,0 +1,3 @@
# @kbn/node-libs-browser-webpack-plugin
Empty package generated by @kbn/generate

View file

@ -0,0 +1,75 @@
/*
* 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/
/** @typedef {import('webpack').Compiler} WebpackCompiler */
/* eslint-disable import/no-extraneous-dependencies */
// @ts-expect-error
const nodeLibsBrowser = require('node-libs-browser');
const NodeLibsBrowserPlugin = class NodeLibsBrowserPlugin {
/**
* @param {WebpackCompiler} compiler
*/
apply(compiler) {
compiler.options.plugins.push(
new compiler.webpack.ProvidePlugin({
Buffer: [nodeLibsBrowser.buffer, 'Buffer'],
console: nodeLibsBrowser.console,
process: nodeLibsBrowser.process,
})
);
compiler.options.resolve.fallback = {
assert: nodeLibsBrowser.assert,
buffer: nodeLibsBrowser.buffer,
child_process: false,
cluster: false,
console: false,
constants: nodeLibsBrowser.constants,
crypto: nodeLibsBrowser.crypto,
dgram: false,
dns: false,
domain: nodeLibsBrowser.domain,
events: nodeLibsBrowser.events,
fs: false,
http: nodeLibsBrowser.http,
https: nodeLibsBrowser.https,
module: false,
net: false,
os: nodeLibsBrowser.os,
path: nodeLibsBrowser.path,
punycode: nodeLibsBrowser.punycode,
process: nodeLibsBrowser.process,
querystring: nodeLibsBrowser.querystring,
readline: false,
repl: false,
stream: nodeLibsBrowser.stream,
_stream_duplex: nodeLibsBrowser._stream_duplex,
_stream_passthrough: nodeLibsBrowser._stream_passthrough,
_stream_readable: nodeLibsBrowser._stream_readable,
_stream_transform: nodeLibsBrowser._stream_transform,
_stream_writable: nodeLibsBrowser._stream_writable,
string_decoder: nodeLibsBrowser.string_decoder,
sys: nodeLibsBrowser.sys,
timers: nodeLibsBrowser.timers,
tls: false,
tty: nodeLibsBrowser.tty,
url: nodeLibsBrowser.url,
util: nodeLibsBrowser.util,
vm: nodeLibsBrowser.vm,
zlib: nodeLibsBrowser.zlib,
...compiler.options.resolve.fallback,
};
}
};
module.exports = {
NodeLibsBrowserPlugin,
};

View file

@ -7,6 +7,8 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
import { discoverStorybookConfig } from './discover.webpack';
module.exports = discoverStorybookConfig;
module.exports = {
preset: '@kbn/test/jest_node',
rootDir: '../..',
roots: ['<rootDir>/packages/kbn-node-libs-browser-webpack-plugin'],
};

View file

@ -0,0 +1,5 @@
{
"type": "shared-common",
"id": "@kbn/node-libs-browser-webpack-plugin",
"owner": "@elastic/kibana-operations"
}

View file

@ -0,0 +1,7 @@
{
"name": "@kbn/node-libs-browser-webpack-plugin",
"devOnly": true,
"private": true,
"version": "1.0.0",
"license": "Elastic License 2.0 OR AGPL-3.0-only OR SSPL-1.0"
}

View file

@ -0,0 +1,18 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"checkJs": true,
"outDir": "target/types",
"types": [
"jest",
"node"
]
},
"include": [
"index.js",
"types.ts"
],
"exclude": [
"target/**/*",
]
}

View file

@ -17,6 +17,8 @@ export type {
} from './src/webpack_helpers';
export {
STATS_WARNINGS_FILTER,
STATS_OPTIONS_DEFAULT_USEFUL_FILTER,
isFailureStats,
failedStatsToErrorMessage,
getModulePath,
@ -25,4 +27,5 @@ export {
isExternalModule,
isIgnoredModule,
isNormalModule,
isRuntimeModule,
} from './src/webpack_helpers';

View file

@ -8,46 +8,31 @@
*/
import webpack from 'webpack';
// @ts-expect-error module is not typed
import Stats from 'webpack/lib/Stats';
export function isFailureStats(stats: webpack.Stats) {
if (stats.hasErrors()) {
return true;
}
const { warnings } = stats.toJson({ all: false, warnings: true });
const { warnings } = stats.toJson({
all: false,
warnings: true,
});
// 1 - when typescript doesn't do a full type check, as we have the ts-loader
// configured here, it does not have enough information to determine
// whether an imported name is a type or not, so when the name is then
// exported, typescript has no choice but to emit the export. Fortunately,
// the extraneous export should not be harmful, so we just suppress these warnings
// https://github.com/TypeStrong/ts-loader#transpileonly-boolean-defaultfalse
//
// 2 - Mini Css Extract plugin tracks the order for each css import we have
// through the project (and it's successive imports) since version 0.4.2.
// In case we have the same imports more than one time with different
// sequences, this plugin will throw a warning. This should not be harmful,
// but the an issue was opened and can be followed on:
// https://github.com/webpack-contrib/mini-css-extract-plugin/issues/250#issuecomment-415345126
const filteredWarnings = Stats.filterWarnings(warnings, STATS_WARNINGS_FILTER);
return filteredWarnings.length > 0;
return warnings && warnings.length > 0;
}
const STATS_WARNINGS_FILTER = new RegExp(
export const STATS_WARNINGS_FILTER = new RegExp(
[
'(export .* was not found in)',
'(export .* was not found in)', // with reexportExportsPresence = false and importExportsPresence = false in the module parser this should not be necessary but looks like it affects performance
'|(chunk .* \\[mini-css-extract-plugin\\]\\\nConflicting order between:)',
].join('')
);
export function failedStatsToErrorMessage(stats: webpack.Stats) {
const details = stats.toString({
...Stats.presetToOptions('minimal'),
...stats.compilation.createStatsOptions('minimal'),
colors: true,
warningsFilter: STATS_WARNINGS_FILTER,
errors: true,
errorDetails: true,
moduleTrace: true,
@ -56,6 +41,21 @@ export function failedStatsToErrorMessage(stats: webpack.Stats) {
return `Optimizations failure.\n${details.split('\n').join('\n ')}`;
}
export const STATS_OPTIONS_DEFAULT_USEFUL_FILTER = {
all: false,
hash: true,
version: true,
timings: true,
assets: true,
modules: true,
reasons: true,
chunks: true,
chunkModules: true,
errorDetails: false,
entrypoints: true,
ids: true,
};
export interface WebpackResolveData {
/** compilation context */
context: string;
@ -103,7 +103,7 @@ export interface WebpackNormalModule {
resource: string;
buildInfo: {
cacheable: boolean;
fileDependencies: Set<string>;
buildDependencies: Set<string>;
};
dependencies: Dependency[];
}
@ -122,7 +122,7 @@ export interface WebpackIgnoredModule {
}
export function isIgnoredModule(module: any): module is WebpackIgnoredModule {
return module?.constructor?.name === 'RawModule' && module.identifierStr?.startsWith('ignored ');
return module?.constructor?.name === 'RawModule' && module.identifierStr?.startsWith('ignored');
}
/** module replacing imports for webpack externals */
@ -169,3 +169,7 @@ export function getModulePath(module: WebpackNormalModule) {
const queryIndex = module.resource.indexOf('?');
return queryIndex === -1 ? module.resource : module.resource.slice(0, queryIndex);
}
export function isRuntimeModule(module: any): boolean {
return module instanceof webpack.RuntimeModule;
}

View file

@ -31,7 +31,7 @@ pageLoadAssetSize:
dataUsage: 30000
dataViewEditor: 28082
dataViewFieldEditor: 42021
dataViewManagement: 5300
dataViewManagement: 6250
dataViews: 65000
dataVisualizer: 27530
devTools: 38637
@ -122,8 +122,8 @@ pageLoadAssetSize:
observabilityShared: 80000
osquery: 107090
painlessLab: 179748
presentationPanel: 55463
presentationUtil: 58834
presentationPanel: 44000
presentationUtil: 33905
profiling: 36694
remoteClusters: 51327
reporting: 58600

View file

@ -122,7 +122,7 @@ export class BundleCache {
}
}
public writeWebpackAsset(compilation: webpack.compilation.Compilation) {
public writeWebpackAsset(compilation: webpack.Compilation) {
if (!this.path) {
return;
}

View file

@ -62,12 +62,19 @@ function usingWorkerProc<T>(config: OptimizerConfig, fn: (proc: ChildProcess) =>
const proc = fork(require.resolve('../worker/run_worker'), [], {
execArgv: [
`--require=@kbn/babel-register/install`,
'--openssl-legacy-provider',
...(inspectFlag && config.inspectWorkers
? [`${inspectFlag}=${inspectPortCounter++}`]
: []),
],
stdio: ['ignore', 'pipe', 'pipe', 'ipc'],
env: {
// NOTE: with the default 2000 limit we get a lot of recursive watcher recreations (introduced in watchpack v2)
// which makes the experience horrible and the performance between 2.5x to 3x worse when watching.
// If that fails in other mac machines with lower defaults for maxfiles and maxfilesperproc
// or just low powerful ones we need to default to polling instead of relying in the OS events watcher system.
// That can be done in the worker/run_compilers file.
WATCHPACK_WATCHER_LIMIT: '4000',
},
});
return {

View file

@ -22,6 +22,36 @@ jest.mock('os', () => {
cpus() {
return ['foo'] as any;
},
totalmem() {
return 64000000000;
},
freemem() {
return 20000000000;
},
};
});
jest.mock('v8', () => {
return {
...jest.requireActual('v8'),
getHeapStatistics() {
return {
total_heap_size: 5816320,
total_heap_size_executable: 262144,
total_physical_size: 6012928,
total_available_size: 4341242192,
used_heap_size: 4930768,
heap_size_limit: 4345298944,
malloced_memory: 262320,
peak_malloced_memory: 571392,
does_zap_garbage: 0,
number_of_native_contexts: 2,
number_of_detached_contexts: 0,
total_global_handles_size: 8192,
used_global_handles_size: 3296,
external_memory: 2209666,
};
},
};
});

View file

@ -33,15 +33,59 @@ export interface Limits {
};
}
function pickMaxWorkerCount(dist: boolean) {
// don't break if cpus() returns nothing, or an empty array
const cpuCount = Math.max(Os.cpus()?.length, 1);
// if we're buiding the dist then we can use more of the system's resources to get things done a little quicker
const maxWorkers = dist ? cpuCount - 1 : Math.ceil(cpuCount / 3);
// ensure we always have at least two workers
return Math.max(maxWorkers, 2);
interface SystemInfo {
cpuCount: number;
}
function getSystemInfo(): SystemInfo {
// collects useful system information for resource usage calculations
const cpuCount = Math.max(Os.cpus()?.length ?? 0, 1);
return { cpuCount };
}
const pickMaxWorkerCount = (dist: boolean) => {
const isDist = dist;
const isCI = !!process.env.CI;
const isUseMaxAvailableResources = !!process.env.KBN_OPTIMIZER_USE_MAX_AVAILABLE_RESOURCES;
const minWorkers = 2;
const { cpuCount } = getSystemInfo();
const maxWorkers = Math.max(cpuCount - 1, minWorkers);
// In case we get this env var set, just use max workers and avoid any kind of
// resource balance according to memory and cpu
if (isUseMaxAvailableResources) {
return maxWorkers;
}
// Start calculating base worker count
let workerCount;
if (isDist && isCI) {
// For CI dist builds, start with most available resources
workerCount = maxWorkers;
} else if (isDist) {
// For local dist builds, start with 80% of resources but leaving some headroom
workerCount = Math.max(Math.floor(cpuCount * 0.8), 2);
} else {
// For regular local builds, start with fewer resources of 50%
workerCount = Math.max(Math.floor(cpuCount * 0.5), 2);
}
// Adjust by the ratio workerCount to maxWorkers.
// If it is lower or equal to 50% it adds an extra worker
// so the available resources are better used
const ratioWorkerCountToMaxWorkers = 1 - workerCount / maxWorkers;
if (ratioWorkerCountToMaxWorkers >= 0.5) {
workerCount = Math.min(workerCount + 1, cpuCount);
}
// Make sure we respect min and max worker limits
workerCount = Math.max(workerCount, minWorkers);
workerCount = Math.min(workerCount, maxWorkers);
return workerCount;
};
interface Options {
/** absolute path to root of the repo/build */
repoRoot: string;

View file

@ -32,82 +32,90 @@ export class BundleMetricsPlugin {
const { bundle } = this;
compiler.hooks.emit.tap('BundleMetricsPlugin', (compilation) => {
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;
compiler.hooks.compilation.tap('BundleMetricsPlugin', (compilation) => {
compilation.hooks.processAssets.tap(
{
name: 'BundleMetricsPlugin',
stage: webpack.Compilation.PROCESS_ASSETS_STAGE_ANALYSE,
},
() => {
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 entryName = `${bundle.id}.${bundle.type}.js`;
const entry = assets.find((a) => a.name === entryName);
if (!entry) {
throw new Error(
`Unable to find bundle entry named [${entryName}] in [${bundle.outputDir}]`
);
}
const ext = Path.extname(filename);
if (IGNORED_EXTNAME.includes(ext)) {
return false;
const chunkPrefix = `${bundle.id}.chunk.`;
const asyncChunks = assets.filter((a) => a.name.startsWith(chunkPrefix));
const miscFiles = assets.filter((a) => a !== entry && !asyncChunks.includes(a));
const sumSize = (files: Asset[]) => files.reduce((acc: number, a) => acc + a.size, 0);
const moduleCount = bundle.cache.getModuleCount();
if (moduleCount === undefined) {
throw new Error(`moduleCount wasn't populated by PopulateBundleCachePlugin`);
}
return true;
});
const bundleMetrics: CiStatsMetric[] = [
{
group: `@kbn/optimizer bundle module count`,
id: bundle.id,
value: moduleCount,
},
{
group: `page load bundle size`,
id: bundle.id,
value: entry.size,
limit: bundle.pageLoadAssetSizeLimit,
limitConfigPath: `packages/kbn-optimizer/limits.yml`,
},
{
group: `async chunks size`,
id: bundle.id,
value: sumSize(asyncChunks),
},
{
group: `async chunk count`,
id: bundle.id,
value: asyncChunks.length,
},
{
group: `miscellaneous assets size`,
id: bundle.id,
value: sumSize(miscFiles),
},
];
const entryName = `${bundle.id}.${bundle.type}.js`;
const entry = assets.find((a) => a.name === entryName);
if (!entry) {
throw new Error(
`Unable to find bundle entry named [${entryName}] in [${bundle.outputDir}]`
);
}
const metricsSource = new RawSource(JSON.stringify(bundleMetrics, null, 2));
const chunkPrefix = `${bundle.id}.chunk.`;
const asyncChunks = assets.filter((a) => a.name.startsWith(chunkPrefix));
const miscFiles = assets.filter((a) => a !== entry && !asyncChunks.includes(a));
const sumSize = (files: Asset[]) => files.reduce((acc: number, a) => acc + a.size, 0);
const moduleCount = bundle.cache.getModuleCount();
if (moduleCount === undefined) {
throw new Error(`moduleCount wasn't populated by PopulateBundleCachePlugin`);
}
const bundleMetrics: CiStatsMetric[] = [
{
group: `@kbn/optimizer bundle module count`,
id: bundle.id,
value: moduleCount,
},
{
group: `page load bundle size`,
id: bundle.id,
value: entry.size,
limit: bundle.pageLoadAssetSizeLimit,
limitConfigPath: `packages/kbn-optimizer/limits.yml`,
},
{
group: `async chunks size`,
id: bundle.id,
value: sumSize(asyncChunks),
},
{
group: `async chunk count`,
id: bundle.id,
value: asyncChunks.length,
},
{
group: `miscellaneous assets size`,
id: bundle.id,
value: sumSize(miscFiles),
},
];
const metricsSource = new RawSource(JSON.stringify(bundleMetrics, null, 2));
// see https://github.com/jantimon/html-webpack-plugin/blob/33d69f49e6e9787796402715d1b9cd59f80b628f/index.js#L266
// @ts-expect-error undocumented, used to add assets to the output
compilation.emitAsset('metrics.json', metricsSource);
// see https://github.com/jantimon/html-webpack-plugin/blob/33d69f49e6e9787796402715d1b9cd59f80b628f/index.js#L266
// @ts-expect-error undocumented, used to add assets to the output
compilation.emitAsset('metrics.json', metricsSource);
}
);
});
}
}

View file

@ -12,6 +12,7 @@ import { KbnImportReq } from '@kbn/repo-packages';
// @ts-ignore not typed by @types/webpack
import Module from 'webpack/lib/Module';
import { RawSource } from 'webpack-sources';
import { BundleRemote } from '../common';
export class BundleRemoteModule extends Module {
@ -27,8 +28,8 @@ export class BundleRemoteModule extends Module {
return this.req.full;
}
chunkCondition(chunk: any) {
return chunk.hasEntryModule();
chunkCondition(chunk: any, { chunkGraph }: any) {
return chunkGraph.getNumberOfEntryModules(chunk) > 0;
}
identifier() {
@ -39,19 +40,56 @@ export class BundleRemoteModule extends Module {
return this.identifier();
}
needRebuild() {
return false;
needBuild(context: any, callback: any) {
return callback(null, !this.buildMeta);
}
build(_: any, __: any, ___: any, ____: any, callback: () => void) {
this.built = true;
this.buildMeta = {};
this.buildMeta = {
async: false,
exportsType: undefined,
};
this.buildInfo = {
strict: false,
topLevelDeclarations: new Set(),
module: __.outputOptions.module,
exportsArgument: '__webpack_exports__',
};
// super.addDependency(new StaticExportsDependency(true, false));
callback();
}
getConcatenationBailoutReason({ moduleGraph }: any) {
return `@kbn/bundleRemote externals can't be concatenated`;
}
codeGeneration(_: any) {
const sources = new Map();
sources.set(
'javascript',
new RawSource(`
__webpack_require__.r(__webpack_exports__);
var ns = __kbnBundles__.get('${this.remote.bundleType}/${this.remote.bundleId}/${this.req.target}');
Object.defineProperties(__webpack_exports__, Object.getOwnPropertyDescriptors(ns))
`)
);
const data = new Map();
data.set('url', this.req.full);
return {
sources,
runtimeRequirements: new Set([
'module',
'__webpack_exports__',
'__webpack_require__',
// '__webpack_require__.r',
]),
data,
};
}
source() {
return `
__webpack_require__.r(__webpack_exports__);
@ -64,8 +102,8 @@ export class BundleRemoteModule extends Module {
return 42;
}
updateHash(hash: any) {
updateHash(hash: any, context: any) {
hash.update(this.identifier());
super.updateHash(hash);
super.updateHash(hash, context);
}
}

View file

@ -0,0 +1,75 @@
/*
* 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/
import NormalizePath from 'normalize-path';
import webpack from 'webpack';
import { Minimatch } from 'minimatch';
import { Bundle } from '../common';
export class BundleRemoteUsedExportsPlugin {
constructor(private readonly bundle: Bundle) {}
apply(compiler: webpack.Compiler) {
const buildPublicDirsPatterns = () => {
const targets = this.bundle.remoteInfo.targets;
const extensions = '.{js,ts,tsx,json}';
const builtPattern = !targets.length
? 'public'
: targets.length === 1
? targets[0]
: `{${targets}}`;
return [`**/${builtPattern}/index${extensions}`, `**/${builtPattern}${extensions}`];
};
const publicDirsPatterns = buildPublicDirsPatterns();
const KbnPluginMainEntryGlob = new Minimatch(publicDirsPatterns[0]);
const KbnPluginExtraFileEntryGlob = new Minimatch(publicDirsPatterns[1]);
compiler.hooks.compilation.tap('MarkExportsAsUsedPlugin', (compilation) => {
const moduleGraph = compilation.moduleGraph;
compilation.hooks.optimizeDependencies.tap('MarkExportsAsUsedPlugin', (modules) => {
Array.from(modules).forEach((module: any) => {
if (!module.resource) {
return;
}
const normalizedModuleResource = NormalizePath(module.resource);
if (
KbnPluginMainEntryGlob.match(normalizedModuleResource) ||
KbnPluginExtraFileEntryGlob.match(normalizedModuleResource)
) {
// Get all exports of the module
const exportsInfo = moduleGraph.getExportsInfo(module);
// If the module uses export *, mark it as used in unknown way
if (module.buildMeta && module.buildMeta.exportsType === 'namespace') {
// @ts-ignore
moduleGraph.getExportsInfo(module).setAllKnownExportsUsed();
// @ts-ignore
moduleGraph.getExportsInfo(module).setUsedInUnknownWay();
moduleGraph.addExtraReason(
module,
`BundleRemoteUsedExportsPlugin/namespace#=>${module.resource}`
);
} else {
Array.from(exportsInfo.exports).forEach((exportInfo) => {
if (exportInfo.name) {
moduleGraph.getExportsInfo(module).setUsedInUnknownWay(exportInfo.name);
moduleGraph.addExtraReason(
module,
`BundleRemoteUsedExportsPlugin/${exportInfo.name}#=>${module.resource}`
);
}
});
}
}
});
});
});
}
}

View file

@ -21,7 +21,6 @@ interface RequestData {
}
type Callback<T> = (error?: any, result?: T) => void;
type ModuleFactory = (data: RequestData, callback: Callback<BundleRemoteModule>) => void;
export class BundleRemotesPlugin {
private allowedBundleIds = new Set<string>();
@ -40,34 +39,33 @@ export class BundleRemotesPlugin {
// hook into the creation of NormalModule instances in webpack, if the import
// statement leading to the creation of the module is pointing to a bundleRef
// entry then create a BundleRefModule instead of a NormalModule.
compilationParams.normalModuleFactory.hooks.factory.tap(
'BundleRefsPlugin/normalModuleFactory/factory',
(wrappedFactory: ModuleFactory): ModuleFactory =>
(data, callback) => {
const { request } = data.dependencies[0];
compilationParams.normalModuleFactory.hooks.factorize.tapAsync(
'BundleRefsPlugin/normalModuleFactory/factorize',
(data: RequestData, callback: Callback<BundleRemoteModule>) => {
const { request } = data.dependencies[0];
const cached = moduleCache.get(request);
if (cached === null) {
return wrappedFactory(data, callback);
}
if (cached !== undefined) {
return callback(null, cached);
}
this.resolve(request, (error, result) => {
if (error || result === undefined) {
return callback(error);
}
moduleCache.set(request, result);
if (result === null) {
return wrappedFactory(data, callback);
}
callback(null, result);
});
const cached = moduleCache.get(request);
if (cached === null) {
return callback();
}
if (cached !== undefined) {
return callback(null, cached);
}
this.resolve(request, (error, result) => {
if (error || result === undefined) {
return callback(error);
}
moduleCache.set(request, result);
if (result === null) {
return callback();
}
callback(null, result);
});
}
);
});
@ -87,7 +85,7 @@ export class BundleRemotesPlugin {
compilation.hooks.finishModules.tapPromise(
'BundleRefsPlugin/finishModules',
async (modules) => {
const usedBundleIds = (modules as any[])
const usedBundleIds = (Array.from(modules) as any[])
.filter((m: any): m is BundleRemoteModule => m instanceof BundleRemoteModule)
.map((m) => m.remote.bundleId);
@ -96,7 +94,7 @@ export class BundleRemotesPlugin {
.join(', ');
if (unusedBundleIds) {
const error = new Error(
const error = new webpack.WebpackError(
`Bundle for [${this.bundle.id}] lists [${unusedBundleIds}] as a required bundle, but does not use it. Please remove it.`
);
(error as any).file = manifestPath;
@ -108,7 +106,9 @@ export class BundleRemotesPlugin {
}
public resolve(request: string, cb: (error?: Error, bundle?: null | BundleRemoteModule) => void) {
if (request.endsWith('.json')) {
// NOTE: previously on webpack v4 ?raw files did not reach this phase and were excluded
// which is not the case anymore in webpack v5 so we need to do exclude them from being resolved
if (request.endsWith('.json') || request.endsWith('?raw')) {
return cb(undefined, null);
}

View file

@ -11,7 +11,7 @@ import Fs from 'fs';
import Path from 'path';
import webpack from 'webpack';
import { STATS_OPTIONS_DEFAULT_USEFUL_FILTER } from '@kbn/optimizer-webpack-helpers';
import { Bundle } from '../common';
export class EmitStatsPlugin {
@ -27,7 +27,7 @@ export class EmitStatsPlugin {
(stats) => {
Fs.writeFileSync(
Path.resolve(this.bundle.outputDir, 'stats.json'),
JSON.stringify(stats.toJson(), null, 2)
JSON.stringify(stats.toJson(STATS_OPTIONS_DEFAULT_USEFUL_FILTER), null, 2)
);
}
);

View file

@ -8,7 +8,7 @@
*/
import Path from 'path';
import { inspect } from 'util';
import { inspect, promisify } from 'util';
import webpack from 'webpack';
import {
@ -17,6 +17,7 @@ import {
isIgnoredModule,
isConcatenatedModule,
isDelegatedModule,
isRuntimeModule,
getModulePath,
} from '@kbn/optimizer-webpack-helpers';
@ -30,6 +31,14 @@ import {
} from '../common';
import { BundleRemoteModule } from './bundle_remote_module';
interface InputFileSystem {
readFile: (
path: string,
encoding: null | undefined,
callback: (err: Error | null, stats: Buffer) => void
) => void;
}
/**
* sass-loader creates about a 40% overhead on the overall optimizer runtime, and
* so this constant is used to indicate to assignBundlesToWorkers() that there is
@ -48,117 +57,157 @@ export class PopulateBundleCachePlugin {
public apply(compiler: webpack.Compiler) {
const { bundle, workerConfig } = this;
const inputFs = compiler.inputFileSystem as InputFileSystem;
if (!inputFs) {
throw new Error('expected inputFs to be defined');
}
const readFile = promisify(inputFs.readFile);
const moduleFileDepsMap = new Map();
const allFileDepsPathSet = new Set();
compiler.hooks.emit.tap(
{
name: 'PopulateBundleCachePlugin',
before: ['BundleMetricsPlugin'],
},
(compilation) => {
const bundleRefExportIds: string[] = [];
let moduleCount = 0;
let workUnits = compilation.fileDependencies.size;
compiler.hooks.compilation.tap('PopulateBundleCachePlugin', (compilation) => {
const hooks = webpack.NormalModule.getCompilationHooks(compilation);
const paths = new Set<string>();
const rawHashes = new Map<string, string | null>();
const addReferenced = (path: string) => {
if (paths.has(path)) {
return;
// first collect file deps for modules
hooks.beforeSnapshot.tap('PopulateBundleCachePlugin', (module: any) => {
// make sure we have file deps for this module
if (module.buildInfo.fileDependencies.size > 0) {
const realFileDeps = [];
for (const path of module.buildInfo.fileDependencies) {
// in webpack v5 there a lot of paths collected that are not real files
// but instead folders or partial paths.
// Here we're verifying if what we have as indeed a filepath
if (Path.extname(path).length > 0) {
realFileDeps.push(path);
allFileDepsPathSet.add(path);
}
}
paths.add(path);
let content: Buffer;
try {
content = compiler.inputFileSystem.readFileSync(path);
} catch {
return rawHashes.set(path, null);
}
return rawHashes.set(path, Hashes.hash(content));
};
const dllRefKeys = new Set<string>();
if (bundle.manifestPath) {
addReferenced(bundle.manifestPath);
moduleFileDepsMap.set(module.identifier(), realFileDeps);
}
});
for (const module of compilation.modules) {
if (isNormalModule(module)) {
moduleCount += 1;
const path = getModulePath(module);
const parsedPath = parseFilePath(path);
// in the end process assets to calculate workUnites and references
compilation.hooks.processAssets.tapAsync(
{
name: 'PopulateBundleCachePlugin',
stage: webpack.Compilation.PROCESS_ASSETS_STAGE_DEV_TOOLING,
},
async (_, callback) => {
const bundleRefExportIds: string[] = [];
let moduleCount = 0;
let workUnits = allFileDepsPathSet.size;
// TODO: Does this need to be updated to support @kbn/ packages?
if (!parsedPath.dirs.includes('node_modules')) {
addReferenced(path);
const paths = new Set<string>();
const rawHashes = new Map<string, string | null>();
const addReferenced = async (path: string) => {
if (paths.has(path)) {
return;
}
if (path.endsWith('.scss')) {
workUnits += EXTRA_SCSS_WORK_UNITS;
paths.add(path);
let content: Buffer;
try {
content = await readFile(path, null);
} catch {
return rawHashes.set(path, null);
}
for (const depPath of module.buildInfo.fileDependencies) {
addReferenced(depPath);
}
return rawHashes.set(path, Hashes.hash(content));
};
const dllRefKeys = new Set<string>();
if (bundle.manifestPath) {
await addReferenced(bundle.manifestPath);
workUnits += 1;
}
for (const module of compilation.modules) {
if (isNormalModule(module)) {
const path = getModulePath(module);
if (Path.extname(path).length === 0) {
continue;
}
moduleCount += 1;
const parsedPath = parseFilePath(path);
if (!parsedPath.dirs.includes('node_modules')) {
await addReferenced(path);
if (path.endsWith('.scss')) {
workUnits += EXTRA_SCSS_WORK_UNITS;
const dependencies = moduleFileDepsMap.get(module.identifier());
if (dependencies) {
await Promise.all(
dependencies.map((depPath: string) => addReferenced(depPath))
);
}
}
continue;
}
const nmIndex = parsedPath.dirs.lastIndexOf('node_modules');
const isScoped = parsedPath.dirs[nmIndex + 1].startsWith('@');
const pkgJsonPath = Path.join(
parsedPath.root,
...parsedPath.dirs.slice(0, nmIndex + 1 + (isScoped ? 2 : 1)),
'package.json'
);
await addReferenced(pkgJsonPath);
continue;
}
const nmIndex = parsedPath.dirs.lastIndexOf('node_modules');
const isScoped = parsedPath.dirs[nmIndex + 1].startsWith('@');
const pkgJsonPath = Path.join(
parsedPath.root,
...parsedPath.dirs.slice(0, nmIndex + 1 + (isScoped ? 2 : 1)),
'package.json'
);
addReferenced(pkgJsonPath);
continue;
if (module instanceof BundleRemoteModule) {
bundleRefExportIds.push(module.req.full);
continue;
}
if (isConcatenatedModule(module)) {
moduleCount += 1;
continue;
}
if (isDelegatedModule(module)) {
dllRefKeys.add(module.userRequest);
continue;
}
if (isExternalModule(module) || isIgnoredModule(module) || isRuntimeModule(module)) {
continue;
}
throw new Error(`Unexpected module type: ${inspect(module)}`);
}
if (module instanceof BundleRemoteModule) {
bundleRefExportIds.push(module.req.full);
continue;
}
const referencedPaths = Array.from(paths).sort(ascending((p) => p));
const sortedDllRefKeys = Array.from(dllRefKeys).sort(ascending((p) => p));
if (isConcatenatedModule(module)) {
moduleCount += module.modules.length;
continue;
}
if (isDelegatedModule(module)) {
// delegated modules are the references to the ui-shared-deps-npm dll
dllRefKeys.add(module.userRequest);
continue;
}
if (isExternalModule(module) || isIgnoredModule(module)) {
continue;
}
throw new Error(`Unexpected module type: ${inspect(module)}`);
}
const referencedPaths = Array.from(paths).sort(ascending((p) => p));
const sortedDllRefKeys = Array.from(dllRefKeys).sort(ascending((p) => p));
bundle.cache.set({
remoteBundleImportReqs: bundleRefExportIds.sort(ascending((p) => p)),
optimizerCacheKey: workerConfig.optimizerCacheKey,
cacheKey: bundle.createCacheKey(
bundle.cache.set({
remoteBundleImportReqs: bundleRefExportIds.sort(ascending((p) => p)),
optimizerCacheKey: workerConfig.optimizerCacheKey,
cacheKey: bundle.createCacheKey(
referencedPaths,
new Hashes(rawHashes),
this.dllManifest,
sortedDllRefKeys
),
moduleCount,
workUnits,
referencedPaths,
new Hashes(rawHashes),
this.dllManifest,
sortedDllRefKeys
),
moduleCount,
workUnits,
referencedPaths,
dllRefKeys: sortedDllRefKeys,
});
dllRefKeys: sortedDllRefKeys,
});
// write the cache to the compilation so that it isn't cleaned by clean-webpack-plugin
bundle.cache.writeWebpackAsset(compilation);
}
);
// write the cache to the compilation so that it isn't cleaned by clean-webpack-plugin
bundle.cache.writeWebpackAsset(compilation);
callback();
}
);
});
}
}

View file

@ -53,7 +53,6 @@ const observeCompiler = (
*/
const complete$ = Rx.fromEventPattern<Stats>((cb) => done.tap(PLUGIN_NAME, cb)).pipe(
maybeMap((stats) => {
// @ts-expect-error not included in types, but it is real https://github.com/webpack/webpack/blob/ab4fa8ddb3f433d286653cd6af7e3aad51168649/lib/Watching.js#L58
if (stats.compilation.needAdditionalPass) {
return undefined;
}

View file

@ -7,7 +7,6 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
import { stringifyRequest, getOptions } from 'loader-utils';
import webpack from 'webpack';
import { parseThemeTags, ALL_THEMES, ThemeTag } from '../common';
@ -16,11 +15,17 @@ const getIsDark = (tag: ThemeTag) => tag.includes('dark');
const compare = (a: ThemeTag, b: ThemeTag) =>
(getVersion(a) === getVersion(b) ? 1 : 0) + (getIsDark(a) === getIsDark(b) ? 1 : 0);
const getStringifiedRequest = (loaderContext: webpack.LoaderContext<any>, request: string) => {
return JSON.stringify(
loaderContext.utils.contextify(loaderContext.context || loaderContext.rootContext, request)
);
};
// eslint-disable-next-line import/no-default-export
export default function (this: webpack.loader.LoaderContext) {
export default function (this: webpack.LoaderContext<any>) {
this.cacheable(true);
const options = getOptions(this);
const options = this.getOptions();
const bundleId = options.bundleId as string;
const themeTags = parseThemeTags(options.themeTags);
@ -28,7 +33,7 @@ export default function (this: webpack.loader.LoaderContext) {
if (themeTags.includes(tag)) {
return `
case '${tag}':
return require(${stringifyRequest(this, `${this.resourcePath}?${tag}`)});`;
return require(${getStringifiedRequest(this, `${this.resourcePath}?${tag}`)});`;
}
const fallback = themeTags
@ -40,7 +45,7 @@ export default function (this: webpack.loader.LoaderContext) {
return `
case '${tag}':
console.error(new Error(${JSON.stringify(message)}));
return require(${stringifyRequest(this, `${this.resourcePath}?${fallback}`)})`;
return require(${getStringifiedRequest(this, `${this.resourcePath}?${fallback}`)})`;
}).join('\n');
return `

View file

@ -10,22 +10,24 @@
import Path from 'path';
import Fs from 'fs';
import { stringifyRequest } from 'loader-utils';
import webpack from 'webpack';
// @ts-expect-error
import TerserPlugin from 'terser-webpack-plugin';
import webpackMerge from 'webpack-merge';
import { merge as webpackMerge } from 'webpack-merge';
import { CleanWebpackPlugin } from 'clean-webpack-plugin';
import UiSharedDepsNpm from '@kbn/ui-shared-deps-npm';
import * as UiSharedDepsSrc from '@kbn/ui-shared-deps-src';
import StatoscopeWebpackPlugin from '@statoscope/webpack-plugin';
// @ts-expect-error
import VisualizerPlugin from 'webpack-visualizer-plugin2';
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
import {
STATS_WARNINGS_FILTER,
STATS_OPTIONS_DEFAULT_USEFUL_FILTER,
} from '@kbn/optimizer-webpack-helpers';
import { NodeLibsBrowserPlugin } from '@kbn/node-libs-browser-webpack-plugin';
import { Bundle, BundleRemotes, WorkerConfig, parseDllManifest } from '../common';
import { BundleRemotesPlugin } from './bundle_remotes_plugin';
import { BundleMetricsPlugin } from './bundle_metrics_plugin';
import { BundleRemoteUsedExportsPlugin } from './bundle_remote_used_exports_plugin';
import { EmitStatsPlugin } from './emit_stats_plugin';
import { PopulateBundleCachePlugin } from './populate_bundle_cache_plugin';
@ -40,31 +42,34 @@ export function getWebpackConfig(
const ENTRY_CREATOR = require.resolve('./entry_point_creator');
const commonConfig: webpack.Configuration = {
node: { fs: 'empty' },
context: bundle.contextDir,
cache: true,
entry: {
[bundle.id]: ENTRY_CREATOR,
},
devtool: worker.dist ? false : '#cheap-source-map',
devtool: worker.dist ? false : 'cheap-source-map',
profile: worker.profileWebpack,
target: 'web',
output: {
hashFunction: 'sha1',
hashFunction: 'xxhash64',
path: bundle.outputDir,
filename: `${bundle.id}.${bundle.type}.js`,
chunkFilename: `${bundle.id}.chunk.[id].js`,
devtoolModuleFilenameTemplate: (info) =>
devtoolModuleFilenameTemplate: (info: any) =>
`/${bundle.type}:${bundle.id}/${Path.relative(
bundle.sourceRoot,
info.absoluteResourcePath
)}${info.query}`,
jsonpFunction: `${bundle.id}_bundle_jsonpfunction`,
chunkLoadingGlobal: `${bundle.id}_bundle_jsonpfunction`,
chunkLoading: 'jsonp',
},
optimization: {
noEmitOnErrors: true,
moduleIds: worker.dist ? 'deterministic' : 'natural',
chunkIds: worker.dist ? 'deterministic' : 'natural',
emitOnErrors: false,
splitChunks: {
maxAsyncRequests: 10,
cacheGroups: {
@ -75,9 +80,13 @@ export function getWebpackConfig(
},
},
externals: UiSharedDepsSrc.externals,
externals: {
'node:crypto': 'commonjs crypto',
...UiSharedDepsSrc.externals,
},
plugins: [
new NodeLibsBrowserPlugin(),
new CleanWebpackPlugin(),
new BundleRemotesPlugin(bundle, bundleRemotes),
new PopulateBundleCachePlugin(worker, bundle, parseDllManifest(DLL_MANIFEST)),
@ -86,24 +95,22 @@ export function getWebpackConfig(
context: worker.repoRoot,
manifest: DLL_MANIFEST,
}),
// @ts-ignore something is wrong with the StatoscopeWebpackPlugin type.
...(worker.profileWebpack
...((worker.profileWebpack
? [
new EmitStatsPlugin(bundle),
new StatoscopeWebpackPlugin({
open: false,
saveReportTo: `${bundle.outputDir}/${bundle.id}.statoscope.html`,
}),
new VisualizerPlugin({ filename: `${bundle.id}.visualizer.html` }),
new BundleAnalyzerPlugin({
analyzerMode: 'static',
reportFilename: `${bundle.id}.analyzer.html`,
openAnalyzer: false,
logLevel: 'silent',
}),
new StatoscopeWebpackPlugin({
open: false,
saveReportTo: `${bundle.outputDir}/${bundle.id}.statoscope.html`,
statsOptions: STATS_OPTIONS_DEFAULT_USEFUL_FILTER,
}),
]
: []),
// @ts-ignore something is wrong with the StatoscopeWebpackPlugin type.
: []) as any),
...(bundle.banner ? [new webpack.BannerPlugin({ banner: bundle.banner, raw: true })] : []),
],
@ -199,14 +206,17 @@ export function getWebpackConfig(
{
loader: 'sass-loader',
options: {
additionalData(content: string, loaderContext: webpack.loader.LoaderContext) {
return `@import ${stringifyRequest(
loaderContext,
Path.resolve(
worker.repoRoot,
`src/core/public/styles/core_app/_globals_${theme}.scss`
additionalData(content: string, loaderContext: webpack.LoaderContext<any>) {
const req = JSON.stringify(
loaderContext.utils.contextify(
loaderContext.context || loaderContext.rootContext,
Path.resolve(
worker.repoRoot,
`src/core/public/styles/core_app/_globals_${theme}.scss`
)
)
)};\n${content}`;
);
return `@import ${req};\n${content}`;
},
implementation: require('sass-embedded'),
sassOptions: {
@ -228,13 +238,6 @@ export function getWebpackConfig(
},
],
},
{
test: /\.(woff|woff2|ttf|eot|svg|ico|png|jpg|gif|jpeg)(\?|$)/,
loader: 'url-loader',
options: {
limit: 8192,
},
},
{
test: /\.(js|tsx?)$/,
exclude: /node_modules/,
@ -243,38 +246,47 @@ export function getWebpackConfig(
options: {
babelrc: false,
envName: worker.dist ? 'production' : 'development',
presets: [BABEL_PRESET],
presets: [[BABEL_PRESET, { useTransformRequireDefault: true }]],
},
},
},
{
test: /node_modules\/@?xstate5\/.*\.js$/,
use: {
loader: 'babel-loader',
options: {
babelrc: false,
envName: worker.dist ? 'production' : 'development',
presets: [BABEL_PRESET],
plugins: ['@babel/plugin-transform-logical-assignment-operators'],
},
},
},
{
test: /\.(html|md|txt|tmpl)$/,
use: {
loader: 'raw-loader',
},
},
{
test: /\.peggy$/,
loader: require.resolve('@kbn/peggy-loader'),
},
// emits a separate file and exports the URL. Previously achievable by using file-loader.
{
include: [
require.resolve('@mapbox/mapbox-gl-rtl-text/mapbox-gl-rtl-text.min.js'),
require.resolve('maplibre-gl/dist/maplibre-gl-csp-worker'),
],
type: 'asset/resource',
},
// exports the source code of the asset. Previously achievable by using raw-loader.
{
resourceQuery: /raw/,
type: 'asset/source',
},
{
test: /\.(html|md|txt|tmpl)$/,
type: 'asset/source',
},
// automatically chooses between exporting a data URI and emitting a separate file. Previously achievable by using url-loader with asset size limit.
{
test: /\.(woff|woff2|ttf|eot|svg|ico|png|jpg|gif|jpeg)(\?|$)/,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 8192,
},
},
},
],
},
resolve: {
extensions: ['.js', '.ts', '.tsx', '.json'],
mainFields: ['browser', 'main'],
mainFields: ['browser', 'module', 'main'],
alias: {
core_app_image_assets: Path.resolve(
worker.repoRoot,
@ -290,16 +302,43 @@ export function getWebpackConfig(
// and not for the webpack compilations performance itself
hints: false,
},
ignoreWarnings: [STATS_WARNINGS_FILTER],
};
const nonDistributableConfig: webpack.Configuration = {
mode: 'development',
cache: {
type: 'memory',
cacheUnaffected: true,
},
experiments: {
cacheUnaffected: true,
backCompat: false,
},
optimization: {
sideEffects: false,
removeAvailableModules: false,
},
module: {
// This was default on webpack v4
unsafeCache: true,
},
};
const distributableConfig: webpack.Configuration = {
mode: 'production',
plugins: [
// NOTE: this plugin is needed to mark exports on public and extraPublicDir entry files
// as used otherwise the new webpack v5 aggressive exports analysis will mark them as unused
// and they will be removed. Without this plugin we need to run with usedExports: false which
// affects the bundle sizes by a big margin.
new BundleRemoteUsedExportsPlugin(bundle),
new webpack.DefinePlugin({
'process.env': {
IS_KIBANA_DISTRIBUTABLE: `"true"`,
@ -310,8 +349,6 @@ export function getWebpackConfig(
optimization: {
minimizer: [
new TerserPlugin({
cache: false,
sourceMap: false,
extractComments: false,
parallel: false,
terserOptions: {

View file

@ -28,5 +28,6 @@
"@kbn/dev-cli-runner",
"@kbn/jest-serializers",
"@kbn/repo-packages",
"@kbn/node-libs-browser-webpack-plugin",
]
}

View file

@ -2,6 +2,7 @@ load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
SRCS = glob(
[
"**/*.js",
"**/*.ts",
],
exclude = [

View file

@ -8,10 +8,12 @@
*/
import { getJsSource } from '@kbn/peggy';
import webpack from 'webpack';
// eslint-disable-next-line import/no-default-export
export default function (this: webpack.loader.LoaderContext) {
/**
* @this {import('webpack').LoaderContext<any>}
*/
export default function () {
this.cacheable(true);
const callback = this.async();

View file

@ -1,6 +1,7 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"checkJs": true,
"outDir": "target/types",
"types": [
"jest",
@ -9,11 +10,12 @@
},
"include": [
"**/*.ts",
],
"kbn_references": [
"@kbn/peggy"
"**/*.js"
],
"exclude": [
"target/**/*",
],
"kbn_references": [
"@kbn/peggy",
]
}

View file

@ -40,9 +40,6 @@ it('builds a generated plugin into a viable archive', async () => {
process.execPath,
['scripts/generate_plugin', '-y', '--name', 'fooTestPlugin'],
{
env: {
NODE_OPTIONS: '--openssl-legacy-provider',
},
cwd: REPO_ROOT,
all: true,
}
@ -55,8 +52,7 @@ it('builds a generated plugin into a viable archive', async () => {
};
expect(filterLogs(generateProc.all)).toMatchInlineSnapshot(`
"Kibana is currently running with legacy OpenSSL providers enabled! For details and instructions on how to disable see https://www.elastic.co/guide/en/kibana/8.16/production.html#openssl-legacy-provider
succ 🎉
" succ 🎉
Your plugin has been created in plugins/foo_test_plugin
"
@ -66,17 +62,13 @@ it('builds a generated plugin into a viable archive', async () => {
process.execPath,
['../../scripts/plugin_helpers', 'build', '--kibana-version', '7.5.0'],
{
env: {
NODE_OPTIONS: '--openssl-legacy-provider',
},
cwd: PLUGIN_DIR,
all: true,
}
);
expect(filterLogs(buildProc.all)).toMatchInlineSnapshot(`
"Kibana is currently running with legacy OpenSSL providers enabled! For details and instructions on how to disable see https://www.elastic.co/guide/en/kibana/8.16/production.html#openssl-legacy-provider
info deleting the build and target directories
" info deleting the build and target directories
info run bazel and build required artifacts for the optimizer
succ bazel run successfully and artifacts were created
info running @kbn/optimizer
@ -106,8 +98,8 @@ it('builds a generated plugin into a viable archive', async () => {
"kibana/fooTestPlugin/server/plugin.js",
"kibana/fooTestPlugin/server/routes/index.js",
"kibana/fooTestPlugin/server/types.js",
"kibana/fooTestPlugin/target/public/fooTestPlugin.chunk.1.js",
"kibana/fooTestPlugin/target/public/fooTestPlugin.chunk.1.js.br",
"kibana/fooTestPlugin/target/public/fooTestPlugin.chunk.637.js",
"kibana/fooTestPlugin/target/public/fooTestPlugin.chunk.637.js.br",
"kibana/fooTestPlugin/target/public/fooTestPlugin.plugin.js",
"kibana/fooTestPlugin/target/public/fooTestPlugin.plugin.js.br",
"kibana/fooTestPlugin/translations/ja-JP.json",

View file

@ -64,7 +64,7 @@ export async function optimize({
const proc = fork(require.resolve('./optimize_worker'), {
cwd: REPO_ROOT,
execArgv: ['--require=@kbn/babel-register/install', '--openssl-legacy-provider'],
execArgv: ['--require=@kbn/babel-register/install'],
stdio: ['ignore', 'pipe', 'pipe', 'ipc'],
});

View file

@ -42,7 +42,7 @@ process.on('message', (msg: any) => {
return;
}
if (stats.hasErrors()) {
if (stats?.hasErrors()) {
send.call(process, {
success: false,
error: `Failed to compile with webpack:\n${stats.toString()}`,
@ -52,7 +52,7 @@ process.on('message', (msg: any) => {
send.call(process, {
success: true,
warnings: stats.hasWarnings() ? stats.toString() : '',
warnings: stats?.hasWarnings() ? stats.toString() : '',
});
}
);

View file

@ -13,7 +13,7 @@ This package exposes a class which can be used to efficiently classify all of th
- `browser package`: plugin code in the root `public/` directory (and a few others in specific plugins), eventually this will include packages of type `browser-plugin` or `browser-shared`
- `common packages`: includes any existing package, plugin code in root `common/` directories, (and a few others in specific plugins), Eventually this will include `common-shared` packages
- `tests or mocks`: code that is loaded by jest/storybook, and mocks/helpers intended for use by that code. These files usually live along side package code but will have a separate dependency tree and are pieces of code which should never end up in the product.
- `static`: static files, currently any .json file or things loaded via `raw-loader` in browser code
- `static`: static files, currently any .json file or things loaded via `?raw` or `?asUrl` in browser code
- `tooling`: scripts, config files for tools like eslint, webpack, etc.
- `non-package`: code that lives outside of packages/plugins or doesn't fit into other more specific categories. Once the package project is complete this category should be limited to just `@kbn/pm`

View file

@ -12,26 +12,17 @@
// This plugin suppresses the irritating TS-related warnings in Storybook HMR.
import { Compiler, Stats } from 'webpack';
// @ts-expect-error
import ModuleDependencyWarning from 'webpack/lib/ModuleDependencyWarning';
export class IgnoreNotFoundExportPlugin {
apply(compiler: Compiler) {
const messageRegExp = /export '.*'( \(reexported as '.*'\))? was not found in/;
const doneHook = (stats: Stats) =>
(stats.compilation.warnings = stats.compilation.warnings.filter(
(warn: any) =>
// Unfortunately webpack is not exporting ModuleDependencyWarning type, so I'm using constructor.name instead
warn.constructor.name === 'ModuleDependencyWarning' && !messageRegExp.test(warn.message)
));
function doneHook(stats: Stats) {
stats.compilation.warnings = stats.compilation.warnings.filter(function (warn) {
if (warn instanceof ModuleDependencyWarning && messageRegExp.test(warn.message)) {
return false;
}
return true;
});
}
if (compiler.hooks) {
compiler.hooks.done.tap('IgnoreNotFoundExportPlugin', doneHook);
} else {
compiler.plugin('done', doneHook);
}
compiler.hooks.done.tap('IgnoreNotFoundExportPlugin', doneHook);
}
}

View file

@ -11,7 +11,7 @@ import * as path from 'path';
import fs from 'fs';
import type { StorybookConfig } from '@storybook/core-common';
import webpack, { Configuration } from 'webpack';
import webpackMerge from 'webpack-merge';
import { merge as webpackMerge } from 'webpack-merge';
import { REPO_ROOT } from './constants';
import { default as WebpackConfig } from '../webpack.config';
@ -24,11 +24,18 @@ const toPath = (_path: string) => path.join(REPO_ROOT, _path);
// This ignore pattern excludes all of node_modules EXCEPT for `@kbn`. This allows for
// changes to packages to cause a refresh in Storybook.
const IGNORE_PATTERN =
/[/\\]node_modules[/\\](?!@kbn[/\\][^/\\]+[/\\](?!node_modules)([^/\\]+))([^/\\]+[/\\][^/\\]+)/;
const IGNORE_GLOBS = [
'**/node_modules/**',
'!**/node_modules/@kbn/**',
'!**/node_modules/@kbn/*/**',
'!**/node_modules/@kbn/*/!(node_modules)/**',
];
export const defaultConfig: StorybookConfig = {
addons: ['@kbn/storybook/preset', '@storybook/addon-a11y', '@storybook/addon-essentials'],
core: {
builder: 'webpack5',
},
stories: ['../**/*.stories.tsx', '../**/*.stories.mdx'],
typescript: {
reactDocgen: false,
@ -99,11 +106,17 @@ export const defaultConfig: StorybookConfig = {
})
);
config.node = { fs: 'empty' };
config.resolve = {
...config.resolve,
fallback: {
...config?.resolve?.fallback,
fs: false,
},
};
config.watch = true;
config.watchOptions = {
...config.watchOptions,
ignored: [IGNORE_PATTERN],
ignored: IGNORE_GLOBS,
};
// Remove when @storybook has moved to @emotion v11

View file

@ -7,25 +7,18 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
/* eslint-disable import/no-default-export */
import { externals } from '@kbn/ui-shared-deps-src';
import { stringifyRequest } from 'loader-utils';
import { resolve } from 'path';
import webpack, { Configuration, Stats } from 'webpack';
import webpackMerge from 'webpack-merge';
import webpack, { Configuration } from 'webpack';
import { merge as webpackMerge } from 'webpack-merge';
import { NodeLibsBrowserPlugin } from '@kbn/node-libs-browser-webpack-plugin';
import { REPO_ROOT } from './lib/constants';
import { IgnoreNotFoundExportPlugin } from './ignore_not_found_export_plugin';
import 'webpack-dev-server'; // Extends webpack configuration with `devServer` property
type Preset = string | [string, Record<string, unknown>] | Record<string, unknown>;
const stats = {
...Stats.presetToOptions('minimal'),
colors: true,
errorDetails: true,
errors: true,
moduleTrace: true,
};
function isProgressPlugin(plugin: any) {
return 'handler' in plugin && plugin.showActiveModules && plugin.showModules;
}
@ -35,7 +28,10 @@ function isHtmlPlugin(plugin: any): plugin is { options: { template: string } }
}
interface BabelLoaderRule extends webpack.RuleSetRule {
use: webpack.RuleSetLoader[];
use: Array<{
loader: 'babel-loader';
[key: string]: unknown;
}>;
}
function isBabelLoaderRule(rule: webpack.RuleSetRule): rule is BabelLoaderRule {
@ -44,7 +40,7 @@ function isBabelLoaderRule(rule: webpack.RuleSetRule): rule is BabelLoaderRule {
Array.isArray(rule.use) &&
rule.use.some(
(l) =>
typeof l === 'object' && typeof l.loader === 'string' && l.loader.includes('babel-loader')
typeof l === 'object' && typeof l?.loader === 'string' && l?.loader.includes('babel-loader')
)
);
}
@ -69,12 +65,14 @@ function isDesiredPreset(preset: Preset) {
}
// Extend the Storybook Webpack config with some customizations
/* eslint-disable import/no-default-export */
/**
* @returns {import('webpack').Configuration}
*/
export default ({ config: storybookConfig }: { config: Configuration }) => {
const config: Configuration = {
devServer: {
devMiddleware: {
stats,
stats: 'errors-only',
},
},
externals,
@ -91,9 +89,7 @@ export default ({ config: storybookConfig }: { config: Configuration }) => {
},
{
test: /\.(html|md|txt|tmpl)$/,
use: {
loader: 'raw-loader',
},
type: 'asset/source',
},
{
test: /\.peggy$/,
@ -119,10 +115,13 @@ export default ({ config: storybookConfig }: { config: Configuration }) => {
loader: 'sass-loader',
options: {
additionalData(content: string, loaderContext: any) {
return `@import ${stringifyRequest(
loaderContext,
resolve(REPO_ROOT, 'src/core/public/styles/core_app/_globals_v8light.scss')
)};\n${content}`;
const req = JSON.stringify(
loaderContext.utils.contextify(
loaderContext.context || loaderContext.rootContext,
resolve(REPO_ROOT, 'src/core/public/styles/core_app/_globals_v8light.scss')
)
);
return `@import ${req};\n${content}`;
},
implementation: require('sass-embedded'),
sassOptions: {
@ -133,20 +132,9 @@ export default ({ config: storybookConfig }: { config: Configuration }) => {
},
],
},
{
test: /node_modules\/@?xstate5\/.*\.js$/,
use: {
loader: 'babel-loader',
options: {
babelrc: false,
presets: [require.resolve('@kbn/babel-preset/webpack_preset')],
plugins: ['@babel/plugin-transform-logical-assignment-operators'],
},
},
},
],
},
plugins: [new IgnoreNotFoundExportPlugin()],
plugins: [new NodeLibsBrowserPlugin(), new IgnoreNotFoundExportPlugin()],
resolve: {
extensions: ['.js', '.mjs', '.ts', '.tsx', '.json', '.mdx'],
mainFields: ['browser', 'main'],
@ -156,16 +144,16 @@ export default ({ config: storybookConfig }: { config: Configuration }) => {
vega: resolve(REPO_ROOT, 'node_modules/vega/build-es5/vega.js'),
},
},
stats,
stats: 'errors-only',
};
// Override storybookConfig mainFields instead of merging with config
delete storybookConfig.resolve?.mainFields;
const updatedModuleRules = [];
const updatedModuleRules: webpack.RuleSetRule[] = [];
// clone and modify the module.rules config provided by storybook so that the default babel plugins run after the typescript preset
for (const originalRule of storybookConfig.module?.rules ?? []) {
const rule = { ...originalRule };
const rule = typeof originalRule !== 'string' ? { ...originalRule } : {};
updatedModuleRules.push(rule);
if (isBabelLoaderRule(rule)) {
@ -218,7 +206,7 @@ export default ({ config: storybookConfig }: { config: Configuration }) => {
filteredStorybookPlugins.push(plugin);
}
return webpackMerge(
return webpackMerge<object>(
{
...storybookConfig,
plugins: filteredStorybookPlugins,

View file

@ -22,6 +22,7 @@
"@kbn/core-i18n-browser",
"@kbn/react-kibana-context-root",
"@kbn/core-analytics-browser",
"@kbn/node-libs-browser-webpack-plugin",
],
"exclude": [
"target/**/*",

View file

@ -30,6 +30,18 @@ const STATIC_FILE_EXT =
.split('|')
.map((e) => `.${e}`);
/**
* @param {string} str
* @returns
*/
function parseRequestOrExtSuffix(str) {
const rawSuffix = '?raw';
if (str.endsWith(rawSuffix)) {
return str.slice(0, -rawSuffix.length);
}
return str;
}
/**
* @param {string} request
* @param {import('resolve').SyncOpts} options
@ -57,25 +69,27 @@ module.exports = (request, options) => {
const reqExt = Path.extname(request);
if (reqExt) {
const reqBasename = Path.basename(request, reqExt);
if ((reqExt === '.css' || reqExt === '.scss') && reqBasename.endsWith('.module')) {
const pRequest = parseRequestOrExtSuffix(request);
const pReqExt = parseRequestOrExtSuffix(reqExt);
const reqBasename = Path.basename(pRequest, pReqExt);
if ((pReqExt === '.css' || pReqExt === '.scss') && reqBasename.endsWith('.module')) {
return CSS_MODULE_MOCK;
}
if (reqExt === '.css' || reqExt === '.less' || reqExt === '.scss') {
if (pReqExt === '.css' || pReqExt === '.less' || pReqExt === '.scss') {
return STYLE_MOCK;
}
if (STATIC_FILE_EXT.includes(reqExt)) {
if (STATIC_FILE_EXT.includes(pReqExt)) {
return FILE_MOCK;
}
if (reqExt === '.worker' && reqBasename.endsWith('.editor')) {
if (pReqExt === '.worker' && reqBasename.endsWith('.editor')) {
return WORKER_MOCK;
}
}
if (request.startsWith('file-loader!') || request.startsWith('!!file-loader!')) {
if (request.endsWith('?asUrl')) {
return FILE_MOCK;
}

View file

@ -26,9 +26,9 @@ SRCS = glob(
RUNTIME_DEPS = [
"@npm//babel-loader",
"@npm//@babel/plugin-proposal-optional-chaining",
"@npm//loader-utils",
"@npm//val-loader",
"//packages/kbn-repo-info",
"//packages/kbn-node-libs-browser-webpack-plugin",
# deps in the dll need to be included in the sandbox for consumers
# of this DLL (ui-shared-deps-src) because webpack won't actually
# use the DLL version of a package until it has resolved to the same
@ -53,6 +53,7 @@ RUNTIME_DEPS = [
"@npm//jquery",
"@npm//lodash",
"@npm//moment-timezone",
"@npm//node-libs-browser",
"@npm//react-dom",
"@npm//react-router-dom",
"@npm//react-router-dom-v5-compat",
@ -94,11 +95,9 @@ webpack_cli(
env = select({
"//:dist": {
"NODE_ENV": "production",
"NODE_OPTIONS": "--openssl-legacy-provider",
},
"//conditions:default": {
"NODE_ENV": "development",
"NODE_OPTIONS": "--openssl-legacy-provider",
},
})
)

View file

@ -7,19 +7,21 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
// eslint-disable-next-line import/no-extraneous-dependencies
const { stringifyRequest } = require('loader-utils');
const VAL_LOADER = require.resolve('val-loader');
const MODULE_CREATOR = require.resolve('./public_path_module_creator');
/**
* @this {any} this
* @this {import('webpack').LoaderContext<any>}
* @param {string} source
*/
module.exports = function (source) {
const options = this.query;
const valOpts = new URLSearchParams({ key: options.key }).toString();
const req = `${VAL_LOADER}?${valOpts}!${MODULE_CREATOR}`;
return `require(${stringifyRequest(this, req)});${source}`;
const req = JSON.stringify(
this.utils.contextify(
this.context || this.rootContext,
`${VAL_LOADER}?${valOpts}!${MODULE_CREATOR}`
)
);
return `require(${req});${source}`;
};

View file

@ -9,6 +9,7 @@
const Path = require('path');
const webpack = require('webpack');
const { NodeLibsBrowserPlugin } = require('@kbn/node-libs-browser-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
@ -19,14 +20,11 @@ const WEBPACK_SRC = require.resolve('webpack');
const REPO_ROOT = Path.resolve(__dirname, '..', '..');
/** @returns {import('webpack').Configuration} */
module.exports = (_, argv) => {
const outputPath = argv.outputPath ? Path.resolve(argv.outputPath) : UiSharedDepsNpm.distDir;
return {
node: {
child_process: 'empty',
fs: 'empty',
},
externals: {
module: 'module',
},
@ -63,8 +61,6 @@ module.exports = (_, argv) => {
'@elastic/charts',
'@elastic/eui',
'@elastic/eui/optimize/es/components/provider/nested',
'@elastic/eui/optimize/es/services',
'@elastic/eui/optimize/es/services/format',
'@elastic/eui/dist/eui_theme_light.json',
'@elastic/eui/dist/eui_theme_dark.json',
'@elastic/numeral',
@ -103,6 +99,7 @@ module.exports = (_, argv) => {
},
context: __dirname,
devtool: 'cheap-source-map',
target: 'web',
output: {
path: outputPath,
filename: '[name].dll.js',
@ -110,7 +107,6 @@ module.exports = (_, argv) => {
devtoolModuleFilenameTemplate: (info) =>
`kbn-ui-shared-deps-npm/${Path.relative(REPO_ROOT, info.absoluteResourcePath)}`,
library: '__kbnSharedDeps_npm__',
futureEmitAssets: true,
},
module: {
@ -144,11 +140,15 @@ module.exports = (_, argv) => {
'scheduler/tracing': 'scheduler/tracing-profiling',
},
extensions: ['.js', '.ts'],
mainFields: ['browser', 'module', 'main'],
conditionNames: ['browser', 'module', 'import', 'require', 'default'],
},
optimization: {
moduleIds: process.env.NODE_ENV === 'production' ? 'deterministic' : 'natural',
chunkIds: process.env.NODE_ENV === 'production' ? 'deterministic' : 'natural',
minimize: false,
noEmitOnErrors: true,
emitOnErrors: false,
},
performance: {
@ -159,6 +159,7 @@ module.exports = (_, argv) => {
},
plugins: [
new NodeLibsBrowserPlugin(),
new CleanWebpackPlugin({
protectWebpackAssets: false,
cleanAfterEveryBuildPatterns: [
@ -171,6 +172,7 @@ module.exports = (_, argv) => {
}),
new webpack.DllPlugin({
context: REPO_ROOT,
entryOnly: false,
path: Path.resolve(outputPath, '[name]-manifest.json'),
name: '__kbnSharedDeps_npm__',
}),

View file

@ -15,7 +15,6 @@ webpack_cli(
"@npm//moment",
"@npm//babel-loader",
"@npm//css-loader",
"@npm//url-loader",
"@npm//@babel/plugin-transform-numeric-separator",
"//packages/kbn-ui-shared-deps-npm",
"//packages/kbn-babel-register",
@ -51,11 +50,9 @@ webpack_cli(
env = select({
"//:dist": {
"NODE_ENV": "production",
"NODE_OPTIONS": "--openssl-legacy-provider",
},
"//conditions:default": {
"NODE_ENV": "development",
"NODE_OPTIONS": "--openssl-legacy-provider",
},
}),
visibility = ["//visibility:public"],

View file

@ -75,8 +75,6 @@ const externals = {
'@elastic/eui': '__kbnSharedDeps__.ElasticEui',
'@elastic/eui/lib/components/provider/nested':
'__kbnSharedDeps__.ElasticEuiLibComponentsUseIsNestedEuiProvider',
'@elastic/eui/lib/services': '__kbnSharedDeps__.ElasticEuiLibServices',
'@elastic/eui/lib/services/format': '__kbnSharedDeps__.ElasticEuiLibServicesFormat',
// transient dep of eui
'@hello-pangea/dnd': '__kbnSharedDeps__.HelloPangeaDnd',

View file

@ -42,8 +42,6 @@ export const ElasticNumeral = require('@elastic/numeral');
export const ElasticCharts = require('@elastic/charts');
export const ElasticEui = require('@elastic/eui');
export const ElasticEuiLibComponentsUseIsNestedEuiProvider = require('@elastic/eui/optimize/es/components/provider/nested');
export const ElasticEuiLibServices = require('@elastic/eui/optimize/es/services');
export const ElasticEuiLibServicesFormat = require('@elastic/eui/optimize/es/services/format');
export const KbnDatemath = require('@kbn/datemath');
export const HelloPangeaDnd = require('@hello-pangea/dnd/dist/dnd');
export const ReduxjsToolkit = require('@reduxjs/toolkit');

View file

@ -13,6 +13,7 @@ require('@kbn/babel-register').install();
const Path = require('path');
const webpack = require('webpack');
const { NodeLibsBrowserPlugin } = require('@kbn/node-libs-browser-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const UiSharedDepsNpm = require('@kbn/ui-shared-deps-npm');
@ -22,11 +23,8 @@ const MOMENT_SRC = require.resolve('moment/min/moment-with-locales.js');
const REPO_ROOT = Path.resolve(__dirname, '..', '..');
/** @returns {import('webpack').Configuration} */
module.exports = {
node: {
child_process: 'empty',
fs: 'empty',
},
externals: {
module: 'module',
},
@ -36,6 +34,7 @@ module.exports = {
},
context: __dirname,
devtool: 'cheap-source-map',
target: 'web',
output: {
path: UiSharedDepsSrcDistDir,
filename: '[name].js',
@ -44,7 +43,6 @@ module.exports = {
devtoolModuleFilenameTemplate: (info) =>
`kbn-ui-shared-deps-src/${Path.relative(REPO_ROOT, info.absoluteResourcePath)}`,
library: '__kbnSharedDeps__',
futureEmitAssets: true,
},
module: {
@ -68,13 +66,6 @@ module.exports = {
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
{
test: /\.(ttf)(\?|$)/,
loader: 'url-loader',
options: {
limit: 8192,
},
},
{
test: /\.(js|tsx?)$/,
exclude: /[\/\\]node_modules[\/\\](?!@kbn)([^\/\\]+)[\/\\]/,
@ -102,13 +93,28 @@ module.exports = {
},
},
},
// automatically chooses between exporting a data URI and emitting a separate file. Previously achievable by using url-loader with asset size limit.
{
test: /\.(ttf)(\?|$)/,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 8192,
},
},
},
],
},
resolve: {
extensions: ['.js', '.ts', '.tsx'],
mainFields: ['browser', 'module', 'main'],
conditionNames: ['browser', 'module', 'import', 'require', 'default'],
alias: {
'@elastic/eui$': '@elastic/eui/optimize/es',
'@elastic/eui/lib/components/provider/nested$':
'@elastic/eui/optimize/es/components/provider/nested',
'@elastic/eui/lib/services/theme/warning$': '@elastic/eui/optimize/es/services/theme/warning',
moment: MOMENT_SRC,
// NOTE: Used to include react profiling on bundles
// https://gist.github.com/bvaughn/25e6233aeb1b4f0cdb8d8366e54a3977#webpack-4
@ -118,8 +124,10 @@ module.exports = {
},
optimization: {
moduleIds: process.env.NODE_ENV === 'production' ? 'deterministic' : 'natural',
chunkIds: process.env.NODE_ENV === 'production' ? 'deterministic' : 'natural',
minimize: false,
noEmitOnErrors: true,
emitOnErrors: false,
},
performance: {
@ -130,6 +138,7 @@ module.exports = {
},
plugins: [
new NodeLibsBrowserPlugin(),
new MiniCssExtractPlugin({
filename: '[name].css',
}),

View file

@ -20,6 +20,15 @@
"matchDepPatterns": [".*"],
"enabled": false
},
{
"groupName": "webpack",
"matchDepNames": ["webpack", "@types/webpack", "webpack-cli", "webpack-dev-server", "webpack-merge"],
"reviewers": ["team:kibana-operations"],
"matchBaseBranches": ["main"],
"labels": ["Team:Operations", "backport:all-open", "release_note:skip", "ci:build-webpack-bundle-analyzer"],
"minimumReleaseAge": "60 days",
"enabled": true
},
{
"groupName": "devcontainer",
"reviewers": ["team:kibana-operations"],

View file

@ -41,6 +41,7 @@ run(
log.verbose('Loading Storybook:', configDir);
// TODO: once storybook is upgraded into a newer version, --no-deprecation flag could be removed when invoking it through the package.json script
runStorybookCli({ configDir, name: alias });
},
{

View file

@ -8,7 +8,7 @@
*/
import { defaultConfig } from '@kbn/storybook';
import webpackMerge from 'webpack-merge';
import { merge as webpackMerge } from 'webpack-merge';
import { resolve } from 'path';
const mockConfig = {

View file

@ -8,7 +8,7 @@
*/
import { defaultConfig } from '@kbn/storybook';
import webpackMerge from 'webpack-merge';
import { merge as webpackMerge } from 'webpack-merge';
import { resolve } from 'path';
const mockConfig = {

View file

@ -8,7 +8,7 @@
*/
import { defaultConfig } from '@kbn/storybook';
import webpackMerge from 'webpack-merge';
import { merge as webpackMerge } from 'webpack-merge';
import { resolve } from 'path';
const mockConfig = {

View file

@ -1,4 +1,4 @@
@import 'src/core/public/mixins';
@import '../../../../../src/core/public/mixins';
.dshUnsavedListingItem {
margin-top: $euiSizeM;

View file

@ -7,9 +7,9 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
import { defaultConfig, StorybookConfig } from '@kbn/storybook';
import { defaultConfig } from '@kbn/storybook';
export const discoverStorybookConfig: StorybookConfig = {
module.exports = {
...defaultConfig,
stories: ['../**/*.stories.tsx'],
};

View file

@ -8,7 +8,7 @@
*/
import { defaultConfig } from '@kbn/storybook';
import webpackMerge from 'webpack-merge';
import { merge as webpackMerge } from 'webpack-merge';
import { resolve } from 'path';
const mockConfig = {

View file

@ -8,6 +8,6 @@
*/
// @ts-ignore
import defaultSpec from '!!raw-loader!./default.spec.hjson';
import defaultSpec from './default.spec.hjson?raw';
export const getDefaultSpec = () => defaultSpec;

View file

@ -1280,6 +1280,8 @@
"@kbn/newsfeed-test-plugin/*": ["test/common/plugins/newsfeed/*"],
"@kbn/no-data-page-plugin": ["src/plugins/no_data_page"],
"@kbn/no-data-page-plugin/*": ["src/plugins/no_data_page/*"],
"@kbn/node-libs-browser-webpack-plugin": ["packages/kbn-node-libs-browser-webpack-plugin"],
"@kbn/node-libs-browser-webpack-plugin/*": ["packages/kbn-node-libs-browser-webpack-plugin/*"],
"@kbn/notifications-plugin": ["x-pack/plugins/notifications"],
"@kbn/notifications-plugin/*": ["x-pack/plugins/notifications/*"],
"@kbn/object-versioning": ["packages/kbn-object-versioning"],

View file

@ -6,7 +6,6 @@
*/
import { defaultConfig } from '@kbn/storybook';
import { Configuration } from 'webpack';
module.exports = {
...defaultConfig,
@ -14,31 +13,4 @@ module.exports = {
reactOptions: {
strictMode: true,
},
webpack: (config: Configuration) => {
config.module?.rules.push({
test: /\.js$/,
include: /node_modules[\\\/]@dagrejs/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
plugins: ['@babel/plugin-proposal-class-properties'],
},
},
});
config.module?.rules.push({
test: /node_modules[\/\\]@?xyflow[\/\\].*.js$/,
loaders: 'babel-loader',
options: {
presets: [['@babel/preset-env', { modules: false }], '@babel/preset-react'],
plugins: [
'@babel/plugin-proposal-optional-chaining',
'@babel/plugin-proposal-nullish-coalescing-operator',
'@babel/plugin-transform-logical-assignment-operators',
],
},
});
return config;
},
};

View file

@ -55,7 +55,6 @@ run(
execa.sync(
process.execPath,
[
'--openssl-legacy-provider',
require.resolve('webpack-dev-server/bin/webpack-dev-server'),
'--config',
webpackConfig,
@ -89,7 +88,6 @@ run(
execa.sync(
process.execPath,
[
'--openssl-legacy-provider',
require.resolve('webpack/bin/webpack'),
'--config',
webpackConfig,

View file

@ -18,9 +18,10 @@
}
:global .kbnCanvas :local .slideContainer {
@include euiScrollBar;
display: flex;
overflow-x: auto;
overflow-y: hidden;
width: 100%;
@include euiScrollBar;
}

View file

@ -9,7 +9,6 @@ require('@kbn/babel-register').install();
const path = require('path');
const webpack = require('webpack');
const { stringifyRequest } = require('loader-utils');
const { CiStatsPlugin } = require('./webpack/ci_stats_plugin');
const {
@ -21,11 +20,13 @@ const {
const isProd = process.env.NODE_ENV === 'production';
/** @type {import('webpack').Configuration} */
module.exports = {
context: KIBANA_ROOT,
entry: {
[SHAREABLE_RUNTIME_NAME]: require.resolve('./index.ts'),
},
target: 'web',
mode: isProd ? 'production' : 'development',
output: {
path: SHAREABLE_RUNTIME_OUTPUT,
@ -35,18 +36,28 @@ module.exports = {
resolve: {
alias: {
core_app_image_assets: path.resolve(KIBANA_ROOT, 'src/core/public/styles/core_app/images'),
[require.resolve('@elastic/eui/es/components/drag_and_drop')]: false,
},
extensions: ['.js', '.json', '.ts', '.tsx', '.scss'],
mainFields: ['browser', 'main'],
mainFields: ['browser', 'module', 'main'],
fallback: {
fs: false,
child_process: false,
},
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loaders: 'babel-loader',
loader: 'babel-loader',
options: {
presets: [require.resolve('@kbn/babel-preset/webpack_preset')],
presets: [
[
require.resolve('@kbn/babel-preset/webpack_preset'),
{ useTransformRequireDefault: true },
],
],
},
},
{
@ -105,15 +116,15 @@ module.exports = {
},
{
test: /\.module\.s(a|c)ss$/,
loader: [
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[name]__[local]___[hash:base64:5]',
exportLocalsConvention: 'camelCase',
},
localsConvention: 'camelCase',
sourceMap: !isProd,
},
},
@ -160,10 +171,16 @@ module.exports = {
loader: 'sass-loader',
options: {
additionalData(content, loaderContext) {
return `@import ${stringifyRequest(
loaderContext,
path.resolve(KIBANA_ROOT, 'src/core/public/styles/core_app/_globals_v8light.scss')
)};\n${content}`;
const req = JSON.stringify(
loaderContext.utils.contextify(
loaderContext.context || loaderContext.rootContext,
path.resolve(
KIBANA_ROOT,
'src/core/public/styles/core_app/_globals_v8light.scss'
)
)
);
return `@import ${req};\n${content}`;
},
implementation: require('sass-embedded'),
sassOptions: {
@ -176,11 +193,23 @@ module.exports = {
},
{
test: require.resolve('jquery'),
loader: 'expose-loader?jQuery!expose-loader?$',
use: [
{
loader: 'expose-loader',
options: {
exposes: ['jQuery', '$'],
},
},
],
},
{
test: /\.(woff|woff2|ttf|eot|svg|ico|png|jpg|gif|jpeg)(\?|$)/,
loader: 'url-loader',
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 8192,
},
},
sideEffects: false,
},
{
@ -188,23 +217,12 @@ module.exports = {
loader: 'html-loader',
exclude: /node_modules/,
},
{
test: [
require.resolve('@elastic/eui/es/components/drag_and_drop'),
require.resolve('highlight.js'),
],
use: require.resolve('null-loader'),
},
{
test: /\.peggy$/,
use: require.resolve('@kbn/peggy-loader'),
},
],
},
node: {
fs: 'empty',
child_process: 'empty',
},
plugins: [
isProd ? new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 }) : [],
new CiStatsPlugin({

View file

@ -67,7 +67,7 @@ export class CiStatsPlugin {
throw new Error(`Unable to find bundle entry named [${entryName}]`);
}
const moduleCount = compilation.modules.reduce((acc, module) => {
const moduleCount = Array.from(compilation.modules).reduce((acc, module) => {
if (isNormalModule(module)) {
return acc + 1;
}

View file

@ -8,15 +8,16 @@
import { resolve } from 'path';
import { defaultConfig, mergeWebpackFinal } from '@kbn/storybook';
import type { StorybookConfig } from '@kbn/storybook';
import { Configuration } from 'webpack';
import { KIBANA_ROOT } from './constants';
export const canvasWebpack = {
export const canvasWebpack: Configuration = {
module: {
rules: [
// Enable CSS Modules in Storybook (Shareable Runtime)
{
test: /\.module\.s(a|c)ss$/,
loader: [
use: [
'style-loader',
{
loader: 'css-loader',
@ -39,23 +40,21 @@ export const canvasWebpack = {
loader: 'sass-loader',
options: {
implementation: require('sass-embedded'),
sassOptions: {
quietDeps: true,
},
},
},
],
},
// Exclude large-dependency, troublesome or irrelevant modules.
{
test: [
resolve(KIBANA_ROOT, 'x-pack/plugins/canvas/public/components/embeddable_flyout'),
resolve(KIBANA_ROOT, 'x-pack/plugins/reporting/public'),
],
use: 'null-loader',
},
],
},
resolve: {
alias: {
'src/plugins': resolve(KIBANA_ROOT, 'src/plugins'),
// Exclude large-dependency, troublesome or irrelevant modules.
[resolve(KIBANA_ROOT, 'x-pack/plugins/canvas/public/components/embeddable_flyout')]: false,
[resolve(KIBANA_ROOT, 'x-pack/plugins/reporting/public')]: false,
},
},
};

View file

@ -5,11 +5,11 @@
"private": true,
"license": "Elastic License 2.0",
"scripts": {
"cypress_space_awareness": "NODE_OPTIONS=--openssl-legacy-provider node ../security_solution/scripts/start_cypress_parallel --config-file ../fleet/cypress.config.space_awareness.ts --ftr-config-file ../../../x-pack/test/fleet_cypress/cli_config.space_awareness",
"cypress_space_awareness": "node ../security_solution/scripts/start_cypress_parallel --config-file ../fleet/cypress.config.space_awareness.ts --ftr-config-file ../../../x-pack/test/fleet_cypress/cli_config.space_awareness",
"cypress_space_awareness:open": "yarn cypress_space_awareness open",
"cypress_space_awareness:run": "yarn cypress_space_awareness run",
"cypress_space_awareness:run:reporter": "yarn cypress_space_awareness run --reporter ../../../node_modules/cypress-multi-reporters --reporter-options configFile=../fleet/cypress/reporter_config.json",
"cypress": "NODE_OPTIONS=--openssl-legacy-provider node ../security_solution/scripts/start_cypress_parallel --config-file ../fleet/cypress.config.ts --ftr-config-file ../../../x-pack/test/fleet_cypress/cli_config",
"cypress": "node ../security_solution/scripts/start_cypress_parallel --config-file ../fleet/cypress.config.ts --ftr-config-file ../../../x-pack/test/fleet_cypress/cli_config",
"cypress:open": "yarn cypress open",
"cypress:run": "yarn cypress run",
"cypress:run:reporter": "yarn cypress run --reporter ../../../node_modules/cypress-multi-reporters --reporter-options configFile=../fleet/cypress/reporter_config.json",

View file

@ -8,7 +8,7 @@
import { EuiPageTemplate } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import React from 'react';
import { css } from '@emotion/react/dist/emotion-react.cjs';
import { css } from '@emotion/react';
export const EmptyList = ({ addDatabaseButton }: { addDatabaseButton: JSX.Element }) => {
return (

View file

@ -73,7 +73,6 @@ function runTests() {
env: {
...process.env,
CYPRESS_CLI_ARGS: JSON.stringify(cypressCliArgs),
NODE_OPTIONS: '--openssl-legacy-provider',
},
encoding: 'utf8',
stdio: 'inherit',

View file

@ -80,7 +80,6 @@ function runTests() {
env: {
...process.env,
CYPRESS_CLI_ARGS: JSON.stringify(cypressCliArgs),
NODE_OPTIONS: '--openssl-legacy-provider',
},
encoding: 'utf8',
stdio: 'inherit',

View file

@ -80,7 +80,6 @@ function runTests() {
env: {
...process.env,
CYPRESS_CLI_ARGS: JSON.stringify(cypressCliArgs),
NODE_OPTIONS: '--openssl-legacy-provider',
},
encoding: 'utf8',
stdio: 'inherit',

View file

@ -7,13 +7,13 @@
"scripts": {
"cypress:burn": "yarn cypress:run --env burn=2 --headed",
"cypress:changed-specs-only": "yarn cypress:run --changed-specs-only --env burn=2",
"cypress": "NODE_OPTIONS=--openssl-legacy-provider node ../security_solution/scripts/start_cypress_parallel --config-file ../osquery/cypress/cypress.config.ts --ftr-config-file ../../../x-pack/test/osquery_cypress/cli_config",
"cypress": "node ../security_solution/scripts/start_cypress_parallel --config-file ../osquery/cypress/cypress.config.ts --ftr-config-file ../../../x-pack/test/osquery_cypress/cli_config",
"cypress:open": "yarn cypress open",
"cypress:run": "yarn cypress run",
"cypress:serverless": "NODE_OPTIONS=--openssl-legacy-provider node ../security_solution/scripts/start_cypress_parallel --config-file ../osquery/cypress/serverless_cypress.config.ts --ftr-config-file ../../../x-pack/test/osquery_cypress/serverless_cli_config",
"cypress:serverless": "node ../security_solution/scripts/start_cypress_parallel --config-file ../osquery/cypress/serverless_cypress.config.ts --ftr-config-file ../../../x-pack/test/osquery_cypress/serverless_cli_config",
"cypress:serverless:open": "yarn cypress:serverless open",
"cypress:serverless:run": "yarn cypress:serverless run",
"cypress:qa:serverless": "NODE_OPTIONS=--openssl-legacy-provider node ../security_solution/scripts/start_cypress_parallel_serverless --config-file ../osquery/cypress/serverless_cypress_qa.config.ts --onBeforeHook ../../test/osquery_cypress/runner_qa.ts",
"cypress:qa:serverless": "node ../security_solution/scripts/start_cypress_parallel_serverless --config-file ../osquery/cypress/serverless_cypress_qa.config.ts --onBeforeHook ../../test/osquery_cypress/runner_qa.ts",
"cypress:qa:serverless:run": "yarn cypress:qa:serverless run",
"nyc": "../../../node_modules/.bin/nyc report --reporter=text-summary",
"junit:merge": "../../../node_modules/.bin/mochawesome-merge ../../../target/kibana-osquery/cypress/results/mochawesome*.json > ../../../target/kibana-osquery/cypress/results/output.json && ../../../node_modules/.bin/marge ../../../target/kibana-osquery/cypress/results/output.json --reportDir ../../../target/kibana-osquery/cypress/results && yarn junit:transform && mkdir -p ../../../target/junit && cp ../../../target/kibana-osquery/cypress/results/*.xml ../../../target/junit/",

View file

@ -7,16 +7,16 @@
"scripts": {
"extract-mitre-attacks": "node scripts/extract_tactics_techniques_mitre.js && node ../../../scripts/eslint ./public/detections/mitre/mitre_tactics_techniques.ts --fix",
"build-beat-doc": "node scripts/beat_docs/build.js && node ../../../scripts/eslint ../timelines/server/utils/beat_schema/fields.ts --fix",
"cypress": "NODE_OPTIONS=--openssl-legacy-provider ../../../node_modules/.bin/cypress",
"cypress": "../../../node_modules/.bin/cypress",
"cypress:burn": "yarn cypress:dw run --env burn=2 --headed",
"cypress:changed-specs-only": "yarn cypress:dw run --changed-specs-only --env burn=2",
"cypress:dw": "NODE_OPTIONS=--openssl-legacy-provider node ./scripts/start_cypress_parallel --config-file ./public/management/cypress/cypress.config.ts --ftr-config-file ../../test/defend_workflows_cypress/cli_config",
"cypress:dw": "node ./scripts/start_cypress_parallel --config-file ./public/management/cypress/cypress.config.ts --ftr-config-file ../../test/defend_workflows_cypress/cli_config",
"cypress:dw:open": "yarn cypress:dw open",
"cypress:dw:run": "yarn cypress:dw run",
"cypress:dw:serverless": "NODE_OPTIONS=--openssl-legacy-provider node ./scripts/start_cypress_parallel --config-file ./public/management/cypress/cypress_serverless.config.ts --ftr-config-file ../../test/defend_workflows_cypress/serverless_config",
"cypress:dw:serverless": "node ./scripts/start_cypress_parallel --config-file ./public/management/cypress/cypress_serverless.config.ts --ftr-config-file ../../test/defend_workflows_cypress/serverless_config",
"cypress:dw:serverless:open": "yarn cypress:dw:serverless open",
"cypress:dw:serverless:run": "yarn cypress:dw:serverless run",
"cypress:dw:qa:serverless": "NODE_OPTIONS=--openssl-legacy-provider node ./scripts/start_cypress_parallel_serverless --config-file ./public/management/cypress/cypress_serverless_qa.config.ts",
"cypress:dw:qa:serverless": "node ./scripts/start_cypress_parallel_serverless --config-file ./public/management/cypress/cypress_serverless_qa.config.ts",
"cypress:dw:qa:serverless:run": "yarn cypress:dw:qa:serverless run",
"cypress:dw:serverless:changed-specs-only": "yarn cypress:dw:serverless run --changed-specs-only --env burn=2",
"cypress:dw:endpoint": "echo '\n** WARNING **: Run script `cypress:dw:endpoint` no longer valid! Use `cypress:dw` instead\n'",
@ -35,4 +35,4 @@
"openapi:bundle:entity-analytics": "node scripts/openapi/bundle_entity_analytics",
"openapi:bundle:endpoint-management": "node scripts/openapi/bundle_endpoint_management"
}
}
}

View file

@ -5,11 +5,11 @@
"private": true,
"license": "Elastic License 2.0",
"scripts": {
"cypress": "NODE_OPTIONS=--openssl-legacy-provider ../../../node_modules/.bin/cypress",
"cypress:open:ess": "TZ=UTC NODE_OPTIONS=--openssl-legacy-provider node ../../plugins/security_solution/scripts/start_cypress_parallel open --spec './cypress/e2e/**/*.cy.ts' --config-file ../../test/security_solution_cypress/cypress/cypress.config.ts --ftr-config-file ../../test/security_solution_cypress/cli_config",
"cypress": "../../../node_modules/.bin/cypress",
"cypress:open:ess": "TZ=UTC node ../../plugins/security_solution/scripts/start_cypress_parallel open --spec './cypress/e2e/**/*.cy.ts' --config-file ../../test/security_solution_cypress/cypress/cypress.config.ts --ftr-config-file ../../test/security_solution_cypress/cli_config",
"cypress:entity_analytics:run:ess": "yarn cypress:ess --spec './cypress/e2e/entity_analytics/**/*.cy.ts'",
"cypress:run:cases:ess": "yarn cypress:ess --spec './cypress/e2e/explore/cases/*.cy.ts'",
"cypress:ess": "TZ=UTC NODE_OPTIONS=--openssl-legacy-provider node ../../plugins/security_solution/scripts/start_cypress_parallel run --config-file ../../test/security_solution_cypress/cypress/cypress_ci.config.ts --ftr-config-file ../../test/security_solution_cypress/cli_config",
"cypress:ess": "TZ=UTC node ../../plugins/security_solution/scripts/start_cypress_parallel run --config-file ../../test/security_solution_cypress/cypress/cypress_ci.config.ts --ftr-config-file ../../test/security_solution_cypress/cli_config",
"cypress:rule_management:run:ess":"yarn cypress:ess --spec './cypress/e2e/detection_response/rule_management/!(prebuilt_rules)/**/*.cy.ts'",
"cypress:rule_management:prebuilt_rules:run:ess": "yarn cypress:ess --spec './cypress/e2e/detection_response/rule_management/prebuilt_rules/**/*.cy.ts'",
"cypress:detection_engine:run:ess":"yarn cypress:ess --spec './cypress/e2e/detection_response/detection_engine/!(exceptions)/**/*.cy.ts'",
@ -23,8 +23,8 @@
"cypress:burn:ess": "yarn cypress:ess --env burn=5",
"junit:merge": "../../../node_modules/.bin/mochawesome-merge ../../../target/kibana-security-solution/cypress/results/mochawesome*.json > ../../../target/kibana-security-solution/cypress/results/output.json && ../../../node_modules/.bin/marge ../../../target/kibana-security-solution/cypress/results/output.json --reportDir ../../../target/kibana-security-solution/cypress/results && yarn junit:transform && mkdir -p ../../../target/junit && cp ../../../target/kibana-security-solution/cypress/results/*.xml ../../../target/junit/",
"junit:transform": "node ../../plugins/security_solution/scripts/junit_transformer --pathPattern '../../../target/kibana-security-solution/cypress/results/*.xml' --rootDirectory ../../../ --reportName 'Security Solution Cypress' --writeInPlace",
"cypress:serverless": "TZ=UTC NODE_OPTIONS=--openssl-legacy-provider node ../../plugins/security_solution/scripts/start_cypress_parallel --config-file ../../test/security_solution_cypress/cypress/cypress_ci_serverless.config.ts --ftr-config-file ../../test/security_solution_cypress/serverless_config",
"cypress:cloud:serverless": "TZ=UTC NODE_OPTIONS=--openssl-legacy-provider NODE_TLS_REJECT_UNAUTHORIZED=0 ../../../node_modules/.bin/cypress",
"cypress:serverless": "TZ=UTC node ../../plugins/security_solution/scripts/start_cypress_parallel --config-file ../../test/security_solution_cypress/cypress/cypress_ci_serverless.config.ts --ftr-config-file ../../test/security_solution_cypress/serverless_config",
"cypress:cloud:serverless": "TZ=UTC NODE_TLS_REJECT_UNAUTHORIZED=0 ../../../node_modules/.bin/cypress",
"cypress:open:cloud:serverless": "yarn cypress:cloud:serverless open --config-file ./cypress/cypress_serverless.config.ts --env CLOUD_SERVERLESS=true",
"cypress:open:serverless": "yarn cypress:serverless open --config-file ../../test/security_solution_cypress/cypress/cypress_serverless.config.ts --spec './cypress/e2e/**/*.cy.ts'",
"cypress:entity_analytics:run:serverless": "yarn cypress:serverless --spec './cypress/e2e/entity_analytics/**/*.cy.ts'",
@ -38,7 +38,7 @@
"cypress:changed-specs-only:serverless": "yarn cypress:serverless --changed-specs-only --env burn=5",
"cypress:cloud_security_posture:run:serverless": "yarn cypress:serverless --spec './cypress/e2e/cloud_security_posture/**/*.cy.ts'",
"cypress:burn:serverless": "yarn cypress:serverless --env burn=2",
"cypress:qa:serverless": "TZ=UTC NODE_OPTIONS=--openssl-legacy-provider node ../../plugins/security_solution/scripts/start_cypress_parallel_serverless --config-file ../../test/security_solution_cypress/cypress/cypress_ci_serverless_qa.config.ts",
"cypress:qa:serverless": "TZ=UTC node ../../plugins/security_solution/scripts/start_cypress_parallel_serverless --config-file ../../test/security_solution_cypress/cypress/cypress_ci_serverless_qa.config.ts",
"cypress:open:qa:serverless": "yarn cypress:qa:serverless open",
"cypress:run:qa:serverless:entity_analytics": "yarn cypress:qa:serverless --spec './cypress/e2e/entity_analytics/**/*.cy.ts'",
"cypress:run:qa:serverless:investigations": "yarn cypress:qa:serverless --spec './cypress/e2e/investigations/**/*.cy.ts'",

View file

@ -5,9 +5,9 @@
"private": true,
"license": "Elastic License 2.0",
"scripts": {
"cypress:open": "NODE_OPTIONS=--openssl-legacy-provider node ../../../../../../node_modules/.bin/cypress open --config-file ./cypress.config.ts",
"cypress:run": "NODE_OPTIONS=--openssl-legacy-provider node ../../../../../../node_modules/.bin/cypress run --browser chrome --config-file ./cypress.config.ts",
"cypress:serverless:open": "NODE_OPTIONS=--openssl-legacy-provider node ../../../../../../scripts/functional_tests --config ./config_runner.ts",
"cypress:serverless:run": "NODE_OPTIONS=--openssl-legacy-provider node ../../../../../../scripts/functional_tests --config ./config_server.ts"
"cypress:open": "node ../../../../../../node_modules/.bin/cypress open --config-file ./cypress.config.ts",
"cypress:run": "node ../../../../../../node_modules/.bin/cypress run --browser chrome --config-file ./cypress.config.ts",
"cypress:serverless:open": "node ../../../../../../scripts/functional_tests --config ./config_runner.ts",
"cypress:serverless:run": "node ../../../../../../scripts/functional_tests --config ./config_server.ts"
}
}

1185
yarn.lock

File diff suppressed because it is too large Load diff