Skip to content

Commit

Permalink
Build targeting Jest with relevant transforms (#2698)
Browse files Browse the repository at this point in the history
* wip

* wip: use babel

* async fn plugins

* dir name; remove index

* ignore

* babelrc

* testenv mock file updates

* babel version bumps

* path.join

* remove iconPropType export

* testenv icon rest

* testenv icon rest

* docs

* CL

* Update wiki/consuming.md

Co-Authored-By: Chandler Prall <chandler.prall@gmail.com>

Co-authored-by: Chandler Prall <chandler.prall@gmail.com>
  • Loading branch information
thompsongl and chandlerprall authored Feb 6, 2020
1 parent 87581c6 commit 034d76d
Show file tree
Hide file tree
Showing 15 changed files with 98 additions and 12 deletions.
9 changes: 9 additions & 0 deletions .babelrc-test-env.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
"extends": "./.babelrc.js",
"plugins": [
"@babel/plugin-transform-runtime",
"@babel/plugin-transform-async-to-generator",
"@babel/plugin-syntax-dynamic-import",
"dynamic-import-node"
],
};
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ dist
node_modules
es
lib
test-env
types
eui.d.ts
**/*.snap.js
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ tmp/
dist/
lib/
es/
test-env/
.idea
.vscode/
.DS_Store
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
- Converted `EuiColorPicker` color conversion functions to `chroma-js` methods ([#2805](https://github.com/elastic/eui/pull/2805))
- Added `direction` parameter to `euiPaletteColorBlind()` for specifiying lighter or darker (or both) alternates ([#2822](https://github.com/elastic/eui/pull/2822))
- Converted `EuiSideNav` to TypeScript ([#2818](https://github.com/elastic/eui/issues/2818))
- Added babel-transformed and partially mocked commonjs build (`test-env/`) to target Kibana's Jest environment ([#2698](https://github.com/elastic/eui/pull/2698))

**Bug fixes**

Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@
"@babel/plugin-proposal-class-properties": "^7.8.3",
"@babel/plugin-proposal-object-rest-spread": "^7.8.3",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-transform-async-to-generator": "^7.8.3",
"@babel/plugin-transform-runtime": "^7.8.3",
"@babel/preset-env": "^7.8.3",
"@babel/preset-react": "^7.8.3",
"@babel/preset-typescript": "^7.8.3",
Expand Down
1 change: 1 addition & 0 deletions scripts/compile-clean.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ const rimraf = require('rimraf');
rimraf.sync('dist');
rimraf.sync('lib');
rimraf.sync('es');
rimraf.sync('test-env');
27 changes: 24 additions & 3 deletions scripts/compile-eui.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const chalk = require('chalk');
const shell = require('shelljs');
const path = require('path');
const glob = require('glob');
const fs = require('fs');
const dtsGenerator = require('dts-generator').default;

function compileLib() {
Expand All @@ -13,11 +14,12 @@ function compileLib() {
'lib/test'
);

console.log('Compiling src/ to es/ and lib/');
console.log('Compiling src/ to es/, lib/, and test-env/');

// Run all code (com|trans)pilation through babel (ESNext JS & TypeScript)

execSync(
'babel --quiet --out-dir=es --extensions .js,.ts,.tsx --ignore "**/webpack.config.js,**/*.test.js,**/*.d.ts" src',
'babel --quiet --out-dir=es --extensions .js,.ts,.tsx --ignore "**/webpack.config.js,**/*.test.js,**/*.test.ts,**/*.test.tsx,**/*.d.ts,**/*.testenv.js,**/*.testenv.tsx,**/*.testenv.ts" src',
{
env: {
...process.env,
Expand All @@ -26,15 +28,34 @@ function compileLib() {
},
}
);

execSync(
'babel --quiet --out-dir=lib --extensions .js,.ts,.tsx --ignore "**/webpack.config.js,**/*.test.js,**/*.test.ts,**/*.test.tsx,**/*.d.ts,**/*.testenv.js,**/*.testenv.tsx,**/*.testenv.ts" src',
{
env: {
...process.env,
NO_COREJS_POLYFILL: true,
},
}
);

execSync(
'babel --quiet --out-dir=lib --extensions .js,.ts,.tsx --ignore "**/webpack.config.js,**/*.test.js,**/*.d.ts" src',
'babel --quiet --out-dir=test-env --extensions .js,.ts,.tsx --config-file="./.babelrc-test-env.js" --ignore "**/webpack.config.js,**/*.test.js,**/*.test.ts,**/*.test.tsx,**/*.d.ts" src',
{
env: {
...process.env,
NO_COREJS_POLYFILL: true,
},
}
);
glob('./test-env/**/*.testenv.js', undefined, (error, files) => {
files.forEach(file => {
const dir = path.dirname(file);
const fileName = path.basename(file, '.js');
const targetName = fileName.replace('.testenv', '');
fs.renameSync(file, path.join(dir, `${targetName}.js`));
});
});

console.log(chalk.green('✔ Finished compiling src/'));

