From 6eac83d25c8ed8b25c5702574bc827c4cd4b6dbf Mon Sep 17 00:00:00 2001 From: restrry Date: Mon, 28 Sep 2020 16:36:52 +0300 Subject: [PATCH 01/11] document ts project references --- docs/development/typescript.md | 54 ++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 docs/development/typescript.md diff --git a/docs/development/typescript.md b/docs/development/typescript.md new file mode 100644 index 0000000000000..a46aec9c3a3ac --- /dev/null +++ b/docs/development/typescript.md @@ -0,0 +1,54 @@ +# Typescript +Although this is not a requirement, we encourage if all new code is developed in [Typescript](https://www.typescriptlang.org/). + +- [Project references](#project-references) + - [Caveats](#caveats) + - [Prerequisitions](#prerequisitions) + - [Implementation](#implementation) + +## Project references +Kibana has crossed the 1.5m LoC mark. The current situation creates some scaling problems when the default out-of-the-box setup stops working. As a result, developers suffer from slow project compilation and IDE unresponsiveness. As a part of [Developer Experience project](https://github.com/elastic/kibana/projects/63), we are migrating our tooling to use built-in TypeScript features addressing the scaling problems - [project references](https://www.typescriptlang.org/docs/handbook/project-references.html) & [incremental buils](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#faster-subsequent-builds-with-the---incremental-flag). In a nutshell - instead of compiling the whole Kibana codebase at once, this setup enforces splitting the code base into independent projects that form a directed acyclic graph (DAG) that allows the TypeScript compiler(`tsc`) to apply several advanced optimizations: +- every project emits *public* interfaces in the form of `d.ts` type declaration +- created`d.ts` type declarations are used whenever a referenced project is imported in a depending project +- it makes it possible to determine which project needs rebuilding when the source code has changed to use a more aggressive caching strategy. +More details are available in the [official docs](https://www.typescriptlang.org/docs/handbook/project-references.html) + +### Caveats +This architecture imposes several limitations to which we must comply: +- projects cannot have circular dependencies. Even though the Kibana platform doesn't support circular dependencies between Kibana plugins, TypeScript does allow circular type imports between files. So in theory, you might face a problem when migrating to the TS project references so you will have to remove this circular dependency. +- a project must emit its type declaration. It's not always possible to generate a type declaration if the compiler cannot reference a type. There are two basic cases: +1. Your plugin exports a type inferring an internal type declared in Kibana codebase. In this case, you'll have to either export an internal type or to declare an exported type explicitly. +2. Your plugin exports something inferring a type from a 3rd party library that doesn't export this type. To fix the problem, you have to declare the exported type manually. + +### Prerequisitions +Since `tsc` doesn't support circular references, the migration order does matter. You can migrate your plugin only when all the plugin dependencies already have migrated. It creates the situation when low-level plugins (such as `data` or `kibana_react`) have to migrate first. + +### Implementation +- make sure all the plugins listed as dependencies in `kibana.json` file have migrated to TS project references. +- add `tsconfig.json` in the root folder of your plugin. +```json +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "composite": true, + "outDir": "./target/types", + "emitDeclarationOnly": true, + "declaration": true, + "declarationMap": true + }, + "include": [ + // add all the folders containg files to be compiled + ], + "references": [ + { "path": "../../core/tsconfig.json" }, + // add references to other TypeScript projects your plugin dependes on + ] +} +``` +If your plugin imports a file not listed in `include`, the build will fail with the next message `File ‘…’ is not listed within the file list of project …’. Projects must list all files or use an 'include' pattern.` +- build you plugin `./node_modules/.bin/tsc -b src/plugins/my_plugin`. Fix errors if `tsc` cannot generate type declarations for your project. +- make sure the `target/types` folder doesn’t contain files not belonging to your project. Otherwise, it means your plugin includes files from another project by mistake. +- add your project reference to `include` property of `tsconfig.refs.json` +- add your plugin to `include` property and plugin folder to `exclude` property of the `tsconfig.json` it used to belong to (for example, for `src/plugins/**` it's `tsconfig.json`; for `x-pack/plugins/**` it’s `x-pack/tsconfig.json`). +- list the reference to your newly created project in all the Kibana `tsconfig.json` files that could import your project: `tsconfig.json`, `test/tsconfig.json`, `x-pack/tsconfig.json`, `x-pack/test/tsconfig.json`. And in all the plugin-specific `tsconfig.refs.json` for dependent plugins. + - you can measure how your changes affect `tsc` compiler performance with `node --max-old-space-size=4096 ./node_modules/.bin/tsc -p tsconfig.json --extendedDiagnostics --noEmit`. Compare with **master** branch. From dc5a6a742f1d0b244ca49a7500ca2dd5f8293696 Mon Sep 17 00:00:00 2001 From: Mikhail Shustov Date: Wed, 30 Sep 2020 09:27:41 +0300 Subject: [PATCH 02/11] Apply suggestions from code review Co-authored-by: Josh Dover --- docs/development/typescript.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/development/typescript.md b/docs/development/typescript.md index a46aec9c3a3ac..aa6e3597cb05d 100644 --- a/docs/development/typescript.md +++ b/docs/development/typescript.md @@ -7,21 +7,23 @@ Although this is not a requirement, we encourage if all new code is developed in - [Implementation](#implementation) ## Project references -Kibana has crossed the 1.5m LoC mark. The current situation creates some scaling problems when the default out-of-the-box setup stops working. As a result, developers suffer from slow project compilation and IDE unresponsiveness. As a part of [Developer Experience project](https://github.com/elastic/kibana/projects/63), we are migrating our tooling to use built-in TypeScript features addressing the scaling problems - [project references](https://www.typescriptlang.org/docs/handbook/project-references.html) & [incremental buils](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#faster-subsequent-builds-with-the---incremental-flag). In a nutshell - instead of compiling the whole Kibana codebase at once, this setup enforces splitting the code base into independent projects that form a directed acyclic graph (DAG) that allows the TypeScript compiler(`tsc`) to apply several advanced optimizations: -- every project emits *public* interfaces in the form of `d.ts` type declaration -- created`d.ts` type declarations are used whenever a referenced project is imported in a depending project -- it makes it possible to determine which project needs rebuilding when the source code has changed to use a more aggressive caching strategy. +Kibana has crossed the 1.5m LoC mark. The current situation creates some scaling problems when the default out-of-the-box setup stops working. As a result, developers suffer from slow project compilation and IDE unresponsiveness. As a part of [Developer Experience project](https://github.com/elastic/kibana/projects/63), we are migrating our tooling to use built-in TypeScript features addressing the scaling problems - [project references](https://www.typescriptlang.org/docs/handbook/project-references.html) & [incremental builds](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#faster-subsequent-builds-with-the---incremental-flag). + +In a nutshell - instead of compiling the whole Kibana codebase at once, this setup enforces splitting the code base into independent projects that form a directed acyclic graph (DAG). This allows the TypeScript compiler (`tsc`) to apply several advanced optimizations: +- Every project emits *public* interfaces in the form of `d.ts` type declarations generated by the TypeScript compiler +- These generated `d.ts` type declarations are used whenever a referenced project is imported in a depending project +- This makes it possible to determine which project needs rebuilding when the source code has changed to use a more aggressive caching strategy. More details are available in the [official docs](https://www.typescriptlang.org/docs/handbook/project-references.html) ### Caveats This architecture imposes several limitations to which we must comply: -- projects cannot have circular dependencies. Even though the Kibana platform doesn't support circular dependencies between Kibana plugins, TypeScript does allow circular type imports between files. So in theory, you might face a problem when migrating to the TS project references so you will have to remove this circular dependency. -- a project must emit its type declaration. It's not always possible to generate a type declaration if the compiler cannot reference a type. There are two basic cases: +- Projects cannot have circular dependencies. Even though the Kibana platform doesn't support circular dependencies between Kibana plugins, TypeScript (and ES6 modules) does allow circular imports between files. So in theory, you may face a problem when migrating to the TS project references and you will have to resolve this circular dependency. +- A project must emit its type declaration. It's not always possible to generate a type declaration if the compiler cannot infer a type. There are two basic cases: 1. Your plugin exports a type inferring an internal type declared in Kibana codebase. In this case, you'll have to either export an internal type or to declare an exported type explicitly. 2. Your plugin exports something inferring a type from a 3rd party library that doesn't export this type. To fix the problem, you have to declare the exported type manually. ### Prerequisitions -Since `tsc` doesn't support circular references, the migration order does matter. You can migrate your plugin only when all the plugin dependencies already have migrated. It creates the situation when low-level plugins (such as `data` or `kibana_react`) have to migrate first. +Since `tsc` doesn't support circular project references, the migration order does matter. You can migrate your plugin only when all the plugin dependencies already have migrated. It creates a situation where commonly used plugins (such as `data` or `kibana_react`) have to migrate first. ### Implementation - make sure all the plugins listed as dependencies in `kibana.json` file have migrated to TS project references. From aeec0f399b23481235b86e8d20023e318a3123aa Mon Sep 17 00:00:00 2001 From: restrry Date: Wed, 30 Sep 2020 10:26:14 +0300 Subject: [PATCH 03/11] capitalize all the bullet points --- docs/development/typescript.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/development/typescript.md b/docs/development/typescript.md index aa6e3597cb05d..736199021f591 100644 --- a/docs/development/typescript.md +++ b/docs/development/typescript.md @@ -26,8 +26,8 @@ This architecture imposes several limitations to which we must comply: Since `tsc` doesn't support circular project references, the migration order does matter. You can migrate your plugin only when all the plugin dependencies already have migrated. It creates a situation where commonly used plugins (such as `data` or `kibana_react`) have to migrate first. ### Implementation -- make sure all the plugins listed as dependencies in `kibana.json` file have migrated to TS project references. -- add `tsconfig.json` in the root folder of your plugin. +- Make sure all the plugins listed as dependencies in `kibana.json` file have migrated to TS project references. +- Add `tsconfig.json` in the root folder of your plugin. ```json { "extends": "../../../tsconfig.base.json", @@ -48,9 +48,9 @@ Since `tsc` doesn't support circular project references, the migration order doe } ``` If your plugin imports a file not listed in `include`, the build will fail with the next message `File ‘…’ is not listed within the file list of project …’. Projects must list all files or use an 'include' pattern.` -- build you plugin `./node_modules/.bin/tsc -b src/plugins/my_plugin`. Fix errors if `tsc` cannot generate type declarations for your project. -- make sure the `target/types` folder doesn’t contain files not belonging to your project. Otherwise, it means your plugin includes files from another project by mistake. -- add your project reference to `include` property of `tsconfig.refs.json` -- add your plugin to `include` property and plugin folder to `exclude` property of the `tsconfig.json` it used to belong to (for example, for `src/plugins/**` it's `tsconfig.json`; for `x-pack/plugins/**` it’s `x-pack/tsconfig.json`). -- list the reference to your newly created project in all the Kibana `tsconfig.json` files that could import your project: `tsconfig.json`, `test/tsconfig.json`, `x-pack/tsconfig.json`, `x-pack/test/tsconfig.json`. And in all the plugin-specific `tsconfig.refs.json` for dependent plugins. - - you can measure how your changes affect `tsc` compiler performance with `node --max-old-space-size=4096 ./node_modules/.bin/tsc -p tsconfig.json --extendedDiagnostics --noEmit`. Compare with **master** branch. +- Build you plugin `./node_modules/.bin/tsc -b src/plugins/my_plugin`. Fix errors if `tsc` cannot generate type declarations for your project. +- Make sure the `target/types` folder doesn’t contain files not belonging to your project. Otherwise, it means your plugin includes files from another project by mistake. +- Add your project reference to `include` property of `tsconfig.refs.json` +- Add your plugin to `include` property and plugin folder to `exclude` property of the `tsconfig.json` it used to belong to (for example, for `src/plugins/**` it's `tsconfig.json`; for `x-pack/plugins/**` it’s `x-pack/tsconfig.json`). +- List the reference to your newly created project in all the Kibana `tsconfig.json` files that could import your project: `tsconfig.json`, `test/tsconfig.json`, `x-pack/tsconfig.json`, `x-pack/test/tsconfig.json`. And in all the plugin-specific `tsconfig.refs.json` for dependent plugins. + - You can measure how your changes affect `tsc` compiler performance with `node --max-old-space-size=4096 ./node_modules/.bin/tsc -p tsconfig.json --extendedDiagnostics --noEmit`. Compare with **master** branch. From 910cd09e72a20fbdfa77265fb263cc277e102c7b Mon Sep 17 00:00:00 2001 From: restrry Date: Mon, 5 Oct 2020 14:51:47 +0300 Subject: [PATCH 04/11] address @rudolf comments --- docs/development/typescript.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/development/typescript.md b/docs/development/typescript.md index 736199021f591..e3a53d6f0697e 100644 --- a/docs/development/typescript.md +++ b/docs/development/typescript.md @@ -26,8 +26,8 @@ This architecture imposes several limitations to which we must comply: Since `tsc` doesn't support circular project references, the migration order does matter. You can migrate your plugin only when all the plugin dependencies already have migrated. It creates a situation where commonly used plugins (such as `data` or `kibana_react`) have to migrate first. ### Implementation -- Make sure all the plugins listed as dependencies in `kibana.json` file have migrated to TS project references. -- Add `tsconfig.json` in the root folder of your plugin. +1. Make sure all the plugins listed as dependencies in `kibana.json` file have migrated to TS project references. +1. Add `tsconfig.json` in the root folder of your plugin. ```json { "extends": "../../../tsconfig.base.json", @@ -48,9 +48,9 @@ Since `tsc` doesn't support circular project references, the migration order doe } ``` If your plugin imports a file not listed in `include`, the build will fail with the next message `File ‘…’ is not listed within the file list of project …’. Projects must list all files or use an 'include' pattern.` -- Build you plugin `./node_modules/.bin/tsc -b src/plugins/my_plugin`. Fix errors if `tsc` cannot generate type declarations for your project. -- Make sure the `target/types` folder doesn’t contain files not belonging to your project. Otherwise, it means your plugin includes files from another project by mistake. -- Add your project reference to `include` property of `tsconfig.refs.json` -- Add your plugin to `include` property and plugin folder to `exclude` property of the `tsconfig.json` it used to belong to (for example, for `src/plugins/**` it's `tsconfig.json`; for `x-pack/plugins/**` it’s `x-pack/tsconfig.json`). -- List the reference to your newly created project in all the Kibana `tsconfig.json` files that could import your project: `tsconfig.json`, `test/tsconfig.json`, `x-pack/tsconfig.json`, `x-pack/test/tsconfig.json`. And in all the plugin-specific `tsconfig.refs.json` for dependent plugins. - - You can measure how your changes affect `tsc` compiler performance with `node --max-old-space-size=4096 ./node_modules/.bin/tsc -p tsconfig.json --extendedDiagnostics --noEmit`. Compare with **master** branch. +1. Build you plugin `./node_modules/.bin/tsc -b src/plugins/my_plugin`. Fix errors if `tsc` cannot generate type declarations for your project. +1. Make sure the `target/types` folder doesn’t contain files not belonging to your project. Otherwise, it means your plugin includes files from another project by mistake. +1. Add your project reference to `references` property of `tsconfig.refs.json` +1. Add your plugin to `references` property and plugin folder to `exclude` property of the `tsconfig.json` it used to belong to (for example, for `src/plugins/**` it's `tsconfig.json`; for `x-pack/plugins/**` it’s `x-pack/tsconfig.json`). +1. List the reference to your newly created project in all the Kibana `tsconfig.json` files that could import your project: `tsconfig.json`, `test/tsconfig.json`, `x-pack/tsconfig.json`, `x-pack/test/tsconfig.json`. And in all the plugin-specific `tsconfig.refs.json` for dependent plugins. +1. You can measure how your changes affect `tsc` compiler performance with `node --max-old-space-size=4096 ./node_modules/.bin/tsc -p tsconfig.json --extendedDiagnostics --noEmit`. Compare with **master** branch. From 225ec421300a41efa1e8d2746aedbc3de4ef9713 Mon Sep 17 00:00:00 2001 From: restrry Date: Mon, 5 Oct 2020 15:35:07 +0300 Subject: [PATCH 05/11] add a reference to example --- docs/development/typescript.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/development/typescript.md b/docs/development/typescript.md index e3a53d6f0697e..eec4d5d50fca8 100644 --- a/docs/development/typescript.md +++ b/docs/development/typescript.md @@ -27,7 +27,7 @@ Since `tsc` doesn't support circular project references, the migration order doe ### Implementation 1. Make sure all the plugins listed as dependencies in `kibana.json` file have migrated to TS project references. -1. Add `tsconfig.json` in the root folder of your plugin. +2. Add `tsconfig.json` in the root folder of your plugin. ```json { "extends": "../../../tsconfig.base.json", @@ -48,9 +48,10 @@ Since `tsc` doesn't support circular project references, the migration order doe } ``` If your plugin imports a file not listed in `include`, the build will fail with the next message `File ‘…’ is not listed within the file list of project …’. Projects must list all files or use an 'include' pattern.` -1. Build you plugin `./node_modules/.bin/tsc -b src/plugins/my_plugin`. Fix errors if `tsc` cannot generate type declarations for your project. -1. Make sure the `target/types` folder doesn’t contain files not belonging to your project. Otherwise, it means your plugin includes files from another project by mistake. -1. Add your project reference to `references` property of `tsconfig.refs.json` -1. Add your plugin to `references` property and plugin folder to `exclude` property of the `tsconfig.json` it used to belong to (for example, for `src/plugins/**` it's `tsconfig.json`; for `x-pack/plugins/**` it’s `x-pack/tsconfig.json`). -1. List the reference to your newly created project in all the Kibana `tsconfig.json` files that could import your project: `tsconfig.json`, `test/tsconfig.json`, `x-pack/tsconfig.json`, `x-pack/test/tsconfig.json`. And in all the plugin-specific `tsconfig.refs.json` for dependent plugins. -1. You can measure how your changes affect `tsc` compiler performance with `node --max-old-space-size=4096 ./node_modules/.bin/tsc -p tsconfig.json --extendedDiagnostics --noEmit`. Compare with **master** branch. +3. Build you plugin `./node_modules/.bin/tsc -b src/plugins/my_plugin`. Fix errors if `tsc` cannot generate type declarations for your project. +4. Add your project reference to `references` property of `tsconfig.refs.json` +5. Add your plugin to `references` property and plugin folder to `exclude` property of the `tsconfig.json` it used to belong to (for example, for `src/plugins/**` it's `tsconfig.json`; for `x-pack/plugins/**` it’s `x-pack/tsconfig.json`). +6. List the reference to your newly created project in all the Kibana `tsconfig.json` files that could import your project: `tsconfig.json`, `test/tsconfig.json`, `x-pack/tsconfig.json`, `x-pack/test/tsconfig.json`. And in all the plugin-specific `tsconfig.refs.json` for dependent plugins. +7. You can measure how your changes affect `tsc` compiler performance with `node --max-old-space-size=4096 ./node_modules/.bin/tsc -p tsconfig.json --extendedDiagnostics --noEmit`. Compare with **master** branch. + +You can use https://github.com/elastic/kibana/pull/79446 as an example. From da5d86e5c99044ea16b81c530bc6f1f82b229f6b Mon Sep 17 00:00:00 2001 From: restrry Date: Mon, 5 Oct 2020 15:36:20 +0300 Subject: [PATCH 06/11] fix identation --- docs/development/typescript.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/development/typescript.md b/docs/development/typescript.md index eec4d5d50fca8..3989f3580fa7c 100644 --- a/docs/development/typescript.md +++ b/docs/development/typescript.md @@ -48,6 +48,7 @@ Since `tsc` doesn't support circular project references, the migration order doe } ``` If your plugin imports a file not listed in `include`, the build will fail with the next message `File ‘…’ is not listed within the file list of project …’. Projects must list all files or use an 'include' pattern.` + 3. Build you plugin `./node_modules/.bin/tsc -b src/plugins/my_plugin`. Fix errors if `tsc` cannot generate type declarations for your project. 4. Add your project reference to `references` property of `tsconfig.refs.json` 5. Add your plugin to `references` property and plugin folder to `exclude` property of the `tsconfig.json` it used to belong to (for example, for `src/plugins/**` it's `tsconfig.json`; for `x-pack/plugins/**` it’s `x-pack/tsconfig.json`). From e786249504affb2bbc79bd600f01596b4052807a Mon Sep 17 00:00:00 2001 From: restrry Date: Mon, 5 Oct 2020 17:20:02 +0300 Subject: [PATCH 07/11] convert into asciidoc --- docs/developer/best-practices/index.asciidoc | 3 ++ .../best-practices/typescript.asciidoc} | 32 +++++++++++-------- 2 files changed, 21 insertions(+), 14 deletions(-) rename docs/{development/typescript.md => developer/best-practices/typescript.asciidoc} (76%) diff --git a/docs/developer/best-practices/index.asciidoc b/docs/developer/best-practices/index.asciidoc index 13ea010d0aa96..42b379e606898 100644 --- a/docs/developer/best-practices/index.asciidoc +++ b/docs/developer/best-practices/index.asciidoc @@ -138,9 +138,12 @@ Review: * <> * <> * <> +* <> include::navigation.asciidoc[leveloffset=+1] include::stability.asciidoc[leveloffset=+1] include::security.asciidoc[leveloffset=+1] + +include::typescript.asciidoc[leveloffset=+1] diff --git a/docs/development/typescript.md b/docs/developer/best-practices/typescript.asciidoc similarity index 76% rename from docs/development/typescript.md rename to docs/developer/best-practices/typescript.asciidoc index 3989f3580fa7c..c676900ad1ea6 100644 --- a/docs/development/typescript.md +++ b/docs/developer/best-practices/typescript.asciidoc @@ -1,31 +1,35 @@ -# Typescript -Although this is not a requirement, we encourage if all new code is developed in [Typescript](https://www.typescriptlang.org/). +[[typescript]] +== Typescript -- [Project references](#project-references) - - [Caveats](#caveats) - - [Prerequisitions](#prerequisitions) - - [Implementation](#implementation) +Although this is not a requirement, we encourage if all new code is developed in https://www.typescriptlang.org/[Typescript]. -## Project references -Kibana has crossed the 1.5m LoC mark. The current situation creates some scaling problems when the default out-of-the-box setup stops working. As a result, developers suffer from slow project compilation and IDE unresponsiveness. As a part of [Developer Experience project](https://github.com/elastic/kibana/projects/63), we are migrating our tooling to use built-in TypeScript features addressing the scaling problems - [project references](https://www.typescriptlang.org/docs/handbook/project-references.html) & [incremental builds](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#faster-subsequent-builds-with-the---incremental-flag). +<> + +[[project-references]] +== Project references +Kibana has crossed the 2m LoC mark. The current situation creates some scaling problems when the default out-of-the-box setup stops working. As a result, developers suffer from slow project compilation and IDE unresponsiveness. As a part of https://github.com/elastic/kibana/projects/63[Developer Experience project], we are migrating our tooling to use built-in TypeScript features addressing the scaling problems - https://www.typescriptlang.org/docs/handbook/project-references.html[project references] & https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#faster-subsequent-builds-with-the---incremental-flag[incremental builds] In a nutshell - instead of compiling the whole Kibana codebase at once, this setup enforces splitting the code base into independent projects that form a directed acyclic graph (DAG). This allows the TypeScript compiler (`tsc`) to apply several advanced optimizations: -- Every project emits *public* interfaces in the form of `d.ts` type declarations generated by the TypeScript compiler + +- Every project emits `public` interfaces in the form of `d.ts` type declarations generated by the TypeScript compiler - These generated `d.ts` type declarations are used whenever a referenced project is imported in a depending project - This makes it possible to determine which project needs rebuilding when the source code has changed to use a more aggressive caching strategy. -More details are available in the [official docs](https://www.typescriptlang.org/docs/handbook/project-references.html) -### Caveats +More details are available in the https://www.typescriptlang.org/docs/handbook/project-references.html[official docs] + +=== Caveats This architecture imposes several limitations to which we must comply: + - Projects cannot have circular dependencies. Even though the Kibana platform doesn't support circular dependencies between Kibana plugins, TypeScript (and ES6 modules) does allow circular imports between files. So in theory, you may face a problem when migrating to the TS project references and you will have to resolve this circular dependency. - A project must emit its type declaration. It's not always possible to generate a type declaration if the compiler cannot infer a type. There are two basic cases: + 1. Your plugin exports a type inferring an internal type declared in Kibana codebase. In this case, you'll have to either export an internal type or to declare an exported type explicitly. 2. Your plugin exports something inferring a type from a 3rd party library that doesn't export this type. To fix the problem, you have to declare the exported type manually. -### Prerequisitions +=== Prerequisites Since `tsc` doesn't support circular project references, the migration order does matter. You can migrate your plugin only when all the plugin dependencies already have migrated. It creates a situation where commonly used plugins (such as `data` or `kibana_react`) have to migrate first. -### Implementation +=== Implementation 1. Make sure all the plugins listed as dependencies in `kibana.json` file have migrated to TS project references. 2. Add `tsconfig.json` in the root folder of your plugin. ```json @@ -53,6 +57,6 @@ If your plugin imports a file not listed in `include`, the build will fail with 4. Add your project reference to `references` property of `tsconfig.refs.json` 5. Add your plugin to `references` property and plugin folder to `exclude` property of the `tsconfig.json` it used to belong to (for example, for `src/plugins/**` it's `tsconfig.json`; for `x-pack/plugins/**` it’s `x-pack/tsconfig.json`). 6. List the reference to your newly created project in all the Kibana `tsconfig.json` files that could import your project: `tsconfig.json`, `test/tsconfig.json`, `x-pack/tsconfig.json`, `x-pack/test/tsconfig.json`. And in all the plugin-specific `tsconfig.refs.json` for dependent plugins. -7. You can measure how your changes affect `tsc` compiler performance with `node --max-old-space-size=4096 ./node_modules/.bin/tsc -p tsconfig.json --extendedDiagnostics --noEmit`. Compare with **master** branch. +7. You can measure how your changes affect `tsc` compiler performance with `node --max-old-space-size=4096 ./node_modules/.bin/tsc -p tsconfig.json --extendedDiagnostics --noEmit`. Compare with `master` branch. You can use https://github.com/elastic/kibana/pull/79446 as an example. From aa38635d04db55b9b2aef4089442fffa6b8964b7 Mon Sep 17 00:00:00 2001 From: restrry Date: Mon, 5 Oct 2020 17:26:48 +0300 Subject: [PATCH 08/11] fix numeration --- docs/developer/best-practices/typescript.asciidoc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/developer/best-practices/typescript.asciidoc b/docs/developer/best-practices/typescript.asciidoc index c676900ad1ea6..518812ae801ac 100644 --- a/docs/developer/best-practices/typescript.asciidoc +++ b/docs/developer/best-practices/typescript.asciidoc @@ -31,7 +31,7 @@ Since `tsc` doesn't support circular project references, the migration order doe === Implementation 1. Make sure all the plugins listed as dependencies in `kibana.json` file have migrated to TS project references. -2. Add `tsconfig.json` in the root folder of your plugin. +1. Add `tsconfig.json` in the root folder of your plugin. ```json { "extends": "../../../tsconfig.base.json", @@ -52,11 +52,11 @@ Since `tsc` doesn't support circular project references, the migration order doe } ``` If your plugin imports a file not listed in `include`, the build will fail with the next message `File ‘…’ is not listed within the file list of project …’. Projects must list all files or use an 'include' pattern.` - -3. Build you plugin `./node_modules/.bin/tsc -b src/plugins/my_plugin`. Fix errors if `tsc` cannot generate type declarations for your project. -4. Add your project reference to `references` property of `tsconfig.refs.json` -5. Add your plugin to `references` property and plugin folder to `exclude` property of the `tsconfig.json` it used to belong to (for example, for `src/plugins/**` it's `tsconfig.json`; for `x-pack/plugins/**` it’s `x-pack/tsconfig.json`). -6. List the reference to your newly created project in all the Kibana `tsconfig.json` files that could import your project: `tsconfig.json`, `test/tsconfig.json`, `x-pack/tsconfig.json`, `x-pack/test/tsconfig.json`. And in all the plugin-specific `tsconfig.refs.json` for dependent plugins. -7. You can measure how your changes affect `tsc` compiler performance with `node --max-old-space-size=4096 ./node_modules/.bin/tsc -p tsconfig.json --extendedDiagnostics --noEmit`. Compare with `master` branch. +[start=3] +1. Build you plugin `./node_modules/.bin/tsc -b src/plugins/my_plugin`. Fix errors if `tsc` cannot generate type declarations for your project. +1. Add your project reference to `references` property of `tsconfig.refs.json` +1. Add your plugin to `references` property and plugin folder to `exclude` property of the `tsconfig.json` it used to belong to (for example, for `src/plugins/**` it's `tsconfig.json`; for `x-pack/plugins/**` it’s `x-pack/tsconfig.json`). +1. List the reference to your newly created project in all the Kibana `tsconfig.json` files that could import your project: `tsconfig.json`, `test/tsconfig.json`, `x-pack/tsconfig.json`, `x-pack/test/tsconfig.json`. And in all the plugin-specific `tsconfig.refs.json` for dependent plugins. +1. You can measure how your changes affect `tsc` compiler performance with `node --max-old-space-size=4096 ./node_modules/.bin/tsc -p tsconfig.json --extendedDiagnostics --noEmit`. Compare with `master` branch. You can use https://github.com/elastic/kibana/pull/79446 as an example. From 536b099815b911cfeafe09e94a3fcc1843928990 Mon Sep 17 00:00:00 2001 From: restrry Date: Mon, 5 Oct 2020 17:59:13 +0300 Subject: [PATCH 09/11] fix asciidoctor failures --- docs/developer/index.asciidoc | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/developer/index.asciidoc b/docs/developer/index.asciidoc index 5f032a3952173..9e349a38557f2 100644 --- a/docs/developer/index.asciidoc +++ b/docs/developer/index.asciidoc @@ -1,7 +1,6 @@ [[development]] = Developer guide -[partintro] -- Contributing to {kib} can be daunting at first, but it doesn't have to be. The following sections should get you up and running in no time. If you have any problems, file an issue in the https://github.com/elastic/kibana/issues[Kibana repo]. From abbe6eb7c0f6f352c9a052b100622462d129b15f Mon Sep 17 00:00:00 2001 From: restrry Date: Mon, 5 Oct 2020 18:00:04 +0300 Subject: [PATCH 10/11] cleanup typescript.asciidoc --- .../best-practices/typescript.asciidoc | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/docs/developer/best-practices/typescript.asciidoc b/docs/developer/best-practices/typescript.asciidoc index 518812ae801ac..30cb2a0ee6803 100644 --- a/docs/developer/best-practices/typescript.asciidoc +++ b/docs/developer/best-practices/typescript.asciidoc @@ -3,10 +3,8 @@ Although this is not a requirement, we encourage if all new code is developed in https://www.typescriptlang.org/[Typescript]. -<> - -[[project-references]] -== Project references +[discrete] +=== Project references Kibana has crossed the 2m LoC mark. The current situation creates some scaling problems when the default out-of-the-box setup stops working. As a result, developers suffer from slow project compilation and IDE unresponsiveness. As a part of https://github.com/elastic/kibana/projects/63[Developer Experience project], we are migrating our tooling to use built-in TypeScript features addressing the scaling problems - https://www.typescriptlang.org/docs/handbook/project-references.html[project references] & https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#faster-subsequent-builds-with-the---incremental-flag[incremental builds] In a nutshell - instead of compiling the whole Kibana codebase at once, this setup enforces splitting the code base into independent projects that form a directed acyclic graph (DAG). This allows the TypeScript compiler (`tsc`) to apply several advanced optimizations: @@ -17,7 +15,8 @@ In a nutshell - instead of compiling the whole Kibana codebase at once, this set More details are available in the https://www.typescriptlang.org/docs/handbook/project-references.html[official docs] -=== Caveats +[discrete] +==== Caveats This architecture imposes several limitations to which we must comply: - Projects cannot have circular dependencies. Even though the Kibana platform doesn't support circular dependencies between Kibana plugins, TypeScript (and ES6 modules) does allow circular imports between files. So in theory, you may face a problem when migrating to the TS project references and you will have to resolve this circular dependency. @@ -26,13 +25,16 @@ This architecture imposes several limitations to which we must comply: 1. Your plugin exports a type inferring an internal type declared in Kibana codebase. In this case, you'll have to either export an internal type or to declare an exported type explicitly. 2. Your plugin exports something inferring a type from a 3rd party library that doesn't export this type. To fix the problem, you have to declare the exported type manually. -=== Prerequisites +[discrete] +==== Prerequisites Since `tsc` doesn't support circular project references, the migration order does matter. You can migrate your plugin only when all the plugin dependencies already have migrated. It creates a situation where commonly used plugins (such as `data` or `kibana_react`) have to migrate first. -=== Implementation +[discrete] +==== Implementation 1. Make sure all the plugins listed as dependencies in `kibana.json` file have migrated to TS project references. 1. Add `tsconfig.json` in the root folder of your plugin. -```json +[source,json] +---- { "extends": "../../../tsconfig.base.json", "compilerOptions": { @@ -50,7 +52,7 @@ Since `tsc` doesn't support circular project references, the migration order doe // add references to other TypeScript projects your plugin dependes on ] } -``` +---- If your plugin imports a file not listed in `include`, the build will fail with the next message `File ‘…’ is not listed within the file list of project …’. Projects must list all files or use an 'include' pattern.` [start=3] 1. Build you plugin `./node_modules/.bin/tsc -b src/plugins/my_plugin`. Fix errors if `tsc` cannot generate type declarations for your project. From 6efc968f8595599d5560d7580f9de812137b7ab9 Mon Sep 17 00:00:00 2001 From: restrry Date: Mon, 5 Oct 2020 18:36:53 +0300 Subject: [PATCH 11/11] back to unordered list. asciidoctor fails validation --- .../developer/best-practices/typescript.asciidoc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/developer/best-practices/typescript.asciidoc b/docs/developer/best-practices/typescript.asciidoc index 30cb2a0ee6803..3321aae3c0994 100644 --- a/docs/developer/best-practices/typescript.asciidoc +++ b/docs/developer/best-practices/typescript.asciidoc @@ -31,8 +31,8 @@ Since `tsc` doesn't support circular project references, the migration order doe [discrete] ==== Implementation -1. Make sure all the plugins listed as dependencies in `kibana.json` file have migrated to TS project references. -1. Add `tsconfig.json` in the root folder of your plugin. +- Make sure all the plugins listed as dependencies in `kibana.json` file have migrated to TS project references. +- Add `tsconfig.json` in the root folder of your plugin. [source,json] ---- { @@ -54,11 +54,11 @@ Since `tsc` doesn't support circular project references, the migration order doe } ---- If your plugin imports a file not listed in `include`, the build will fail with the next message `File ‘…’ is not listed within the file list of project …’. Projects must list all files or use an 'include' pattern.` -[start=3] -1. Build you plugin `./node_modules/.bin/tsc -b src/plugins/my_plugin`. Fix errors if `tsc` cannot generate type declarations for your project. -1. Add your project reference to `references` property of `tsconfig.refs.json` -1. Add your plugin to `references` property and plugin folder to `exclude` property of the `tsconfig.json` it used to belong to (for example, for `src/plugins/**` it's `tsconfig.json`; for `x-pack/plugins/**` it’s `x-pack/tsconfig.json`). -1. List the reference to your newly created project in all the Kibana `tsconfig.json` files that could import your project: `tsconfig.json`, `test/tsconfig.json`, `x-pack/tsconfig.json`, `x-pack/test/tsconfig.json`. And in all the plugin-specific `tsconfig.refs.json` for dependent plugins. -1. You can measure how your changes affect `tsc` compiler performance with `node --max-old-space-size=4096 ./node_modules/.bin/tsc -p tsconfig.json --extendedDiagnostics --noEmit`. Compare with `master` branch. + +- Build you plugin `./node_modules/.bin/tsc -b src/plugins/my_plugin`. Fix errors if `tsc` cannot generate type declarations for your project. +- Add your project reference to `references` property of `tsconfig.refs.json` +- Add your plugin to `references` property and plugin folder to `exclude` property of the `tsconfig.json` it used to belong to (for example, for `src/plugins/**` it's `tsconfig.json`; for `x-pack/plugins/**` it’s `x-pack/tsconfig.json`). +- List the reference to your newly created project in all the Kibana `tsconfig.json` files that could import your project: `tsconfig.json`, `test/tsconfig.json`, `x-pack/tsconfig.json`, `x-pack/test/tsconfig.json`. And in all the plugin-specific `tsconfig.refs.json` for dependent plugins. +- You can measure how your changes affect `tsc` compiler performance with `node --max-old-space-size=4096 ./node_modules/.bin/tsc -p tsconfig.json --extendedDiagnostics --noEmit`. Compare with `master` branch. You can use https://github.com/elastic/kibana/pull/79446 as an example.