Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

share specific instances of some ui packages #54079

Merged
merged 8 commits into from
Jan 10, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

const { readdirSync } = require('fs');
const { resolve } = require('path');
const UiSharedDeps = require('@kbn/ui-shared-deps');

const APACHE_2_0_LICENSE_HEADER = `
/*
Expand Down Expand Up @@ -366,15 +367,15 @@ module.exports = {
'src/fixtures/**/*.js', // TODO: this directory needs to be more obviously "public" (or go away)
],
settings: {
// instructs import/no-extraneous-dependencies to treat modules
// in plugins/ or ui/ namespace as "core modules" so they don't
// trigger failures for not being listed in package.json
// instructs import/no-extraneous-dependencies to treat certain modules
// as core modules, even if they aren't listed in package.json
'import/core-modules': [
'plugins',
'legacy/ui',
'uiExports',
// TODO: Remove once https://github.com/benmosher/eslint-plugin-import/issues/1374 is fixed
'querystring',
...Object.keys(UiSharedDeps.externals),
],

'import/resolver': {
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@
"@kbn/pm": "1.0.0",
"@kbn/test-subj-selector": "0.2.1",
"@kbn/ui-framework": "1.0.0",
"@kbn/ui-shared-deps": "1.0.0",
"@types/json-stable-stringify": "^1.0.32",
"@types/lodash.clonedeep": "^4.5.4",
"@types/react-grid-layout": "^0.16.7",
Expand Down
3 changes: 3 additions & 0 deletions packages/kbn-ui-shared-deps/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# `@kbn/ui-shared-deps`

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.
39 changes: 39 additions & 0 deletions packages/kbn-ui-shared-deps/entry.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

// must load before angular
export const Jquery = require('jquery');
window.$ = window.jQuery = Jquery;

export const Angular = require('angular');
export const ElasticCharts = require('@elastic/charts');
export const ElasticEui = require('@elastic/eui');
export const ElasticEuiLibServices = require('@elastic/eui/lib/services');
export const ElasticEuiLightTheme = require('@elastic/eui/dist/eui_theme_light.json');
export const ElasticEuiDarkTheme = require('@elastic/eui/dist/eui_theme_dark.json');
export const Moment = require('moment');
export const MomentTimezone = require('moment-timezone/moment-timezone');
export const React = require('react');
export const ReactDom = require('react-dom');
export const ReactIntl = require('react-intl');
export const ReactRouter = require('react-router'); // eslint-disable-line
export const ReactRouterDom = require('react-router-dom');

// load timezone data into moment-timezone
Moment.tz.load(require('moment-timezone/data/packed/latest.json'));
29 changes: 26 additions & 3 deletions webpackShims/angular.js → packages/kbn-ui-shared-deps/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,29 @@
* under the License.
*/

require('jquery');
require('../node_modules/angular/angular');
module.exports = window.angular;
/**
* Absolute path to the distributable directory
*/
export const distDir: string;

/**
* Filename of the main bundle file in the distributable directory
*/
export const distFilename: string;

/**
* Filename of the dark-theme css file in the distributable directory
*/
export const darkCssDistFilename: string;

/**
* Filename of the light-theme css file in the distributable directory
*/
export const lightCssDistFilename: string;

/**
* Externals mapping inteded to be used in a webpack config
*/
export const externals: {
[key: string]: string;
};
41 changes: 41 additions & 0 deletions packages/kbn-ui-shared-deps/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

const Path = require('path');

exports.distDir = Path.resolve(__dirname, 'target');
exports.distFilename = 'kbn-ui-shared-deps.js';
exports.lightCssDistFilename = 'kbn-ui-shared-deps.light.css';
exports.darkCssDistFilename = 'kbn-ui-shared-deps.dark.css';
exports.externals = {
angular: '__kbnSharedDeps__.Angular',
'@elastic/charts': '__kbnSharedDeps__.ElasticCharts',
'@elastic/eui': '__kbnSharedDeps__.ElasticEui',
'@elastic/eui/lib/services': '__kbnSharedDeps__.ElasticEuiLibServices',
'@elastic/eui/dist/eui_theme_light.json': '__kbnSharedDeps__.ElasticEuiLightTheme',
'@elastic/eui/dist/eui_theme_dark.json': '__kbnSharedDeps__.ElasticEuiDarkTheme',
jquery: '__kbnSharedDeps__.Jquery',
moment: '__kbnSharedDeps__.Moment',
'moment-timezone': '__kbnSharedDeps__.MomentTimezone',
react: '__kbnSharedDeps__.React',
'react-dom': '__kbnSharedDeps__.ReactDom',
'react-intl': '__kbnSharedDeps__.ReactIntl',
'react-router': '__kbnSharedDeps__.ReactRouter',
'react-router-dom': '__kbnSharedDeps__.ReactRouterDom',
};
29 changes: 29 additions & 0 deletions packages/kbn-ui-shared-deps/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "@kbn/ui-shared-deps",
"version": "1.0.0",
"license": "Apache-2.0",
"private": true,
"scripts": {
"build": "node scripts/build",
"kbn:bootstrap": "node scripts/build --dev",
"kbn:watch": "node scripts/build --watch"
},
"devDependencies": {
"@elastic/eui": "17.3.1",
"@elastic/charts": "^16.0.2",
"@kbn/dev-utils": "1.0.0",
"@yarnpkg/lockfile": "^1.1.0",
"angular": "^1.7.9",
"css-loader": "^2.1.1",
"del": "^5.1.0",
"jquery": "^3.4.1",
"mini-css-extract-plugin": "0.8.0",
"moment": "^2.24.0",
"moment-timezone": "^0.5.27",
"react-dom": "^16.12.0",
"react-intl": "^2.8.0",
"react": "^16.12.0",
"read-pkg": "^5.2.0",
"webpack": "4.41.0"
}
}
105 changes: 105 additions & 0 deletions packages/kbn-ui-shared-deps/scripts/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

const Path = require('path');

const { run, createFailError } = require('@kbn/dev-utils');
const webpack = require('webpack');
const Stats = require('webpack/lib/Stats');
const del = require('del');

const { getWebpackConfig } = require('../webpack.config');

run(
async ({ log, flags }) => {
log.info('cleaning previous build output');
await del(Path.resolve(__dirname, '../target'));

const compiler = webpack(
getWebpackConfig({
dev: flags.dev,
})
);

/** @param {webpack.Stats} stats */
const onCompilationComplete = stats => {
const took = Math.round((stats.endTime - stats.startTime) / 1000);

if (!stats.hasErrors() && !stats.hasWarnings()) {
log.success(`webpack completed in about ${took} seconds`);
return;
}

throw createFailError(
`webpack failure in about ${took} seconds\n${stats.toString({
colors: true,
...Stats.presetToOptions('minimal'),
})}`
);
};

if (flags.watch) {
compiler.hooks.done.tap('report on stats', stats => {
try {
onCompilationComplete(stats);
} catch (error) {
log.error(error.message);
}
});

compiler.hooks.watchRun.tap('report on start', () => {
process.stdout.cursorTo(0, 0);
process.stdout.clearScreenDown();
log.info('Running webpack compilation...');
});

compiler.watch({}, error => {
if (error) {
log.error('Fatal webpack error');
log.error(error);
process.exit(1);
}
});

return;
}

onCompilationComplete(
await new Promise((resolve, reject) => {
compiler.run((error, stats) => {
if (error) {
reject(error);
} else {
resolve(stats);
}
});
})
);
},
{
description: 'build @kbn/ui-shared-deps',
flags: {
boolean: ['watch', 'dev'],
help: `
--watch Run in watch mode
--dev Build development friendly version
`,
},
}
);
6 changes: 6 additions & 0 deletions packages/kbn-ui-shared-deps/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": "../../tsconfig.json",
"include": [
"index.d.ts"
]
}
90 changes: 90 additions & 0 deletions packages/kbn-ui-shared-deps/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

const Path = require('path');

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { REPO_ROOT } = require('@kbn/dev-utils');
const webpack = require('webpack');

const SharedDeps = require('./index');

const MOMENT_SRC = require.resolve('moment/min/moment-with-locales.js');

exports.getWebpackConfig = ({ dev = false } = {}) => ({
mode: dev ? 'development' : 'production',
entry: {
[SharedDeps.distFilename.replace(/\.js$/, '')]: './entry.js',
[SharedDeps.darkCssDistFilename.replace(/\.css$/, '')]: [
'@elastic/eui/dist/eui_theme_dark.css',
'@elastic/charts/dist/theme_only_dark.css',
],
[SharedDeps.lightCssDistFilename.replace(/\.css$/, '')]: [
'@elastic/eui/dist/eui_theme_light.css',
'@elastic/charts/dist/theme_only_light.css',
],
},
context: __dirname,
devtool: dev ? '#cheap-source-map' : false,
output: {
path: SharedDeps.distDir,
filename: '[name].js',
sourceMapFilename: '[file].map',
publicPath: '__REPLACE_WITH_PUBLIC_PATH__',
devtoolModuleFilenameTemplate: info =>
`kbn-ui-shared-deps/${Path.relative(REPO_ROOT, info.absoluteResourcePath)}`,
library: '__kbnSharedDeps__',
},

module: {
noParse: [MOMENT_SRC],
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
],
},

resolve: {
alias: {
moment: MOMENT_SRC,
},
},

optimization: {
noEmitOnErrors: true,
},

performance: {
// NOTE: we are disabling this as those hints
// are more tailored for the final bundles result
// and not for the webpack compilations performance itself
hints: false,
},

plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': dev ? '"development"' : '"production"',
}),
],
});
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ describe('CoordinateMapsVisualizationTest', function() {
async function compareImage(expectedImageSource, index) {
const elementList = domNode.querySelectorAll('canvas');
const firstCanvasOnMap = elementList[index];
return imageComparator.compareImage(firstCanvasOnMap, expectedImageSource, THRESHOLD);
return await imageComparator.compareImage(firstCanvasOnMap, expectedImageSource, THRESHOLD);
}

function setupDOM(width, height) {
Expand Down
Loading