-
Notifications
You must be signed in to change notification settings - Fork 8.5k
Description
The problem
Today, we import local source code with many different path formats. Client-side code can use webpack aliases, TypeScript can import from kibana, ui, or plugins (technically on either server or client), server-side JavaScript can only do relative imports.
This is a burden for us, so we agreed to fix it. Since relative imports are usable anywhere (in theory), we decided all imports should be done through relative imports. This solves the consistency problem, but it introduces others.
Relative imports across module/package/plugin boundaries inherently make those modules less portable if the system around them changes. A great example of this is the recent move of the legacy plugins, which involved updating hundreds of import paths despite the intention of those import statements remaining unchanged.
Relative imports create ambiguity with similarly named files and directories. e.g. At a glance, does import from '../../../../../../tests' import from the root level tests directory or from the tests directory inside your plugin? The deeper your code is nested, the harder that question is to answer. It's not purely visual as well, as you can't really use find+replace to identify this either.
Relative imports make many developers unhappy. There has been strong push back on relative imports for sharing code across plugins, especially from folks that do most of their development in the browser where they're used to convenient webpack aliases.
Finally, the assumption we made when adopting a relative imports strategy that they are available in all contexts is not accurate. Despite them seeming like the standard import mechanism, developers have run into issues in various places (e.g. mocks in tests) when trying to do relative imports.
Proposed solution
Code should be imported from outside the current package/system/plugin using imports from Kibana root.
Within a package/system/plugin, it's appropriate to use relative imports, though absolute imports are still acceptable when the relative import is still crazy. Most developers will do this anyway given the option.
So for example, any of these options would be OK from within a plugin called "foo":
/*
src
plugins
foo
bar
whatever.js
test_utils
foomocks.js
test_utils
globalmocks.js
*/
// src/plugins/foo/bar/whatever.js
// OK
import from 'test_utils/globalmocks';
import from 'src/plugins/foo/test_utils/foomocks';
import from '../test_utils/foomocks';
// NOT OK
import from '../../../test_utils/globalmocks';I have a proof of concept for supporting this import behavior in #40066. More work is required, like updating the webpack configuration for client-side code and getting CI passing, but overall I think this is very doable.