kibana/packages/kbn-pm
Tiago Costa 6c62c686cf
chore(NA): upgrade to lodash@4 (#69868)
* chore(NA): upgrade oss to lodash4

chore(NA): migrate cli, cli_plugin, cli_keystore,  dev, test_utils and apm src script to lodash4

chore(NA): missing file for cli plugin

chore(NA): add src core

chore(NA): es archiver and fixtures

chore(NA): try to fix functional test failure

chore(NA): migrate src/legacy entirely to lodash4 except src/legacy/core_plugins

chore(NA): move legacy core plugins to lodash4

chore(NA): upgrade optimize to lodash4

chore(NA): upgrade to lodash4 on advanced_settings, charts, console and dashboard

chore(NA): migrate to lodash4 on dev_tools, discover, embeddable, es_ui)shared, expressions, home plugins

chore(NA): upgrade data plugin to lodash4

chore(NA): upgrade usage_collection, ui_actions, tile_map, telemtry, share, saved_objects, saved_objects_management, region_map and navigation to lodash4

chore(NA): missing data upgrades to lodash4

Revert "chore(NA): upgrade usage_collection, ui_actions, tile_map, telemtry, share, saved_objects, saved_objects_management, region_map and navigation to lodash4"

This reverts commit 137055c5fed2fc52bb26547e0bc1ad2e3d4fe309.

Revert "Revert "chore(NA): upgrade usage_collection, ui_actions, tile_map, telemtry, share, saved_objects, saved_objects_management, region_map and navigation to lodash4""

This reverts commit f7e73688782998513d9fb6d7e8f0765e9beb28d1.

Revert "chore(NA): missing data upgrades to lodash4"

This reverts commit 92b85bf947a89bfc70cc4052738a6b2128ffb076.

Revert "chore(NA): upgrade data plugin to lodash4"

This reverts commit 88fdb075ee1e26c4ac979b6681d8a2b002df74c6.

chore(NA): upgrade idx_pattern_mgt, input_control_vis, inspector, kbn_legacy, kbn_react, kbn_usage_collections, kbn_utils, management and maps_legacy to lodash4

chore(NA): map src plugin data to lodash3

chore(NA): missing lodash.clonedeep dep

chore(NA): change packages kbn-config-schema deps

chore(NA): update renovate config

chore(NA): upgrade vis_type plugins to lodash4

chore(NA): move vis_type_vislib to lodash3

chore(NA): update visualizations and visualize to lodash4

chore(NA): remove lodash 3 types from src and move test to lodash4

chore(NA): move home, usage_collection and management to lodash 3

Revert "chore(NA): move home, usage_collection and management to lodash 3"

This reverts commit f86e8585f02d21550746569af54215b076a79a3d.

chore(NA): move kibana_legacy, saved_objects saved_objects_management into lodash3

chore(NA): update x-pack test to mock lodash4

Revert "chore(NA): move kibana_legacy, saved_objects saved_objects_management into lodash3"

This reverts commit 2d10fe450533e1b36db21d99cfae3ce996a244e0.

* chore(NA): move x-pack and packages to lodash 4

* chore(NA): remove mention to lodash from main package.json

* chore(NA): remove helper alias for lodash4 and make it the default lodash

* chore(NA): fix last failing types in the repo

* chore(NA): fix public api

* chore(NA): fix types for agg_row.tsx

* chore(NA): fix increment of optimizer modules in the rollup plugin