Expand Down
2 changes: 2 additions & 0 deletions scripts/dtsgenerator.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ const generator = dtsGenerator({
'src-framer/**/*',
'**/*.test.ts',
'**/*.test.tsx',
'**/*.testenv.ts',
'**/*.testenv.tsx',
'src/themes/charts/*' // A separate d.ts file is generated for the charts theme file
],
resolveModuleId(params) {
Expand Down
7 changes: 5 additions & 2 deletions src/components/date_picker/date_picker_range.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import classNames from 'classnames';

import { EuiText } from '../text';
import { IconPropType, EuiIcon } from '../icon';
import { EuiIcon } from '../icon';

export const EuiDatePickerRange = ({
children,
Expand Down Expand Up @@ -88,7 +88,10 @@ EuiDatePickerRange.propTypes = {
/**
* Pass either an icon type or set to `false` to remove icon entirely
*/
iconType: PropTypes.oneOfType([PropTypes.bool, IconPropType]),
iconType: PropTypes.oneOfType([
PropTypes.bool,
PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
]),
fullWidth: PropTypes.bool,
/**
* Won't apply any additional props to start and end date components
Expand Down
8 changes: 8 additions & 0 deletions src/components/icon/icon.testenv.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import React from 'react';
export const EuiIcon = ({ type, ...rest }: any) => (
<div data-euiicon-type={type} {...rest} />
);

export const TYPES = [];
export const COLORS = [];
export const SIZES = [];
6 changes: 0 additions & 6 deletions src/components/icon/icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import React, {
ReactElement,
SVGAttributes,
} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import { CommonProps, keysOf } from '../common';
Expand Down Expand Up @@ -396,11 +395,6 @@ export type EuiIconType = keyof typeof typeToPathMap;

export type IconType = EuiIconType | string | ReactElement;

export const IconPropType = PropTypes.oneOfType([
PropTypes.string,
PropTypes.node,
]);

const colorToClassMap = {
default: null,
primary: 'euiIcon--primary',
Expand Down
1 change: 0 additions & 1 deletion src/components/icon/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ export {
IconColor,
IconSize,
IconType,
IconPropType,
TYPES as ICON_TYPES,
SIZES as ICON_SIZES,
COLORS as ICON_COLORS,
Expand Down
20 changes: 20 additions & 0 deletions wiki/consuming.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,23 @@ ReactDOM.render(
### "Module build failed" or "Module parse failed: Unexpected token" error

If you get an error when importing a React component, you might need to configure Webpack's `resolve.mainFields` to `['webpack', 'browser', 'main']` to import the components from `lib` intead of `src`. See the [Webpack docs](https://webpack.js.org/configuration/resolve/#resolve-mainfields) for more info.

## Using the `test-env` build

EUI provides a separate babel-transformed and partially mocked commonjs build for testing environments in consuming projects. The output is identical to that of `lib/`, but has transformed async functions and dynamic import statements, and also applies some useful mocks. This build mainly targets Kibana's Jest environment, but may be helpful for testing environments in other projects.

### Mapping to the `test-env` directory

In Kibana's Jest configuration, the `moduleNameMapper` option is used to resolve standard EUI import statements with `test-env` aliases.

```js
moduleNameMapper: {
'@elastic/eui$': '<rootDir>/node_modules/@elastic/eui/test-env'
}
```

This eliminates the need to polyfill or transform the EUI build for an environment that otherwise has no need for such processing.

### Mocked component files

Besides babel transforms, the test environment build consumes mocked component files of the type `src/**/[name].testenv.*`. During the build, files of the type `src/**/[name].*` will be replaced by those with the `testenv` namespace. The purpose of this mocking is to further mitigate the impacts of time- and import-dependent rendering, and simplify environment output such as test snapshots. Information on creating mock component files can be found with [testing documentation](testing).
14 changes: 14 additions & 0 deletions wiki/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,17 @@ describe('YourComponent', () => {
});

```

## Writing mock component files

A component file can be mocked for snapshot simplification or to mitigate nondeterministic rendering in test environments. See [`src/components/icon`](../src/components/icon) for a example.

_Although mock component files are currently only used as part of consuming project test environments, the concept will soon be applied to EUI's own testing environment._

### Using the mock namespace

Component mocking relies on using the `[name].testenv.*` namespace for identification. The mocked module will replace the standard import in the `test-env` build. Both `index` files and individual component files can mocked.

### Mapping all module exports

The rendered output of a mocked component is at the author's discretion, however, all public exports from a module must be preserved in the mock file. Note that this does not apply to exported TypeScript types and interfaces, which will always be derived from the original component file.
10 changes: 10 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,16 @@
dependencies:
"@babel/helper-plugin-utils" "^7.8.3"

"@babel/plugin-transform-runtime@^7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.8.3.tgz#c0153bc0a5375ebc1f1591cb7eea223adea9f169"
integrity sha512-/vqUt5Yh+cgPZXXjmaG9NT8aVfThKk7G4OqkVhrXqwsC5soMn/qTCxs36rZ2QFhpfTJcjw4SNDIZ4RUb8OL4jQ==
dependencies:
"@babel/helper-module-imports" "^7.8.3"
"@babel/helper-plugin-utils" "^7.8.3"
resolve "^1.8.1"
semver "^5.5.1"

"@babel/plugin-transform-shorthand-properties@^7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.8.3.tgz#28545216e023a832d4d3a1185ed492bcfeac08c8"
Expand Down

0 comments on commit 034d76d

Please sign in to comment.