Skip to content

Commit 357be59

Browse files
author
Spencer
authored
share specific instances of some ui packages (elastic#54079)
* share specific instances of some ui packages * remove unnecessary eslint changes, every package will define deps anyway * remove mentions of moment webpackShims in eslint resolver * remove use of lodash * list angular as dep for x-pack * add operations as codeowner of shared-deps pkg
1 parent 51c1a8f commit 357be59

File tree

24 files changed

+416
-242
lines changed

24 files changed

+416
-242
lines changed

.eslintrc.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -341,9 +341,8 @@ module.exports = {
341341
'src/fixtures/**/*.js', // TODO: this directory needs to be more obviously "public" (or go away)
342342
],
343343
settings: {
344-
// instructs import/no-extraneous-dependencies to treat modules
345-
// in plugins/ or ui/ namespace as "core modules" so they don't
346-
// trigger failures for not being listed in package.json
344+
// instructs import/no-extraneous-dependencies to treat certain modules
345+
// as core modules, even if they aren't listed in package.json
347346
'import/core-modules': [
348347
'plugins',
349348
'legacy/ui',

.github/CODEOWNERS

+1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
/packages/kbn-es/ @elastic/kibana-operations
8787
/packages/kbn-pm/ @elastic/kibana-operations
8888
/packages/kbn-test/ @elastic/kibana-operations
89+
/packages/kbn-ui-shared-deps/ @elastic/kibana-operations
8990
/src/legacy/server/keystore/ @elastic/kibana-operations
9091
/src/legacy/server/pid/ @elastic/kibana-operations
9192
/src/legacy/server/sass/ @elastic/kibana-operations

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@
134134
"@kbn/pm": "1.0.0",
135135
"@kbn/test-subj-selector": "0.2.1",
136136
"@kbn/ui-framework": "1.0.0",
137+
"@kbn/ui-shared-deps": "1.0.0",
137138
"@types/json-stable-stringify": "^1.0.32",
138139
"@types/lodash.clonedeep": "^4.5.4",
139140
"@types/node-forge": "^0.9.0",

packages/kbn-eslint-import-resolver-kibana/lib/get_webpack_config.js

-2
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ exports.getWebpackConfig = function(kibanaPath, projectRoot, config) {
3030
ui: fromKibana('src/legacy/ui/public'),
3131
test_harness: fromKibana('src/test_harness/public'),
3232
querystring: 'querystring-browser',
33-
moment$: fromKibana('webpackShims/moment'),
34-
'moment-timezone$': fromKibana('webpackShims/moment-timezone'),
3533

3634
// Dev defaults for test bundle https://github.com/elastic/kibana/blob/6998f074542e8c7b32955db159d15661aca253d7/src/core_plugins/tests_bundle/index.js#L73-L78
3735
ng_mock$: fromKibana('src/test_utils/public/ng_mock'),

packages/kbn-ui-shared-deps/README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# `@kbn/ui-shared-deps`
2+
3+
Shared dependencies that must only have a single instance are installed and re-exported from here. To consume them, import the package and merge the `externals` export into your webpack config so that all references to the supported modules will be remapped to use the global versions.

packages/kbn-ui-shared-deps/entry.js

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
// must load before angular
21+
export const Jquery = require('jquery');
22+
window.$ = window.jQuery = Jquery;
23+
24+
export const Angular = require('angular');
25+
export const ElasticCharts = require('@elastic/charts');
26+
export const ElasticEui = require('@elastic/eui');
27+
export const ElasticEuiLibServices = require('@elastic/eui/lib/services');
28+
export const ElasticEuiLightTheme = require('@elastic/eui/dist/eui_theme_light.json');
29+
export const ElasticEuiDarkTheme = require('@elastic/eui/dist/eui_theme_dark.json');
30+
export const Moment = require('moment');
31+
export const MomentTimezone = require('moment-timezone/moment-timezone');
32+
export const React = require('react');
33+
export const ReactDom = require('react-dom');
34+
export const ReactIntl = require('react-intl');
35+
export const ReactRouter = require('react-router'); // eslint-disable-line
36+
export const ReactRouterDom = require('react-router-dom');
37+
38+
// load timezone data into moment-timezone
39+
Moment.tz.load(require('moment-timezone/data/packed/latest.json'));

webpackShims/angular.js packages/kbn-ui-shared-deps/index.d.ts

+26-3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,29 @@
1717
* under the License.
1818
*/
1919

20-
require('jquery');
21-
require('../node_modules/angular/angular');
22-
module.exports = window.angular;
20+
/**
21+
* Absolute path to the distributable directory
22+
*/
23+
export const distDir: string;
24+
25+
/**
26+
* Filename of the main bundle file in the distributable directory
27+
*/
28+
export const distFilename: string;
29+
30+
/**
31+
* Filename of the dark-theme css file in the distributable directory
32+
*/
33+
export const darkCssDistFilename: string;
34+
35+
/**
36+
* Filename of the light-theme css file in the distributable directory
37+
*/
38+
export const lightCssDistFilename: string;
39+
40+
/**
41+
* Externals mapping inteded to be used in a webpack config
42+
*/
43+
export const externals: {
44+
[key: string]: string;
45+
};

packages/kbn-ui-shared-deps/index.js

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
const Path = require('path');
21+
22+
exports.distDir = Path.resolve(__dirname, 'target');
23+
exports.distFilename = 'kbn-ui-shared-deps.js';
24+
exports.lightCssDistFilename = 'kbn-ui-shared-deps.light.css';
25+
exports.darkCssDistFilename = 'kbn-ui-shared-deps.dark.css';
26+
exports.externals = {
27+
angular: '__kbnSharedDeps__.Angular',
28+
'@elastic/charts': '__kbnSharedDeps__.ElasticCharts',
29+
'@elastic/eui': '__kbnSharedDeps__.ElasticEui',
30+
'@elastic/eui/lib/services': '__kbnSharedDeps__.ElasticEuiLibServices',
31+
'@elastic/eui/dist/eui_theme_light.json': '__kbnSharedDeps__.ElasticEuiLightTheme',
32+
'@elastic/eui/dist/eui_theme_dark.json': '__kbnSharedDeps__.ElasticEuiDarkTheme',
33+
jquery: '__kbnSharedDeps__.Jquery',
34+
moment: '__kbnSharedDeps__.Moment',
35+
'moment-timezone': '__kbnSharedDeps__.MomentTimezone',
36+
react: '__kbnSharedDeps__.React',
37+
'react-dom': '__kbnSharedDeps__.ReactDom',
38+
'react-intl': '__kbnSharedDeps__.ReactIntl',
39+
'react-router': '__kbnSharedDeps__.ReactRouter',
40+
'react-router-dom': '__kbnSharedDeps__.ReactRouterDom',
41+
};
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"name": "@kbn/ui-shared-deps",
3+
"version": "1.0.0",
4+
"license": "Apache-2.0",
5+
"private": true,
6+
"scripts": {
7+
"build": "node scripts/build",
8+
"kbn:bootstrap": "node scripts/build --dev",
9+
"kbn:watch": "node scripts/build --watch"
10+
},
11+
"devDependencies": {
12+
"@elastic/eui": "17.3.1",
13+
"@elastic/charts": "^16.1.0",
14+
"@kbn/dev-utils": "1.0.0",
15+
"@yarnpkg/lockfile": "^1.1.0",
16+
"angular": "^1.7.9",
17+
"css-loader": "^2.1.1",
18+
"del": "^5.1.0",
19+
"jquery": "^3.4.1",
20+
"mini-css-extract-plugin": "0.8.0",
21+
"moment": "^2.24.0",
22+
"moment-timezone": "^0.5.27",
23+
"react-dom": "^16.12.0",
24+
"react-intl": "^2.8.0",
25+
"react": "^16.12.0",
26+
"read-pkg": "^5.2.0",
27+
"webpack": "4.41.0"
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
const Path = require('path');
21+
22+
const { run, createFailError } = require('@kbn/dev-utils');
23+
const webpack = require('webpack');
24+
const Stats = require('webpack/lib/Stats');
25+
const del = require('del');
26+
27+
const { getWebpackConfig } = require('../webpack.config');
28+
29+
run(
30+
async ({ log, flags }) => {
31+
log.info('cleaning previous build output');
32+
await del(Path.resolve(__dirname, '../target'));
33+
34+
const compiler = webpack(
35+
getWebpackConfig({
36+
dev: flags.dev,
37+
})
38+
);
39+
40+
/** @param {webpack.Stats} stats */
41+
const onCompilationComplete = stats => {
42+
const took = Math.round((stats.endTime - stats.startTime) / 1000);
43+
44+
if (!stats.hasErrors() && !stats.hasWarnings()) {
45+
log.success(`webpack completed in about ${took} seconds`);
46+
return;
47+
}
48+
49+
throw createFailError(
50+
`webpack failure in about ${took} seconds\n${stats.toString({
51+
colors: true,
52+
...Stats.presetToOptions('minimal'),
53+
})}`
54+
);
55+
};
56+
57+
if (flags.watch) {
58+
compiler.hooks.done.tap('report on stats', stats => {
59+
try {
60+
onCompilationComplete(stats);
61+
} catch (error) {
62+
log.error(error.message);
63+
}
64+
});
65+
66+
compiler.hooks.watchRun.tap('report on start', () => {
67+
process.stdout.cursorTo(0, 0);
68+
process.stdout.clearScreenDown();
69+
log.info('Running webpack compilation...');
70+
});
71+
72+
compiler.watch({}, error => {
73+
if (error) {
74+
log.error('Fatal webpack error');
75+
log.error(error);
76+
process.exit(1);
77+
}
78+
});
79+
80+
return;
81+
}
82+
83+
onCompilationComplete(
84+
await new Promise((resolve, reject) => {
85+
compiler.run((error, stats) => {
86+
if (error) {
87+
reject(error);
88+
} else {
89+
resolve(stats);
90+
}
91+
});
92+
})
93+
);
94+
},
95+
{
96+
description: 'build @kbn/ui-shared-deps',
97+
flags: {
98+
boolean: ['watch', 'dev'],
99+
help: `
100+
--watch Run in watch mode
101+
--dev Build development friendly version
102+
`,
103+
},
104+
}
105+
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"extends": "../../tsconfig.json",
3+
"include": [
4+
"index.d.ts"
5+
]
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
const Path = require('path');
21+
22+
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
23+
const { REPO_ROOT } = require('@kbn/dev-utils');
24+
const webpack = require('webpack');
25+
26+
const SharedDeps = require('./index');
27+
28+
const MOMENT_SRC = require.resolve('moment/min/moment-with-locales.js');
29+
30+
exports.getWebpackConfig = ({ dev = false } = {}) => ({
31+
mode: dev ? 'development' : 'production',
32+
entry: {
33+
[SharedDeps.distFilename.replace(/\.js$/, '')]: './entry.js',
34+
[SharedDeps.darkCssDistFilename.replace(/\.css$/, '')]: [
35+
'@elastic/eui/dist/eui_theme_dark.css',
36+
'@elastic/charts/dist/theme_only_dark.css',
37+
],
38+
[SharedDeps.lightCssDistFilename.replace(/\.css$/, '')]: [
39+
'@elastic/eui/dist/eui_theme_light.css',
40+
'@elastic/charts/dist/theme_only_light.css',
41+
],
42+
},
43+
context: __dirname,
44+
devtool: dev ? '#cheap-source-map' : false,
45+
output: {
46+
path: SharedDeps.distDir,
47+
filename: '[name].js',
48+
sourceMapFilename: '[file].map',
49+
publicPath: '__REPLACE_WITH_PUBLIC_PATH__',
50+
devtoolModuleFilenameTemplate: info =>
51+
`kbn-ui-shared-deps/${Path.relative(REPO_ROOT, info.absoluteResourcePath)}`,
52+
library: '__kbnSharedDeps__',
53+
},
54+
55+
module: {
56+
noParse: [MOMENT_SRC],
57+
rules: [
58+
{
59+
test: /\.css$/,
60+
use: [MiniCssExtractPlugin.loader, 'css-loader'],
61+
},
62+
],
63+
},
64+
65+
resolve: {
66+
alias: {
67+
moment: MOMENT_SRC,
68+
},
69+
},
70+
71+
optimization: {
72+
noEmitOnErrors: true,
73+
},
74+
75+
performance: {
76+
// NOTE: we are disabling this as those hints
77+
// are more tailored for the final bundles result
78+
// and not for the webpack compilations performance itself
79+
hints: false,
80+
},
81+
82+
plugins: [
83+
new MiniCssExtractPlugin({
84+
filename: '[name].css',
85+
}),
86+
new webpack.DefinePlugin({
87+
'process.env.NODE_ENV': dev ? '"development"' : '"production"',
88+
}),
89+
],
90+
});

src/legacy/ui/ui_render/bootstrap/template.js.hbs

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ if (window.__kbnStrictCsp__ && window.__kbnCspNotEnforced__) {
1414
window.onload = function () {
1515
var files = [
1616
'{{dllBundlePath}}/vendors.bundle.dll.js',
17+
'{{regularBundlePath}}/kbn-ui-shared-deps/{{sharedDepsFilename}}',
1718
'{{regularBundlePath}}/commons.bundle.js',
1819
'{{regularBundlePath}}/{{appId}}.bundle.js'
1920
];

0 commit comments

Comments
 (0)