* chore(NA): migrate `src/core/public/http/fetch.ts` (#5)

* omit undefined query props

* just remove merge usage

* fix types

* chore(NA): fixes for feedback from apm team

* chore(NA): recover old behaviour on apm LoadingIndeicatorContext.tsx

* chore(NA): fixes for feedback from watson

* Platform lodash4 tweaks (#6)

* chore(NA): fix types and behaviour on src/core/server/elasticsearch/errors.ts

* Canvas fixes for lodash upgrade

* [APM] Adds unit test for APM service maps transform (#7)

* Adds a snapshot unit test for getConnections and rearranges some code to make testing easier

* reverts `ArrayList` back to `String[]` in the painless script within `fetch_service_paths_from_trace_ids.ts`

* chore(NA): update yarn.lock

* chore(NA): remove any and use a real type for alerts task runner

Co-authored-by: Gidi Meir Morris <github@gidi.io>

* chore(NA): used named import for triggers_actions_ui file

* chore(NA): fix eslint

* chore(NA): fix types

* Delete most uptime lodash references.

* Simplify. Clean up types.

* [Uptime] Delete most uptime lodash references (#8)

* Delete most uptime lodash references.

* Simplify. Clean up types.

* chore(NA): add eslint rule to avoid using lodash3

* chore(NA): apply changes on feedback from es-ui team

* fix some types (#9)

* Clean up some expressions types.

* chore(NA): missing ts-expect-error statements

* Upgrade lodash 4 vislib (#11)

* replace lodash 3 with lodash 4 on vislib plugin

* Further changes

* further replacement of lodash3 to 4

* further work on upgrading to lodash 4

* final changes to update lodash

* chore(NA): upgrade data plugin to lodash4

chore(NA): upgrade data plugin public to lodash4

chore(NA): fix typecheck task

chore(NA): fix agg_config with hasIn

chore(NA): assign to assignIn and has to hasIn

chore(NA): upgrade data plugin server to lodash4

chore(NA): new signature for core api

fix(NA): match behaviour between lodash3 and lodash4 for set in search_source

* chore(NA): remove lodash3 completely from the repo

* chore(NA): fix x-pack/test/api_integration/apis/metrics_ui/snapshot.ts missing content

* chore(NA): fix lodash usage on apm

* chore(NA): fix typecheck for maps

* Patch lodash template (#12)

* Applying changes from https://github.com/elastic/kibana/pull/64985

* Using isIterateeCall, because it seems less brittle

* Also patching `lodash/template` and `lodash/fp/template`

* Reorganizing some files...

* Revising comment

* Ends up `_` is a function also... I hate JavaScript

Co-authored-by: Pierre Gayvallet <pierre.gayvallet@gmail.com>
Co-authored-by: Josh Dover <me@joshdover.com>
Co-authored-by: Clint Andrew Hall <clint.hall@elastic.co>
Co-authored-by: Oliver Gupte <ogupte@users.noreply.github.com>
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
Co-authored-by: Gidi Meir Morris <github@gidi.io>
Co-authored-by: Justin Kambic <justin.kambic@elastic.co>
Co-authored-by: Stratoula Kalafateli <stratoula1@gmail.com>
Co-authored-by: Luke Elmers <luke.elmers@elastic.co>
Co-authored-by: Brandon Kobel <brandon.kobel@gmail.com>
Co-authored-by: kobelb <brandon.kobel@elastic.co>
2020-07-03 01:30:13 +01:00
..
dist Fix typo in bootstrap command (#69976) 2020-06-30 15:55:15 +02:00
src chore(NA): upgrade to lodash@4 (#69868) 2020-07-03 01:30:13 +01:00
.babelrc Migration to Babel7 and @babel/preset-typescript (#33093) 2019-03-26 20:44:03 +00:00
cli.js Apache 2.0 license headers (#19383) 2018-05-28 20:06:30 -07:00
package.json chore(NA): upgrade to lodash@4 (#69868) 2020-07-03 01:30:13 +01:00
README.md Remove outdated documentation referencing a local/vendored version of yarn. The reliance on a local version of yarn was removed by #17741 (#24014) 2019-06-27 17:33:20 -07:00
tsconfig.json [kbn/pm] add caching to bootstrap (#53622) 2020-01-03 09:35:38 -07:00
webpack.config.js Update dependency write-pkg to v4 (#43226) 2019-08-23 13:50:07 -07:00
yarn.lock Add lockfile symlinks (#55440) 2020-01-27 11:38:20 -05:00

@kbn/pm — The Kibana project management tool

@kbn/pm is a project management tool inspired by Lerna, which enables sharing code between Kibana and Kibana plugins.

To run @kbn/pm, go to Kibana root and run yarn kbn.

Why @kbn/pm?

Long-term we want to get rid of Webpack from production (basically, it's causing a lot of problems, using a lot of memory and adding a lot of complexity). Ideally we want each plugin to build its own separate production bundles for both server and UI. To get there all Kibana plugins (including x-pack) need to be able to build their production bundles separately from Kibana, which means they need to be able to depend on code from Kibana without import-ing random files directly from the Kibana source code.

From a plugin perspective there are two different types of Kibana dependencies: runtime and static dependencies. Runtime dependencies are things that are instantiated at runtime and that are injected into the plugin, for example config and elasticsearch clients. Static dependencies are those dependencies that we want to import. eslint-config-kibana is one example of this, and it's actually needed because eslint requires it to be a separate package. But we also have dependencies like datemath, flot, eui and others that we control, but where we want to import them in plugins instead of injecting them (because injecting them would be painful to work with). (Btw, these examples aren't necessarily a part of the Kibana repo today, they are just meant as examples of code that we might at some point want to include in the repo while having them be importable in Kibana plugins like any other npm package)

Another reason we need static dependencies is that we're starting to introduce TypeScript into Kibana, and to work nicely with TypeScript across plugins we need to be able to statically import dependencies. We have for example built an observable library for Kibana in TypeScript and we need to expose both the functionality and the TypeScript types to plugins (so other plugins built with TypeScript can depend on the types for the lib).

However, even though we have multiple packages we don't necessarily want to npm publish them. The ideal solution for us is being able to work on code locally in the Kibana repo and have a nice workflow that doesn't require publishing, but where we still get the value of having "packages" that are available to plugins, without these plugins having to import files directly from the Kibana folder.

Basically, we just want to be able to share "static code" (aka being able to import) between Kibana and Kibana plugins. To get there we need tooling.

@kbn/pm is a tool that helps us manage these static dependencies, and it enables us to share these packages between Kibana and Kibana plugins. It also enables these packages to have their own dependencies and their own build scripts, while still having a nice developer experience.

How it works

Internal usage

For packages that are referenced within the Kibana repo itself (for example, using the @kbn/i18n package from an x-pack plugin), we are leveraging Yarn's workspaces feature. This allows yarn to optimize node_modules within the entire repo to avoid duplicate modules by hoisting common packages as high in the dependency tree as possible.

To reference a package from within the Kibana repo, simply use the current version number from that package's package.json file. Then, running yarn kbn bootstrap will symlink that package into your dependency tree. That means you can make changes to @kbn/i18n and immediately have them available in Kibana itself. No npm publish needed anymore — Kibana will always rely directly on the code that's in the local packages.

External Plugins

For external plugins, referencing packages in Kibana relies on link: style dependencies in Yarn. With link: dependencies you specify the relative location to a package instead of a version when adding it to package.json. For example:

"@kbn/i18n": "link:packages/kbn-i18n"

Now when you run yarn it will set up a symlink to this folder instead of downloading code from the npm registry. This allows external plugins to always use the versions of the package that is bundled with the Kibana version they are running inside of.

"@kbn/i18n": "link:../../kibana/packages/kbn-date-math"

This works because we moved to a strict location of Kibana plugins, ./plugins/{pluginName} inside of Kibana, or ../kibana-extra/{pluginName} relative to Kibana. This is one of the reasons we wanted to move towards a setup that looks like this:

elastic
└── kibana
    └── plugins
        ├── kibana-canvas
        └── x-pack-kibana

Relying on link: style dependencies means we no longer need to npm publish our Kibana specific packages. It also means that plugin authors no longer need to worry about the versions of the Kibana packages, as they will always use the packages from their local Kibana.

The kbn use-cases

Bootstrapping

Now, instead of installing all the dependencies with just running yarn you use the @kbn/pm tool, which can install dependencies (and set up symlinks) in all the packages using one command (aka "bootstrap" the setup).

To bootstrap Kibana:

yarn kbn bootstrap

By default, @kbn/pm will bootstrap all packages within Kibana, plus all Kibana plugins located in ./plugins or ../kibana-extra. There are several options for skipping parts of this, e.g. to skip bootstrapping of Kibana plugins:

yarn kbn bootstrap --skip-kibana-plugins

Or just skip few selected packages:

yarn kbn bootstrap --exclude @kbn/pm --exclude @kbn/i18n

For more details, run:

yarn kbn

Bootstrapping also calls the kbn:bootstrap script for every included project. This is intended for packages that need to be built/transpiled to be usable.

Running scripts

Some times you want to run the same script across multiple packages and plugins, e.g. build or test. Instead of jumping into each package and running yarn build you can run:

yarn kbn run build

And if needed, you can skip packages in the same way as for bootstrapping, e.g. with --exclude and --skip-kibana-plugins:

yarn kbn run build --exclude kibana

Watching

During development you can also use kbn to watch for changes. For this to work package should define kbn:watch script in the package.json:

yarn kbn watch

By default kbn watch will sort all packages within Kibana into batches based on their mutual dependencies and run watch script for all packages in the correct order.

As with any other kbn command, you can use --include and --exclude filters to watch only for a selected packages:

yarn kbn watch --include @kbn/pm --include kibana

Building packages for production

The production build process relies on both the Grunt setup at the root of the Kibana project and code in @kbn/pm. The full process is described in tasks/build/packages.js.

Development

This package is run from Kibana root, using yarn kbn. This will run the "pre-built" (aka built and committed to git) version of this tool, which is located in the dist/ folder. This will also use the included version of Yarn instead of using your local install of Yarn.

If you need to build a new version of this package, run yarn build in this folder.

Even though this file is generated we commit it to Kibana, because it's used before dependencies are fetched (as this is the tool actually responsible for fetching dependencies).

Technical decisions

Why our own tool?

While exploring the approach to static dependencies we built PoCs using npm 5 (which symlinks packages using file: dependencies), Yarn workspaces, Yarn (using link: dependencies), and Lerna.

In the end we decided to build our own tool, based on Yarn, and link: dependencies, and workspaces. This gave us the control we wanted, and it fits nicely into our context (e.g. where publishing to npm isn't necessarily something we want to do).

Some notes from this exploration

file: dependencies in npm<5 and in yarn

When you add a dependency like "foo": "file:../../kibana/packages/foo", both npm<5 and yarn copies the files into the node_modules folder. This means you can't easily make changes to the plugin while developing. Therefore this is a no-go.

file: dependencies in npm5

In npm5 file: dependencies changed to symlink instead of copy the files. This means you can have a nicer workflow while developing packages locally. However, we hit several bugs when using this feature, and we often had to re-run npm install in packages. This is likely because we used an early version of the new file: dependencies in npm5.

This is the same feature as file: dependencies in npm5. However, we did not hit any problems with them during our exploration.

Yarn workspaces

Enables specifying multiple "workspaces" (aka packages/projects) in package.json. When running yarn from the root, Yarn will install all the dependencies for these workspaces and hoist the dependencies to the root (to "deduplicate" packages). However:

Workspaces must be children of the workspace root in term of folder hierarchy. You cannot and must not reference a workspace that is located outside of this filesystem hierarchy.

So Yarn workspaces requires a shared root, which (at least currently) doesn't fit Kibana, and it's therefore a no-go for now.

Lerna

Lerna is based on symlinking packages (similarly to the link feature which exists in both npm and Yarn, but it's not directly using that feature). It's a tool built specifically for managing JavaScript projects with multiple packages. However, it's primarily built (i.e. optimized) for monorepo libraries, so it's focused on publishing packages and other use-cases that are not necessarily optimized for our use-cases. It's also not ideal for the setup we currently have, with one app that "owns everything" and the rest being packages for that app.